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
.