Шаблонизатор

Материал из Xgu.ru

Перейти к: навигация, поиск
Шаблонизатор берёт шаблон и данные и генерирует на их основе результирующий текст

Шаблонизатор (template engine) — ...

Все многочисленные способы генерирования текстовых файлов (любых: конфигурационных файлов, HTML-страниц, отчётов и прочих) можно разделить на три больших категории:

  1. Интерполяция текста
  2. Embedded-языки
  3. Использование шаблонизаторов

Интерполяция текст знакома всем программистам на shell, на python, perl и других языках программирования. В исходном тексте присутствуют определённые последовательности, обозначающие имена переменных, которые при обработке заменяются их значениями.

Например, на Python:

    """
    hostname %(hostname)s
    ip addr %(ip)s %(netmask)s
    """ % {
        "hostname": "router1",
        "ip":       "192.168.1.1",
        "netmask":  "255.255.255.0",
    }

Здесь %(hostname)s это последовательность, в котором python видит место, куда нужно подставить значение параметра hostname, передающегося с оператором интерполяции. В нашем примере данные передаются с помощью явного ассоциативного массива, но можно было использовать и локальные пременные напрямую:

    """
    hostname %(hostname)s
    ip addr %(ip)s %(netmask)s
    """ % locals()

Интерполяция, как правило, очень беспомощна. Максимум, что она может, это форматирование значений определённого типа (например, вывести действительное число с такой-то точностью после запятой) или простейшие команды (например, командная подстановка вида "`cmd`", в shell или perl). Ни циклов, ни условий, ничего более сложно в интерполяции, обычно, не предусмотрено.

На другом полюсе находятся embedded-языки, ярчайшем представителем которых является PHP. Embedded, то есть внедрённый, значит что язык напрямую используется в тексте, и для конструирования результата может использоваться вся мощь языка: условия, циклы, функции, библиотеки, объектная ориентация и так далее.

Минус этого подхода в другом — шаблон из исходного текста с изменяемыми значениями, чем он изначально был, превращается в полноценную программу, в которой уже и исходного текста не видно, а редактирование шаблона превращается в написание программы, со всеми вытекающими отсюда проблемами.

Но самое страшное даже не это — хуже что три стихии совершенно различные по своей природе — исходные данные, шаблон генерируемого текста и код смешиваются так, что не разберёшь. Именно за это чаще всего критикуют PHP его противники, и именно с этим борются предлагая Model-Template-View, Model-View-Controller и прочие архитектуры.

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

Воспринимайте шаблон как интерполяцию строк на стероидах. Использовать шаблонизатор это почти как использовать интерполяцию строк, просто считайте строка с переменными, только вы можете:

  1. Обращаться к вложенным данным (например, в шаблоне вы можете использовать что-то вроде {{ node.ipaddress }}, а в строке только готовое значение %( node_ipaddress )s, но не его по частям;
  2. Использовать простейшую логику (if или for).
  3. (Опционально) В развитых шаблонизаторах, таких как Jinja2 вы можете использовать наследование, включение друг в друга и прочее совместное использование шаблонов.

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

Важнейшим свойством шаблонизатора является развязка данных, логики и шаблона. Вы помните, что в шаблоне только логика, касающаяся генерации текста? Это позволяет использовать шаблонизаторы в совершенно различных системах, начиная от web-фреймворков (для которых они первоначально и разрабатывались) и заканчивая системами управления конфигурацией: jinja интегрирована и в Ansible и в SaltStack, и облегчает написание playbook'ов невероятно.

Вы можете использовать шаблонизаторы везде, где есть шаблон и динамически изменяемые данные:

  • Веб;
  • Конфигурационные файлы;
  • Отчёты;
  • Счета;
  • Письма;
  • Лабораторные и курсовые;
  • Заготовки для документов.

Какие шаблонизаторы наиболее известны и наиболее распространены?

Сейчас чаще всего шаблонизаторы пишутся на Python и для Python (хотя и не только! вообще, как правило, для всех языков они есть) и среди них можно назвать наиболее популярные:

  • Django (часть Django это шаблонизатор) — с него и началась особая популярность;
  • Jinja2 — как в Django, но намного мощнее + является независимым модулем;
  • Mako — другой синтаксис, больше свободы (может быть минусом для шаблонизаторов), быстрый (важной для нагруженных сайтов);
  • Genshi — очень интересное решение для XML-шаблонов (но очень медленное, если кого-то волнует скорость).

Сравните Genshi с Jinja2:

Это Jinja2:

<title>{% block title %}Page Title{% endblock %}</title>
{% if show_paragraph %}
  <p>{% trans %}Example paragraph with {{ variable }} content{% endtrans %}
{% endif %}

А это Genshi:

<title>Page Title</title>
<p py:if="show_paragraph">Example paragraph with $variable content</p>

Как уже было сказано, шаблонизаторы есть не только для Python, но и для Ruby, JavaScript, PHP (twig), Java/Scala/Clojure (scalate, twirl и другие), Go (text/template и другие) и даже Си и Си++ (Wt, CTemplate, CTPP).

[править] Шаблонизаторы в разных языках программирования

[править] Python

  • Jinja2
  • Mako
  • Genshi
  • Cheetah
  • ClearSilver
  • Kid
  • HTMLTemplate
  • Nevow
  • PSP
  • PyMeld
  • py.xml
  • XSLT
  • Xyaptu
  • ZPT

Сравнение скорости шаблонизаторов:

[править] Дополнительная информация