Холст и узлы
Холст — способ собрать экран деревом узлов: берёте у кита узел, кладёте в него другие и печатаете корень одним вызовом. Тегов, имён классов и склейки строк в коде экрана при этом нет.
Модель#
В модели три участника.
- Кит — фабрика узлов. Каждая функция кита (
Кит.Ряд,Кит.Таблица,Кит.Кнопка) возвращает новый узел. - Элемент экрана — сам узел. У него есть род, вид, родитель и дети. Детей передают фабрике аргументами или кладут методом
Добавить, печатают методомРендер. - Холст — корень куска экрана. Своего тега не печатает: он только держит детей и печатает их подряд.
Порядок детей и есть порядок на экране. Печать идёт один раз, с корня: каждый узел печатает себя и всё, что внутри него. Правила, по которым пишется код экрана, собраны на странице Язык узлов.
Список объектов: шапка, таблица, карточки, действие
| Имя |
|---|
отчёт |
объект
описание объекта
HTML = Кит.Холст(
Кит.Ряд("выбор",
Кит.Надпись("Витрина").Вид("название"),
Кит.Надпись("холст, ряд, надпись, текст").Вид("пояснение")),
Кит.Таблица(
Кит.Колонка("Имя"),
Кит.Запись(Кит.Ячейка(Кит.Код("отчёт")))),
Кит.Область(
Кит.Статья(
Кит.Заголовок(3, "объект").Вид("имя"),
Кит.Примечание("описание объекта").Вид("описание")).Вид("карточка")).Вид("карточки"),
Кит.Кнопка("Действие").Основная()).Рендер();Дети аргументами#
Фабрика контейнера принимает до восьми детей позиционно, по порядку на экране. Неопределено пропускается: ребёнок, которого может не быть, пишется прямо в списке. Девятый и дальше кладутся методом Добавить; Добавить(Неопределено) тоже ничего не кладёт — необязательную часть экрана можно добавлять в цикле, не оборачивая её в Кит.Холст.
Строка на месте узла — текст: она становится узлом Кит.Текст и экранируется, разметкой не станет никогда.
Строки — текст, узлы — узлы
<p class="muted">Ключ <code>api-7f2c</code> показывается один раз.</p>HTML = Кит.Примечание("Ключ ", Кит.Код("api-7f2c"), " показывается один раз.").Рендер();Добавить возвращает положенное#
Добавить возвращает не родителя, а ребёнка — тот узел, который только что положили. Поэтому цепочка Холст.Добавить(Кит.Ряд(...)).Добавить(...) спускается вглубь дерева, а не наполняет один уровень. Строку Добавить тоже принимает и отдаёт её текстовый узел.
Нужен родитель — возьмите его методом Родитель(). Так узел, собранный в одну строку, отдают целиком.
Цепочка вглубь и возврат к родителю
Ключ показывается один раз.
Абзац = Кит.Примечание().Добавить("Ключ показывается один раз.").Родитель();
HTML = Абзац.Рендер();Список, который собирается циклом, наполняют Добавить:
Дети из цикла — Добавить
Ряд = Кит.Ряд("признаки");
Для Каждого Имя Из СтрРазделить("свежий,проверен,открытый", ",") Цикл
Ряд.Добавить(Кит.Плашка(Имя));
КонецЦикла;
HTML = Ряд.Рендер();Род и вид#
Род — что это за узел: ряд, таблица, ссылка, текст. Род определяет тег и то, что можно положить внутрь. Вид — оформление узла из закрытого набора его рода. Вид задают словом .Вид(…): Кит.Таблица(…).Вид("карточками"). У ряда вид — его смысл, поэтому он первым аргументом: Кит.Ряд("выбор", …).
Вид — не имя CSS-класса. Его проверяют сразу: опечатка останавливает сборку, а не даёт молча голый экран. Все роды и их виды собраны в словаре родов.
Неизвестный вид — исключение
Разметка элементов: узел «ряд» вида «кнопки» не знает. Вид — значение из закрытого набора кита, а не имя CSS-класса; этот род знает виды: выбор, признаки, свёрнутые, плашки, справа, строкой, действия (пусто — рода «ряд» кит не знает вовсе, «—» значит «без вида»).
Попытка
Кит.Ряд("кнопки");
Исключение
HTML = Кит.Примечание(КраткоеПредставлениеОшибки(ИнформацияОбОшибке())).Рендер();
КонецПопытки;Прежде вид шёл вторым аргументом: Кит.Примечание("Ничего", "пусто"). Теперь там ребёнок-текст, и слово «пусто» напечаталось бы на экране. Строку, совпавшую с видом рода, кит ловит при рождении узла и подсказывает слово .Вид(…).
Условие словом#
.Когда(Условие) есть у любого узла: ложь печатает пустую строку, а узел остаётся в дереве — Дерево() показывает его пометкой [скрыт]. Условие вычисляется всегда; там, где вычислять дорого, пишите Если и Кит.Ничего().
Когда — узел на месте, на экране его нет
Ключи доступа
Ключей пока нет.
ЕстьКлючи = Ложь;
HTML = Кит.Холст(
Кит.Заголовок(3, "Ключи доступа"),
Кит.Примечание("Ключей пока нет.").Вид("пусто").Когда(НЕ ЕстьКлючи),
Кит.Кнопка("Отозвать все").Опасная().Когда(ЕстьКлючи)).Рендер();Правила вложения#
Дерево проверяет себя на каждом ребёнке. Ошибку видно сразу, в строке, где её сделали, а не на экране, с которого содержимое молча пропало.
- Внутрь кладут узел или строку текста. Готовую разметку, которую пока некому собрать деревом, заворачивают в
Кит.Готовое(). - Лист дерева (текст, картинка, мета, компонент без слота) детей не принимает.
- Один узел — одно место на экране. Для второго места возьмите у кита новый узел.
- Узел нельзя положить в самого себя или в своего потомка.
- Некоторые роды принимают только своих детей: в таблицу кладут колонки и записи, в запись — ячейки, в список — пункты, в свойства — свойства, в документ — голову и тело. Строка в таком роде — тоже чужой ребёнок.
- В форму строка не кладётся вовсе: токен задаётся словом
.Токен(…), текст — узломКит.Текст().
Чужой ребёнок — исключение
Разметка элементов: внутрь узла «список» кладут только «пункт», а не «примечание»: узел чужого рода этот родитель не печатает, и содержимое молча исчезло бы с экрана.
Попытка
Кит.Список(Кит.Примечание("абзац вместо пункта"));
Исключение
HTML = Кит.Примечание(КраткоеПредставлениеОшибки(ИнформацияОбОшибке())).Рендер();
КонецПопытки;Строка в записи таблицы — исключение
Разметка элементов: внутрь узла «запись» кладут только «ячейка», а не «текст»: узел чужого рода этот родитель не печатает, и содержимое молча исчезло бы с экрана.
Попытка
Кит.Запись("значение без ячейки");
Исключение
HTML = Кит.Примечание(КраткоеПредставлениеОшибки(ИнформацияОбОшибке())).Рендер();
КонецПопытки;Холст и Ничего#
Кит.Холст() и Кит.Ничего() возвращают одинаковый узел и печатаются одинаково — пустой строкой, пока в них ничего не положили. Разница видна только тому, кто читает код экрана, и в ней весь смысл.
Кит.Холст(…)— корень куска экрана: его наполняют и печатают целиком.Кит.Ничего()— место, где показывать нечего: его не наполняют, он и есть ответ.
Ничего печатается пустой строкой
этот вызов не печатает ничего
HTML = Кит.Ничего().Рендер();Ничего ложится всюду, где принимают холст, но не в обход правил вложения: внутрь записи по-прежнему кладут ячейку, внутрь таблицы — запись, внутрь списка — пункт.
Функция БлокЧерновика(Знач Статья)
Если Статья.Черновик Тогда
Возврат Кит.Ничего(); // на странице этого места просто не будет
КонецЕсли;
Возврат Кит.Холст( // а здесь собираем кусок экрана
Кит.Заголовок(3, "Как читать"),
Кит.Примечание(Статья.Пояснение).Вид("описание"));
КонецФункции
На Возврат Кит.Ничего(); читатель останавливается: элемента здесь нет. На Возврат Кит.Холст(); он идёт вверх по функции искать, чем холст наполнили, и не находит ничего.
Слово «пусто» в ките уже занято видимым смыслом: компонент «Пустое состояние», вид примечания «пусто» и Таблица.Пусто(). Все три что-то показывают человеку, поэтому место без содержимого называется иначе.
Дерево узла#
Дерево() печатает, из чего собран кусок экрана: род и вид каждого узла, вложенность отступом, снятые словом Когда — пометкой [скрыт]. Это ответ на вопрос «что здесь напечатано» без чтения функций, которые экран собирали.
Из чего собран экран
холст
ряд[выбор]
компонент[кнопка]
таблица
пусто
примечание[пусто]
текст
колонка
текст
запись
разворот
ячейка
код
текст
примечание [скрыт]
текст
Холст = Кит.Холст(
Кит.Ряд("выбор", Кит.Кнопка("Все").Вторичная()),
Кит.Таблица(
Кит.Колонка("Имя"),
Кит.Запись(Кит.Ячейка(Кит.Код("отчёт")))).Пусто("Ничего не найдено"),
Кит.Примечание("Фильтр не задан.").Когда(Ложь));
HTML = Кит.Код(Холст.Дерево()).Вид("блочный").Рендер();Свойства узла#
Атрибуты узла задаются словами, а не строкой. Каждое слово возвращает тот же узел, поэтому их ставят цепочкой.
Подпись— доступное имя ряда, легенда группы, заголовок таблицы, имя свойства, текстaltкартинки.Якорь— атрибутid: на него ссылаются адрес с решёткой и кнопка вне своей формы.Признак— атрибутdata-*для скрипта страницы. Печатается даже пустым. Имя — латиницей, цифрами и дефисом: признак с другим именем молча не печатается.Роль— роль для скринридера из набора кита: «группа», «состояние», «тревога».Подсказка— атрибутtitle.ОтключитьиСкрыть— атрибутыdisabledиhidden.Вид,Когда,Токен— вид узла, условие показа и CSRF-токен для форм внутри.
У компонента те же слова пишут поля его модели — подробно на странице Компонент в дереве.
Свойства печатаются атрибутами
<div id="шаг-2" class="inset" role="status" title="Шаг второй" data-step="2"><p class="muted">Ключ создан</p></div>HTML = Кит.Область(Кит.Примечание("Ключ создан"))
.Вид("вставка").Якорь("шаг-2").Роль("состояние").Подсказка("Шаг второй")
.Признак("step", "2").Рендер();Отключённая и скрытая группа полей
<fieldset class="field-set" disabled hidden><legend>Расписание</legend><label class="field"><span class="field__label">Время</span><input class="field__control" type="text" name="время"></label></fieldset>HTML = Кит.Группа("Расписание", Кит.Поле("время", "Время"))
.Вид("простая").Отключить().Скрыть().Рендер();Гайдлайны#
Отчёт за март
Код
Черновик = Истина;
Холст = Кит.Холст(Кит.Заголовок(3, "Отчёт за март"));
Если Черновик Тогда
Холст.Добавить(Кит.Ничего());
Иначе
Холст.Добавить(Кит.Примечание("Как читать отчёт").Вид("описание"));
КонецЕсли;
HTML = Холст.Рендер();Отчёт за март
Код
Черновик = Истина;
Холст = Кит.Холст(Кит.Заголовок(3, "Отчёт за март"));
Если Черновик Тогда
Холст.Добавить(Кит.Холст());
Иначе
Холст.Добавить(Кит.Примечание("Как читать отчёт").Вид("описание"));
КонецЕсли;
HTML = Холст.Рендер();Ключи доступа
Ключ показывается один раз.
Код
HTML = Кит.Холст(
Кит.Заголовок(3, "Ключи доступа"),
Кит.Примечание("Ключ показывается один раз.")).Рендер();Ключи доступа
Ключ показывается один раз.
Код
HTML = Кит.Заголовок(3, "Ключи доступа").Рендер()
+ Кит.Примечание("Ключ показывается один раз.").Рендер();Имя <main> уже занято.
Код
HTML = Кит.Примечание("Имя ", Кит.Код("<main>"), " уже занято.").Рендер();Имя <main> уже занято.
Код
HTML = Кит.Примечание(Кит.Готовое("Имя <code><main></code> уже занято.")).Рендер();Доступность#
- Текст из данных печатается текстом — строкой-ребёнком или узлом
Кит.Текст()— и экранируется всегда: разметкой он не станет. - Уровень заголовка — число от 1 до 6, другой кит не соберёт. Не пропускайте уровни: скринридер строит по ним оглавление страницы.
- Ряд с подписью получает
aria-label(ставьте ему и роль «группа», иначе имя уdivне прочтут), группа — видимую легенду, картинка —alt. Картинка без подписи декоративна, скринридер её пропускает. - Роль ставится только из набора кита, произвольную строку кит отвергнет.
- Пустые ссылка, заголовок и примечание не печатаются вовсе: безымянная ссылка и пустой заголовок для скринридера — дыра.
Справка#
Кит.Холст()src/Классы/холст/Кит.os
Холст — корень куска экрана: его наполняют и печатают целиком. Своего тега не печатает: обёртка, которой на экране никто не просил, ломает вертикальный ритм соседей. Место, где показывать нечего, — это Ничего(), а не холст, который забыли наполнить. Параметры: Р1…Р8 - ЭлементЭкрана, Строка - (необязательные) дети узла; строка — текст. Возвращаемое значение: ЭлементЭкрана
Кит.Ничего()src/Классы/холст/Кит.os
Ничего — место экрана, где показывать нечего: всюду, где принимают холст, но не в обход правил вложения — внутрь записи по-прежнему кладут ячейку, внутрь таблицы запись, внутрь списка пункт. Узел тот же, что холст, и печатается он так же — пустой строкой; отличается тем, что читатель «Возврат Кит.Ничего();» видит отсутствие элемента сразу, а не ищет по функции, чем этот холст наполнили. Наполнять его незачем: собираете кусок экрана — берите Холст(). Именем «пусто» звать нельзя: у ПустоеСостояние, примечания вида «пусто» и Таблица.Пусто() смысл обратный — они человеку что-то ПОКАЗЫВАЮТ. Возвращаемое значение: ЭлементЭкрана - печатается пустой строкой.
ЭлементЭкрана.Добавить()src/Классы/холст/ЭлементЭкрана.os
Кладёт элемент внутрь этого. Порядок детей и есть порядок на экране. Строка на месте элемента — это текст: она становится узлом Кит.Текст и экранируется. Сырую разметку кладут только узлом Кит.Готовое(). Неопределено пропускается, как позиционный ребёнок: необязательная часть экрана кладётся без обёртки в Кит.Холст (0.13, дев-сборка 7). Параметры: Ребёнок - ЭлементЭкрана, Строка, Неопределено - что положить; Неопределено — ничего. Возвращаемое значение: ЭлементЭкрана, Неопределено - положенный элемент, чтобы наполнять его дальше; для строки — её текстовый узел; для Неопределено — Неопределено.
ЭлементЭкрана.Наполнить()src/Классы/холст/ЭлементЭкрана.os
Кладёт внутрь до восьми элементов разом, по порядку. Неопределено пропускается: так условный ребёнок пишется прямо в списке, а девятый и дальше кладутся Добавить(). Параметры: Р1 - ЭлементЭкрана, Строка, Неопределено - (необязательный) первый ребёнок; строка — текст. Р2 - ЭлементЭкрана, Строка, Неопределено - (необязательный) второй, и так до Р8. Р3 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р4 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р5 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р6 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р7 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Р8 - ЭлементЭкрана, Строка, Неопределено - (необязательный) Возвращаемое значение: ЭлементЭкрана - этот же элемент.
ЭлементЭкрана.Родитель()src/Классы/холст/ЭлементЭкрана.os
Элемент, внутри которого лежит этот. Возвращаемое значение: ЭлементЭкрана, Неопределено - родитель; Неопределено у корня.
ЭлементЭкрана.Рендер()src/Классы/холст/ЭлементЭкрана.os
Печатает элемент и всё, что внутри него. Возвращаемое значение: Строка - HTML-фрагмент.
ЭлементЭкрана.Дерево()src/Классы/холст/ЭлементЭкрана.os
Из чего собран этот кусок экрана — построчное дерево родов и видов. Отвечает объектом
на вопрос «что здесь напечатано», не заставляя читать одиннадцать файлов.
Возвращаемое значение:
Строка - строки вида « ряд[выбор]», вложенность — отступом; узел, снятый словом
Когда(Ложь), помечен « [скрыт]».ЭлементЭкрана.Вид()src/Классы/холст/ЭлементЭкрана.os
Вид узла — значение из закрытого набора его рода; проверяется так же, как при рождении. У компонента пишет поле Вид его модели. Параметры: Значение - Строка - вид. Возвращаемое значение: ЭлементЭкрана - этот же элемент.
ЭлементЭкрана.Когда()src/Классы/холст/ЭлементЭкрана.os
Печатает узел только при условии. Ложь печатает пустую строку, но узел остаётся в дереве (Дерево() показывает его пометкой [скрыт]); у колонки таблицы ложь снимает и заголовок, и ячейки под ним. Условие вычисляется всегда: там, где вычислять дорого, пишите Если и Кит.Ничего(). Параметры: Условие - Булево - печатать ли узел. Возвращаемое значение: ЭлементЭкрана - этот же элемент.
ЭлементЭкрана.Подпись()src/Классы/холст/ЭлементЭкрана.os
Подпись элемента: доступное имя ряда, легенда группы, заголовок таблицы, имя реестра. У компонента, в модели которого есть поле Подпись, пишет его (у сводки и записи реестра — добавляет часть подписи). Параметры: Текст - Строка - подпись (экранируется при печати). Возвращаемое значение: ЭлементЭкрана - этот же элемент.
ЭлементЭкрана.Якорь()src/Классы/холст/ЭлементЭкрана.os
Якорь — идентификатор узла на странице (атрибут id): на него ссылаются адрес с решёткой и кнопка, отправляющая форму снаружи неё (Кнопка с полем Форма). У карточки и секции пишет поле Якорь их модели. Параметры: Значение - Строка - идентификатор, уникальный на странице. Возвращаемое значение: ЭлементЭкрана - этот же элемент.
ЭлементЭкрана.Признак()src/Классы/холст/ЭлементЭкрана.os
Вешает на элемент data-признак — то, за что его берёт скрипт страницы.
Параметры:
Имя - Строка - имя признака БЕЗ префикса data-, латиницей: буква, затем буквы,
цифры и дефисы («step», «row-id»). Другое имя браузер принял бы не везде,
поэтому оно останавливает сборку исключением, а не пропадает молча.
Значение - Строка - значение признака.
Возвращаемое значение:
ЭлементЭкрана - этот же элемент.ЭлементЭкрана.Роль()src/Классы/холст/ЭлементЭкрана.os
Задаёт роль элемента для скринридера. Параметры: Значение - Строка - роль ARIA («группа»). Возвращаемое значение: ЭлементЭкрана - этот же элемент.