Шаблонизатор
Материал из Xgu.ru
Шаблонизатор (template engine) — ...
Все многочисленные способы генерирования текстовых файлов (любых: конфигурационных файлов, HTML-страниц, отчётов и прочих) можно разделить на три больших категории:
- Интерполяция текста
- Embedded-языки
- Использование шаблонизаторов
Интерполяция текст знакома всем программистам на 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 и прочие архитектуры.
Шаблонизаторы берут лучшее из двух миров: с одной стороны они оставляют шаблон максимально похожим на шаблон, не превращая его в программу, с другой стороны — они позволяют автоматизировать наиболее очевидные рутинные задачи по генерации частей шаблона (но ни в коем случае не забирая на себя часть, ответственную за логику!).
Воспринимайте шаблон как интерполяцию строк на стероидах. Использовать шаблонизатор это почти как использовать интерполяцию строк, просто считайте строка с переменными, только вы можете:
- Обращаться к вложенным данным (например, в шаблоне вы можете использовать что-то вроде {{ node.ipaddress }}, а в строке только готовое значение %( node_ipaddress )s, но не его по частям;
- Использовать простейшую логику (if или for).
- (Опционально) В развитых шаблонизаторах, таких как 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
Сравнение скорости шаблонизаторов:
[править] Дополнительная информация
- Зачем нужен шаблонизатор? (рус.) — эта статья в Контакте