LHTT: Углублённый анализ шаблонов и генерация HTML

Технология LHTT (Lisp Hyper-Text Template) использует представление HTML на основе структур данных языка Лисп. Она является синтезом технологий YHTML-TEMPLATE и LHTML. Полный цикл её применения изображен на следующем рисунке:

Исходный шаблон myfile.htt
parse-html
==>
LHTML
шаблонные вкрапления в виде строк
template-lhtt
==>
LHTT
шаблонные псевдо-элементы
lhtt-print
==>
среда: var1=val1...
Окончательный HTML
myfile.html

В прямоугольниках со сплошной рамкой показаны представления, с которыми контактирует пользователь (дизайнер, разработчик), не нуждающийся в знании языка Лисп. Пунктирной рамкой обведены скрытые от него внутренние представления в виде списков Лисп.

  1. На вход подаётся шаблон - файл со встроенными шаблонными тегами. Тег выглядит, как комментарий с особой начинкой (см. документацию по YHTML-Template). Теги не загромождают исходный файл, требуют минимального знания HTML и могут вноситься как с помощью простейшего текстового редактора, так и "навороченного" WYSIWYG-инструментария.
  2. Анализатор parse-html выполняет проверку синтаксиса исходного HTML, разбирает его и преобразует его в списковое представление LHTML.
  3. Во внутреннем LHTML шаблонные теги остаются "не разобранными", т.е. содержимое каждого шаблонного элемента представлено в виде одной строки Лисп.
  4. Конвертер template-lhtt анализирует шаблонные теги с учётом возможной вложенности и преобразует шаблон в формат LHTT.
  5. Во внутреннем LHTT присутствуют шаблонные псевдоэлементы :if, :loop и другие; это представление можно считать компилированным шаблоном.
  6. Принтер lhtt-print, помимо шаблона, принимает на вход среду - ассоциативный список, связывающий шаблонные переменные со значениями.
  7. На выходе получается "чистый" HTML или XHTML.

Определение формата LHTT

Формально, форма LHTT есть одна из следующих

Функции

Сигнатура

[Function] template-lhtt lhtml &optional (package (find-package :html))

Описание

Преобразует одну форму LHTML в форму LHTT.

Сигнатура

[Generic Function] parse-htt arg &optional package

Описание

Преобразует аргумент в список форм LHTT. Определены методы, специализированные по arg: список форм LHTML или спецификация файла.

Сигнатура

[Function] lhtt-print lhtt environment &optional (stream *html-stream*)

Описание

Конвертирует одну форму LHTT в HTML и печатает результат в поток stream.

Сигнатура

[Function] lhtt-print-list lhtt-list environment &optional (stream *html-stream*)

Описание

Конвертирует список форм LHTT в HTML и печатает их подряд в поток stream. Это эквивалентно вызову lhtt-print над каждым элементом списка lhtt-list.

Пример

(setq htt "<html>
<ul>
<!-- TMPL_LOOP rows -->
<li><a href='<!-- TMPL_EVAL foo -->'><!-- TMPL_EVAL bar --></a> <b>Bold</b>,
<!-- TMPL_EVAL (list baz 1) --></li>
<!-- /TMPL_LOOP -->
</ul>
</html>")
> (setq lhtml (phtml:parse-html htt)) =>
((:HTML
  (:UL
   (:COMMENT " TMPL_LOOP rows ")
   (:LI
    ((:A :HREF "<!-- TMPL_EVAL foo -->") (:COMMENT " TMPL_EVAL bar ")) " "
     (:B "Bold") ","
     (:COMMENT " TMPL_EVAL (list baz 1) "))
     (:COMMENT " /TMPL_LOOP "))))
> (setq lhtt (html:parse-htt lhtml)) =>
((:HTML
 (:UL (:LOOP ROWS
        (:LI ((:A :HREF (:OPTIONAL FOO))
             (:EVAL BAR)) " "
             (:B "Bold") ","
             (:EVAL (LIST BAZ 1)))))))
> (html:lhtt-print-list lhtt
  '((rows . (((foo . "a.html") (bar . "EINS") (baz . "ONE"))
((foo . "b.html") (bar . "ZWEI") (baz . "TWO"))))) =>
<html>
<ul>
<li><a href="a.html">EINS</a> <b>Bold</b>, ONE 1</li>
<li><a href="b.html">ZWEI</a> <b>Bold</b>, TWO 1</li>
</ul>
</html>