Модуль View
Фасад библиотеки. Делает четыре вещи: читает и выставляет заголовки htmx, экранирует значения модели, отдаёт htmx и Alpine.js как статику и создаёт объекты рендеринга и защиты форм.
Все функции принимают и возвращают нейтральные значения - Соответствие заголовков и строки, - поэтому работают и внутри winow, и в тестах без поднятого сервера.
#Использовать winow-viewСправочник заголовков: htmx headers.
Состав
| Группа | Методы |
|---|---|
| Заголовки запроса | ЭтоHxЗапрос, ЭтоHxBoosted, ЦельHx, ТриггерHx, ИмяТриггераHx, ТекущийАдресHx, ЭтоЗапросИсторииHx, ЗапросПодтвержденияHx, ЗначениеЗаголовка |
| Заголовки ответа | УстановитьТриггер, УстановитьТриггерПослеЗамены, УстановитьТриггерПослеУстановки, Перенаправить, Обновить, ЗаменитьАдрес, ПротолкнутьАдрес, ПереопределитьЦель, ПереопределитьСпособЗамены, ПереопределитьВыборку |
| Экранирование | ЭкранироватьHtml, ЭкранироватьАтрибут |
| Статика | ПутьКСтатике, ФайлБиблиотеки, СодержимоеБиблиотеки, ТегиПодключения, ВерсииБиблиотек |
| Объекты | СоздатьОтображения, СоздатьЗащитуCSRF |
Заголовки запроса
Все функции группы принимают один параметр:
| Параметр | Тип | Описание |
|---|---|---|
Заголовки | Соответствие, Структура | Заголовки запроса, в winow это Запрос.Заголовки |
Регистр имён заголовков не важен: HTTP/2 передаёт их только в нижнем регистре, а прокси нормализуют по-своему. Отсутствующий заголовок даёт Ложь для проверок и пустую строку для значений.
| Метод | Возвращает | Заголовок | Смысл |
|---|---|---|---|
ЭтоHxЗапрос(Заголовки) | Булево | HX-Request | Запрос отправлен htmx, а не обычным переходом браузера |
ЭтоHxBoosted(Заголовки) | Булево | HX-Boosted | Запрос вызван ссылкой или формой с hx-boost |
ЭтоЗапросИсторииHx(Заголовки) | Булево | HX-History-Restore-Request | htmx восстанавливает страницу из истории |
ЦельHx(Заголовки) | Строка | HX-Target | Идентификатор элемента, в который подставится ответ |
ТриггерHx(Заголовки) | Строка | HX-Trigger | Идентификатор элемента, вызвавшего запрос |
ИмяТриггераHx(Заголовки) | Строка | HX-Trigger-Name | Атрибут name этого элемента |
ТекущийАдресHx(Заголовки) | Строка | HX-Current-URL | Адрес страницы, с которой отправлен запрос |
ЗапросПодтвержденияHx(Заголовки) | Строка | HX-Prompt | Ответ пользователя на hx-prompt |
Основное применение - решение, чем отвечать. Фрагмент отдаётся только на обычный hx-запрос: hx-boost и восстановление истории заменяют содержимое body, поэтому им нужна страница целиком.
Если View.ЭтоHxЗапрос(Запрос.Заголовки) И Не View.ЭтоHxBoosted(Запрос.Заголовки) Тогда
Ответ.ТелоТекст = Отображения.Фрагмент("задачи/список", Модель);
Иначе
Ответ.ТелоТекст = Отображения.Страница("задачи/список", Модель);
КонецЕсли;
Сообщить(View.ЦельHx(Запрос.Заголовки)); // задачи
Сообщить(View.ИмяТриггераHx(Запрос.Заголовки)); // названиеЗначениеЗаголовка
Функция ЗначениеЗаголовка(Знач Заголовки, Знач Имя, Знач ЗначениеПоУмолчанию = "") ЭкспортВозвращает произвольный заголовок независимо от регистра его имени.
Параметры
| Параметр | Тип | Описание |
|---|---|---|
Заголовки | Соответствие, Структура | Заголовки запроса |
Имя | Строка | Имя заголовка |
ЗначениеПоУмолчанию | Произвольный | Что вернуть, если заголовка нет |
Возвращаемое значение: Строка, Произвольный - значение заголовка.
Язык = View.ЗначениеЗаголовка(Запрос.Заголовки, "Accept-Language", "ru-RU");Заголовки ответа
Все функции группы возвращают то же Соответствие, что получили, поэтому вызовы можно ставить подряд. Если передать Неопределено, Соответствие создаётся.
| Параметр | Тип | Описание |
|---|---|---|
Заголовки | Соответствие | Заголовки ответа, в winow это Ответ.Заголовки. Неопределено создаёт новое |
| Метод | Заголовок | Что делает клиент |
|---|---|---|
Перенаправить(Заголовки, Адрес) | HX-Redirect | Переходит по адресу |
Обновить(Заголовки) | HX-Refresh | Перезагружает страницу целиком |
ЗаменитьАдрес(Заголовки, Адрес) | HX-Replace-Url | Заменяет адрес в строке браузера без записи в историю |
ПротолкнутьАдрес(Заголовки, Адрес) | HX-Push-Url | Добавляет адрес в историю, кнопка «назад» вернёт состояние |
ПереопределитьЦель(Заголовки, Селектор) | HX-Retarget | Подставляет ответ в другой элемент |
ПереопределитьСпособЗамены(Заголовки, Способ) | HX-Reswap | Меняет способ подстановки: значения те же, что у hx-swap |
ПереопределитьВыборку(Заголовки, Селектор) | HX-Reselect | Берёт из ответа только часть, перекрывая hx-select |
Параметр Адрес - Строка с адресом перехода, Селектор - Строка с CSS-селектором, Способ - Строка вида innerHTML, outerHTML, beforeend, none.
// Ошибку валидации показываем в общем блоке сообщений, а не в элементе,
// который просил ответ
View.ПереопределитьСпособЗамены(View.ПереопределитьЦель(Ответ.Заголовки, "#ошибки"), "outerHTML");
// Код 302 для hx-запроса не работает: браузер подставил бы результат
// в целевой элемент
View.Перенаправить(Ответ.Заголовки, "/задачи/список");Триггеры
Функция УстановитьТриггер(Знач Заголовки, Знач Имя, Знач Данные = Неопределено) Экспорт
Функция УстановитьТриггерПослеЗамены(Знач Заголовки, Знач Имя, Знач Данные = Неопределено) Экспорт
Функция УстановитьТриггерПослеУстановки(Знач Заголовки, Знач Имя, Знач Данные = Неопределено) ЭкспортПросят htmx вызвать событие на клиенте. Три метода различаются моментом вызова:
| Метод | Заголовок | Когда событие вызывается |
|---|---|---|
УстановитьТриггер | HX-Trigger | Сразу после получения ответа |
УстановитьТриггерПослеЗамены | HX-Trigger-After-Swap | После подстановки ответа в DOM |
УстановитьТриггерПослеУстановки | HX-Trigger-After-Settle | После анимаций и досылки атрибутов |
Параметры
| Параметр | Тип | Описание |
|---|---|---|
Заголовки | Соответствие | Заголовки ответа |
Имя | Строка | Имя события, например задачаДобавлена. Пустое имя даёт исключение |
Данные | Структура, Соответствие, Строка, Число, Булево | Подробности события, попадают в detail на клиенте |
Возвращаемое значение: Соответствие - заголовки ответа с соответствующим заголовком.
Повторные вызовы накапливаются. Единственное событие без данных передаётся простым именем - так заголовок читается в отладчике браузера. Как только появляются данные или второе событие, заголовок становится объектом JSON.
View.УстановитьТриггер(Ответ.Заголовки, "задачаДобавлена");
// HX-Trigger: задачаДобавлена
View.УстановитьТриггер(Ответ.Заголовки, "счётчикИзменён", Новый Структура("всего", 3));
// HX-Trigger: {"задачаДобавлена":null,"счётчикИзменён":{"всего":3}}Экранирование
Шаблонизатор подставляет значения как есть, поэтому всё, что пришло от пользователя, экранируется явно.
Функция ЭкранироватьHtml(Знач Текст) Экспорт
Функция ЭкранироватьАтрибут(Знач Текст) Экспорт| Метод | Куда безопасно вставлять | Дополнительно к ЭкранироватьHtml |
|---|---|---|
ЭкранироватьHtml | Текстовое содержимое элемента | - |
ЭкранироватьАтрибут | Значение атрибута в кавычках | Снимает обратную кавычку |
Параметры
| Параметр | Тип | Описание |
|---|---|---|
Текст | Произвольный | Выводимое значение. Числа и Неопределено допустимы |
Возвращаемое значение: Строка - значение, безопасное для вставки.
Модель.Вставить("Название", View.ЭкранироватьHtml(Задача.Название));
Модель.Вставить("Подсказка", View.ЭкранироватьАтрибут(Задача.Комментарий));<li title="{{ Модель.Подсказка }}">{{ Модель.Название }}</li>Обратная кавычка в атрибуте без кавычек работает ограничителем значения в некоторых браузерах, поэтому ЭкранироватьАтрибут заменяет и её. Значение атрибута всё равно берите в кавычки.
Статика
ПутьКСтатике
Функция ПутьКСтатике() ЭкспортКаталог с библиотеками, поставляемыми в составе пакета. Его достаточно зарегистрировать в winow как каталог статики.
Возвращаемое значение: Строка - полный путь к каталогу.
Приложение.ДобавитьКаталогСтатики("/static", View.ПутьКСтатике());ФайлБиблиотеки
Функция ФайлБиблиотеки(Знач Имя) ЭкспортПараметры: Имя - Строка "htmx" или "alpine", допускается и полное имя файла.
Возвращаемое значение: Строка - полный путь к файлу.
Сообщить(View.ФайлБиблиотеки("htmx")); // ...\src\static\htmx.min.jsСодержимоеБиблиотеки
Функция СодержимоеБиблиотеки(Знач Имя) ЭкспортВозвращает содержимое поставляемой библиотеки. Нужно, когда файлы отдаёт сам обработчик, а не каталог статики winow.
Параметры: Имя - Строка "htmx" или "alpine", допускается и полное имя файла.
Возвращаемое значение: Строка - текст файла библиотеки.
Имя проверяется по закрытому списку: имя, пришедшее из запроса, не прочитает ничего, кроме двух поставляемых файлов, даже если в нём приедет ../.
&ТочкаМаршрута("static/{ИмяФайла}")
Процедура Библиотека(ИмяФайла, Ответ) Экспорт
Ответ.УстановитьТипКонтента("js");
Ответ.ТелоТекст = View.СодержимоеБиблиотеки(ИмяФайла);
КонецПроцедурыТегиПодключения
Функция ТегиПодключения(Знач Префикс = "/static") ЭкспортТеги подключения htmx и Alpine.js для вставки в макет. Завершающие слеши в префиксе отбрасываются.
Параметры: Префикс - Строка адрес, по которому раздаётся каталог статики.
Возвращаемое значение: Строка - два тега script, разделённые переводом строки.
Модель.Вставить("Скрипты", View.ТегиПодключения("/static"));<script src="/static/htmx.min.js"></script>
<script src="/static/alpine.min.js" defer></script>Alpine.js подключается с defer не для скорости: без него библиотека инициализируется раньше, чем разобран документ, и не находит разметку.
ВерсииБиблиотек
Функция ВерсииБиблиотек() ЭкспортВозвращаемое значение: Соответствие - "htmx" и "alpine" -> версия.
Версия проверяется тестом: объявленная здесь должна совпадать с версией внутри файла, иначе документация и то, что реально уходит браузеру, разъедутся.
Сообщить(View.ВерсииБиблиотек().Получить("htmx")); // 2.0.10Объекты
СоздатьОтображения
Функция СоздатьОтображения(Знач КаталогШаблонов, Знач Параметры = Неопределено) ЭкспортСоздаёт объект рендеринга шаблонов.
Параметры
| Параметр | Тип | Описание |
|---|---|---|
КаталогШаблонов | Строка | Каталог с файлами шаблонов |
Параметры | Структура, Соответствие | Настройки, см. ViewRenderer |
Возвращаемое значение: ViewRenderer - объект рендеринга.
Отображения = View.СоздатьОтображения("шаблоны", Новый Структура("Макет", "макет"));СоздатьЗащитуCSRF
Функция СоздатьЗащитуCSRF(Знач Секрет, Знач СрокЖизни = 3600) ЭкспортСоздаёт защиту форм от CSRF.
Параметры
| Параметр | Тип | Описание |
|---|---|---|
Секрет | Строка | Секрет приложения для подписи токенов |
СрокЖизни | Число | Срок жизни токена в секундах |
Возвращаемое значение: CsrfGuard - объект защиты форм.
Защита = View.СоздатьЗащитуCSRF(ПолучитьПеременнуюСреды("APP_SECRET"));