Каркас страницы
Каркас печатает всё, что стоит вокруг экрана: голову документа с темой, шапку, единое меню, подвал и скрипты. Экран отдаёт ему только содержимое.
Что печатает каркас#
- Голову: кодировку, viewport,
color-scheme, заголовок вкладки, значки, карточку ссылки Open Graph, токены темы инлайном, базовый лист кита, лист инсталляции. - Шапку: знак, верхние дороги, переключатель темы и действия инсталляции справа.
- Единое меню: если слот заполнен — бургер на телефоне и панель с дорогами, разделами экрана и темой.
- Основное: ваше содержимое в
<main>. - Подвал с подписью инсталляции.
- Скрипты: скрипт кита, затем скрипт инсталляции, оба отложенные.
Токены темы печатаются в голове, а не лежат в листе: страница приезжает уже нужного цвета и не мигает, пока лист в пути. Тема и акцент берутся из cookie посетителя поверх оформления инсталляции.
Вызов#
Контекст = Каркас.КонтекстСтраницы(Пользователь, КукиЗапроса, ПоказатьАдмин, Приватная, ПутьЗапроса, Сессия);
Ответ.ТелоТекст = Каркас.Страница("Проекты", Холст, Контекст, РазделыЭкрана);
Сессия (необязательная, дев-сборка 10) — сессия запроса, которую уже прочитал страж приложения: кит её не читает, а довозит до обрамления полем Контекст.Сессия — оттуда берут токен формы выхода, не читая сессию по куке второй раз. Двери, которые получают готовый контекст, добавляют сессию Каркас.КонтекстССессией(Контекст, Сессия).
Содержимое — узел холста или готовая строка HTML. РазделыЭкрана — разделы текущего экрана: на телефоне они уезжают в единое меню отдельной секцией. Именно так оглавление этой документации попадает в шторку на узком экране.
КаркасСтраницы.КонтекстСтраницы()src/Классы/каркас/КаркасСтраницы.os
Собирает контекст запроса. КукиЗапроса обязательны: страница без них молча потеряла бы
оформление читателя, поэтому тот, кому нечего передать, пишет Неопределено явно.
Параметры:
Пользователь - Произвольный, Неопределено - принципал запроса; посетитель —
Неопределено.
КукиЗапроса - Куки, Неопределено - куки запроса winow.
ПоказатьАдмин - Булево - (необязательный, по умолчанию Ложь) показывать ли разделы
администратора в навигации приватной части.
Приватная - Булево - (необязательный, по умолчанию Ложь) страница приватной
части: над содержимым встаёт её навигация.
Путь - Строка - (необязательный, по умолчанию "") путь текущего запроса.
Кит его НЕ разбирает и ни с чем не сравнивает — только довозит
до обрамления: какая дорога сейчас активна, знает инсталляция,
потому что адреса дорог придумала она. Пусто — как было раньше.
Сессия - Произвольный, Неопределено - (необязательный, дев-сборка 10) сессия
запроса, которую уже прочитал страж: токен формы выхода, срок. Кит её
не читает — довозит до обрамления (Обрамление(Контекст).Сессия), чтобы
страница собиралась из одного чтения сессии, а не второго по куке.
Возвращаемое значение:
Структура - Пользователь, КукиЗапроса, ПоказатьАдмин, Приватная, Путь, Сессия.КаркасСтраницы.КонтекстССессией()src/Классы/каркас/КаркасСтраницы.os
Контекст страницы с сессией запроса (дев-сборка 10): тот же контекст, что пришёл, и сессия, прочитанная стражем, — для дверей, которые получают готовый контекст или собирают его в одном месте, а сессию узнают позже. Параметры: Контекст - Структура - контекст запроса, см. КонтекстСтраницы(). Сессия - Произвольный - сессия запроса. Возвращаемое значение: Структура - копия контекста с полем Сессия.
КаркасСтраницы.Страница()src/Классы/каркас/КаркасСтраницы.os
Полный HTML-документ вокруг содержимого.
Параметры:
Заголовок - Строка - заголовок вкладки; пустой оставляет во вкладке один знак.
Содержимое - ЭлементЭкрана, Строка - то, ради чего страницу открыли. Строка —
ДОВЕРЕННЫЙ HTML непереведённого экрана, она заворачивается в готовый
фрагмент.
Контекст - Структура - контекст запроса, см. КонтекстСтраницы().
РазделыЭкрана - Массив, Структура, Неопределено - (необязательный, по умолчанию
Неопределено) разделы ТЕКУЩЕГО экрана (Подпись, Адрес, Иконка, Активен,
Рубрика, Опасный, Счётчик, ПодписьСчётчика) — их знает не инсталляция,
а сама страница, поэтому они приходят сюда, а не обрамлением. Уезжают
в единое меню первой группой под учёткой; пусто — группы нет. Структура
Заголовок, Разделы называет группу именем экрана; у массива группа
подписана заголовком дома настроек (Кит.ДомНастроек), если он — содержимое
страницы, иначе словарём (chrome.menu.section.screen). Не передан, а
содержимое — дом: разделы берутся у дома, группа называется его заголовком.
КарточкаСсылки - Массив из Структура, Неопределено - (необязательный, по умолчанию
Неопределено) свойства карточки, которую чужой сервис строит по ссылке
на страницу: Свойство (og:title, og:image…) и Содержание. Печатаются
в голове объявлениями <meta property> в порядке массива; пара с пустым
свойством или содержанием не печатается. Пусто — голова прежняя.
Возвращаемое значение:
Строка - HTML-документ.Обрамление — контракт инсталляции#
Как приложение называется, куда ведут его дороги и где его лист стилей, кит не знает. Это знает обрамление — желудь с прозвищем ОбрамлениеИнсталляции. Кит везёт пустое обрамление по умолчанию, а приложение подставляет своё с пометкой &Верховный.
Функция Обрамление(Знач Контекст) Экспорт
Результат = Новый Структура();
Результат.Вставить("Язык", "ru");
Результат.Вставить("Знак", "Ромашка");
Результат.Вставить("Разделы", Дороги(Контекст.Путь));
Результат.Вставить("АдресСтилей", Активы.Адрес("ромашка.css"));
// … остальные поля — см. справку ниже
Возврат Результат;
КонецФункции
&Верховный
&Прозвище("ОбрамлениеИнсталляции")
&Желудь
Процедура ПриСозданииОбъекта(&Пластилин(Значение = "АктивыСтатики") _Активы) Экспорт
Активы = _Активы;
КонецПроцедуры
Обрамление спрашивается на каждый запрос: знак, активная дорога и имя вошедшего меняются от запроса к запросу. Путь текущего запроса приходит в Контекст.Путь, и активную дорогу вычисляет само приложение.
ОбрамлениеИнсталляцииПоУмолчанию.Обрамление()src/Классы/каркас/ОбрамлениеИнсталляцииПоУмолчанию.os
Чем инсталляция обрамляет содержимое страницы. Спрашивается НА КАЖДЫЙ запрос:
и знак, и разделы, и имя вошедшего меняются от запроса к запросу.
Параметры:
Контекст - Структура - контекст запроса: Пользователь, КукиЗапроса, ПоказатьАдмин,
Приватная, Путь (путь текущего запроса; кит его не разбирает, а довозит
сюда — по нему инсталляция и решает, какая её дорога активна).
Возвращаемое значение:
Структура:
Язык - Строка - код языка страницы; "" — язык не объявляется;
Знак - Строка - как инсталляция называет себя в шапке и во вкладке;
Подпись - Строка - строка подвала;
ПолитикаПерехода - Строка - что уходит наружу в заголовке перехода;
АдресСтилей - Строка - адрес СВОЕГО листа стилей; он встаёт вторым после
базового листа библиотеки и потому перебивает его правила.
Пусто — инсталляции хватает базового листа;
АдресСкрипта - Строка - адрес скрипта страницы;
Иконки - Массив из Структура(Отношение, Тип, Размеры, Адрес);
Знамя - Структура(Адрес, Ширина, Название): картинка знака, её известная
ширина в пикселях (0 — пропорции произвольны, считает браузер)
и печатать ли название рядом с картинкой;
Разделы - Массив из Структура(Подпись, Адрес, Иконка) — верхняя навигация;
Приватные - Массив той же формы — навигация приватной части; пустой массив
означает, что страница публичная;
Действия - Массив - что стоит в шапке справа от дорог, по порядку: вход,
кабинет, выход, меню учётки, ссылка на репозиторий — что угодно.
Кит своих действий не сочиняет. Элемент — модель кнопки кита
(Структура: Подпись, Адрес, Иконка, Вариант, ТолькоИконка…), узел
холста (Кит.Меню с полем Аккаунт — меню учётки; Кит.ФормаБезТокена —
форма выхода) либо ДОВЕРЕННЫЙ фрагмент HTML (Строка). На телефоне
с единым меню действия уезжают в его панель кнопками во всю ширину;
МенюХаба - Структура, Неопределено - слот ЕДИНОГО меню инсталляции. Заполнен —
дороги, тема, действия и учётка собираются в одну панель.
На широком экране шапка прежняя (знак, дороги, тема, действия),
а кнопка учётки открывает панель выпадающим меню; на телефоне
полоса ходов прячется, слева встаёт бургер, панель выезжает
шторкой. Поля:
Счётчик и ПодписьСчётчика — сумма дел на бургере и как она
зовётся в речи. ПРАВИЛО ПАРЫ: задано непустое ненулевое число —
обязана быть и подпись, иначе меню не соберётся; ноль и пусто
не печатаются вовсе. Правило одно и то же для суммы на бургере
и для числа у пункта;
Учётка — Структура(Логин, Роль, Адрес): вошедший, его роль словами
и ход в кабинет. Логин пуст — блока учётки нет;
Дела — Массив(Подпись, Адрес, Иконка, Счётчик, ПодписьСчётчика,
Активен): личные дела с РАЗДЕЛЬНЫМИ числами;
Настройки — Массив той же формы, что Дела: ходы в настройки
(свои и приложения), отдельной группой после дел; в сумму на
бургере их числа не входят;
Навигация — Массив(Подпись, Адрес, Иконка, Активен): дороги хаба;
они же становятся значками рейки. Активен подсвечивает дорогу
В ОБОИХ местах разом — и пункт панели, и значок рейки. Активен
вычисляет ИНСТАЛЛЯЦИЯ, сравнивая свои адреса с Путём контекста:
кит адресов не знает и сравнивать их не берётся;
разделы ТЕКУЩЕГО экрана в слот НЕ входят: их знает не инсталляция,
а сама страница, и они приходят четвёртым параметром
КаркасСтраницы.Страница(..., РазделыЭкрана);
Выход — форма выхода в подвале панели: узел холста (дев-сборка 10:
Кит.Форма(…) с токеном, собранная деревом) либо ДОВЕРЕННЫЙ фрагмент
строкой, как прежде.
Ни дел, ни навигации, ни логина — слот пуст, и шапка остаётся
прежней целиком;
Адреса - Структура(Корень, Оформление): ход знака и адрес POST
переключателя темы. Пустое Оформление — переключателя нет.
Дев-сборка 10: в контексте приходит и Сессия — сессия запроса, которую уже прочитал страж
(КаркасСтраницы.КонтекстСтраницы, шестой параметр): из неё берут токен формы выхода, не
читая сессию по куке второй раз.Действия шапки#
Справа от дорог стоит то, что даёт приложение полем обрамления Действия, — по порядку и ничего сверх. Кит своих кнопок в шапку не добавляет: у сайта без учёток не появится «Войти», у приложения с учётками вход и меню учётки — его собственные действия.
Элемент — узел холста, модель кнопки кита (прежний вид) или готовый HTML:
Функция Действия(Знач Вошедший)
Результат = Новый Массив();
Если НЕ ЗначениеЗаполнено(Вошедший) Тогда
Результат.Добавить(Кит.Кнопка("Войти").Вторичная().Адрес("/вход").Иконка("аккаунт"));
Возврат Результат;
КонецЕсли;
Результат.Добавить(Кит.Меню("Меню учётки",
Кит.ПунктМеню("Личное", "/личное").Иконка("аккаунт"),
Кит.ФормаБезТокена("/выход", Кит.Кнопка("Выйти").Иконка("выход")).Вид("меню"))
.Аккаунт(Вошедший));
Возврат Результат;
КонецФункции
Так выглядят оба случая:
Гость — действие «Войти»
HTML = Набор.Кнопка().Отрисовать(Новый Структура("Подпись, Адрес, Вариант, Иконка",
"Войти", "/вход", "вторичная", "аккаунт"));Вошедший — меню учётки действием
HTML = Кит.Меню("Меню учётки",
Кит.ПунктМеню("Личное", "/личное").Иконка("аккаунт")).Аккаунт("алиса").Рендер();На телефоне с единым меню полоса ходов спрятана, поэтому действия повторяются в его панели кнопками во всю ширину. Переключатель темы — возможность кита, и включает её адрес Адреса.Оформление: нет адреса — нет и переключателя.
Переключатель — обычная POST-форма на этот адрес, и без скрипта она работает перезагрузкой страницы. Со скриптом кита тема меняется сразу, без перезагрузки: обе палитры уже в голове страницы, а форма уходит на сервер в фоне, и cookie, как и прежде, пишет сервер. От инсталляции требуется одно: после записи cookie перенаправить обратно на страницу, с которой пришёл запрос.
Выглядит переключатель пилюлей с бегунком, как на сайте oscript.io: дорожка 44 × 24, в бегунке солнце в светлой теме и луна в тёмной. Это кнопка отправки формы с ролью переключателя (role="switch"): включён — тёмная тема, имя — состояние словами из словаря (theme.switch.dark — «Тема: тёмная», theme.switch.light — «Тема: светлая»), подсказка — куда переключит (chrome.top.theme.to-light, chrome.top.theme.to-dark). Бегунок стоит по теме страницы, поэтому со скриптом он едет в тот же миг, что перекрашивается страница (0.2 с; при «уменьшить движение» — без перехода). В шторке единого меню переключатель — строкой: подпись словами, пилюля в конце строки. В дереве экрана он узел компонент[переключатель-темы] — его печатает каркас (Кит.ПереключательТемы).
Остальные контракты#
| Прозвище | Что даёт приложение | Что будет без него |
|---|---|---|
ОбрамлениеИнсталляции |
знак, дороги, подпись, свой лист и скрипт, слоты меню | пустая шапка без знака |
СловарьИнтерфейса |
тексты шапки и меню по ключам chrome.* |
на месте текста ключ в скобках [?chrome.menu.open] |
СтатикаИнсталляции |
свой каталог статики и список файлов | раздаются только файлы кита |
ОформлениеИнсталляции |
тема и акцент по умолчанию, имя cookie | тёмная тема, базовый акцент, cookie ui |
Готовые реализации всех четырёх — в исходниках этого сайта: документация/src/Классы/сайт/.
Гайдлайны#
- Отдавайте каркасу узел холста, а не склеенную строку: так экран остаётся деревом до последнего момента.
- Активную дорогу вычисляйте в обрамлении по
Контекст.Путь. Кит адресов не знает и сравнивать их не берётся. - Не печатайте второе единое меню руками: его идентификатор на странице один, и вторая кнопка открыла бы чужую панель.