YHTML-Template — это переносимая Коммон Лисп библиотека, базирующаяся на исходном коде HTML-TEMPLATE Эдмунда Вайца (Edi Weitz). С её помощью работающая программа "наполняет" текстовые шаблоны конкретным содержанием. Является ли фактический результат текстом в формате HTML или нет, неважно. Хотя в основном, библиотека используется именно для генерации HTML.
Поскольку прототипом послужил модуль Перл HTML::Template (см. также в Википедии), в части синтаксиса шаблонов обе библиотеки имеют немало общего. Похожий синтаксис шаблонов применяются и в phpBB — популярном пакете для создания форумов.
Исходный код библиотеки-прототипа и документация на английском находятся здесь http://weitz.de/html-template/. В YHTML-Template в этот код с доработан с целью придать синтаксису больший "Лисп-оттенок". Внесены также новые конструкции, см. ниже.
YHTML-Template сочетает возможности двух типов шаблонов.
<html>
<head><title><!-- TMPL_EVAL title --></title></head>
<body>
<p>Вывод списка:</p>
<ul>
<!-- TMPL_LOOP items -->
<li><!-- TMPL_EVAL item --></li>
<!-- TMPL_LOOPELSE -->
<li>(нет данных)</li>
<!-- /TMPL_LOOP items -->
</ul>
</body>
</html>
Стандартный синтаксис псевдотегов шаблона выглядит
словно комментарий HTML.
Открывающий тег:
<!-- TMPL_tag form... ; comment -->
Закрывающий тег:
<!-- /TMPL_tag comment -->
TMPL_FOR, TMPL_LOOP и TMPL_CALL
допустима последовательность, т.е. список или вектор.-->.| Возможность | HTML::Template | HTML-TEMPLATE | YHTML-Template | phpBB |
|---|---|---|---|---|
| Получение значения переменной | да | да | да | да |
| Присваивание значения переменной | нет | нет | да | нет |
| Обращение напрямую к полям структур, вызов функций и методов | нет | нет | да | да |
| Цикл по списку или массиву for/foreach/dolist | да | да | да | да |
| Цикл по счётчику repeat/dotimes | нет | да | да | нет |
| Вложение шаблонов | да | да | да | да |
| Передача параметров в подшаблон | нет | нет | да | нет |
Исходные файлы доступны в любом из дистрибутивов:
Инструкции по развёртыванию находятся в файле INSTALLATION.TXT (на английском языке).
TMPL_INCLUDE, а в остальных местах допустимы произвольные формы Лисп,
считываемые стандартной функцией read.keyword; поскольку с точки зрения идеологии Лисп
ключи являются константами, их использование в качестве переменных
семантически неадекватно.
*template-package* (новая специальная переменная).
template-eval.
Она оценивает выражения, аналогично стандартной функции eval, но
в упрощённом варианте:
IF WHEN UNLESS AND OR NOT QUOTE PROGN SETQ;
symbol-value;
*value-access-function*.
TMPL_EVAL, предназначенный в качестве замены
TMPL_VAR, для него реализована новая функция подстановки
create-eval-printer.TMPL_VAR поддерживается для совместимости.
*format-non-strings*.
Если оно есть T, подставляемый текст формируется из объекта, как и прежде, с
помощью princ-to-string,
т.е. (format nil "~A" ...).*string-modifier*.TMPL_ELIF позволяет писать более короткие
шаблоны. Полный синтаксис "условного оператора" теперь такой:
<!-- TMPL_IF condition_1 --> body_1 <!-- TMPL_ELIF condition_2 --> body_2 ... <!-- TMPL_ELSE --> else_body <!-- /TMPL_IF -->
TMPL_LOOPELSE позволяет указать текст
выдаваемый когда длина аргумента-последовательности, по которому идёт цикл,
равна нулю.
<!-- TMPL_LOOP sequence --> body_1 <!-- TMPL_LOOPELSE --> else_body <!-- /TMPL_LOOP -->
TMPL_FOR реализует цикл общего вида.
Он моделирует специальные операторы Коммон Лисп
dolist, dotimes и loop for across.
<!-- TMPL_FOR var sequence-or-integer --> body <!-- TMPL_FORELSE --> else_body <!-- /TMPL_FOR -->
TMPL_LET, связывающий динамические
переменные с произвольным значением подобно специальные оператору
let Коммон Лисп.
<!-- TMPL_LET { var1 | (var1 expr1) } ... -->
body
<!-- /TMPL_LET -->
TMPL_INCLUDE:
<!-- TMPL_INCLUDE filename [(var expr)] ... -->Это позволяет передавать аргументы при вызове подшаблона.
(create-template-printer pathname) происходит
во время прогона внутри лексического замыкания, созданного вызывающим
принтером, и изменение файла pathname приводит к его повторной компиляции,
так как дата в кэше сопоставляется с датой, возвращённой
file-write-date.*ignore-tag-rest* контролирует,
допустим ли перед маркером "-->" произвольный текст.TMPL_EVAL, TMPL_VAR, TMPL_IF, TMPL_ELIF,
TMPL_UNLESS, TMPL_LOOP, TMPL_REPEAT, TMPL_CALL,TMPL_FOR,TMPL_ELSE, TMPL_FORELSE
и всех завершающих /TMPL_....<!-- TMPL_EVAL (+ row-number 1) Increase by one --> <!-- TMPL_FOR var '(1 2 3) ; Loop over items --> <!-- /TMPL_LOOP ; rows -->Указанный текст служит для улучшения читабельности шаблона и игнорируется анализатором. Дело вкуса — начинать такой текст с точки запятой (;).
*ignore-tag-rest* есть ложь,
анализатор, обнаружив "лишние" аргументы, сигналит об ошибке.
*ignore-comments* контролирует
удаление комментариев, заключённых в <!--...-->, в том
числе нераспознанных шаблонных тегов, из результирующего HTML-кода.(let ((*ignore-comments* t)) ... "The <!-- comment --> brown fox" ...) => "The brown fox"
Чтобы работать в YHTML-Template с шаблонам в синтаксисе HTML-TEMPLATE, проделайте следующее.
*attributes-are-lisp-forms*
равным NIL.