Файлы шаблонов иногда пишутся дизайнерами или фронтенд-разработчиками, и сложность страниц может усложнить координирование. Рассмотрим правила хорошего тона как для приложений, передающих динамическое содержимое движку, так и для самих шаблонов.
• Никогда зачастую лучше, чем прямо сейчас. Файлам шаблонов должно передаваться только то динамическое содержимое, которое нужно отрисовать. Постарайтесь не передавать дополнительное содержимое на всякий случай: гораздо проще добавить отсутствующие переменные, чем убрать переменную, которая, скорее всего, не будет использоваться в работе.
• Постарайтесь держать логику за пределами шаблона. Многие движки шаблонов позволяют создавать сложные выражения или операции присваивания в самом шаблоне, а также встраивать код Python, который будет оценен именно в шаблоне. Это может привести к неконтролируемому росту сложности и зачастую усложняет поиск ошибок. Мы не против такого подхода — практичность побеждает красоту, — просто держите себя в руках.
• Отделяйте JavaScript от HTML. Зачастую необходимо смешивать шаблоны JavaScript с шаблонами HTML. Не теряйте голову: изолируйте те части, где шаблон HTML передает переменные в код JavaScript.
Все движки шаблонов, перечисленные в табл. 7.4, принадлежат ко второму поколению, их скорость отрисовки высока [90] Отрисовка редко является узким местом в веб-приложениях (обычно это доступ к данным).
, а функциональность создана благодаря опыту работы со старыми библиотеками шаблонов.
Таблица 7.4.Движки шаблонов
Библиотека Python |
Лицензия |
Причины использовать |
Jinja2 |
Лицензия BSD |
По умолчанию используется в Flask и поставляется с Django. Основана на языке шаблонов Django Template Language, в шаблоны можно добавить лишь немного логики. Jinja2 — это движок по умолчанию для Sphinx, Ansible и Salt (если вы использовали эти инструменты, вы знаете Jinja2) |
Chameleon |
Модифицированная лицензия BSD |
Шаблоны сами по себе являются корректными XML/HTML. Похожа на Template Attribute Language (TAL) и его derivatives |
Mako |
Лицензия MIT |
Используется по умолчанию в Pyramid. Разработана для повышения скорости выполнения программы — используйте, когда отрисовка шаблона ограничена во времени. Позволяет поместить большое количество кода в шаблоны — Mako похож на версию Python для PHP ( http://php.net/) |
В следующих разделах приводится более подробная информация о библиотеках из табл. 7.4.
Мы рекомендуем выбирать Jinja2 ( http://jinja.pocoo.org/) в качестве библиотеки шаблонов для новых веб-приложений Python. Используется в качестве движка по умолчанию в Flask и генераторе документации для Python Sphinx ( http://www.sphinx-doc.org/), может применяться в Django, Pyramid и Tornado. Она работает с основанным на тексте языком шаблонов, поэтому подойдет для генерации любой разметки, а не только HTML.
Позволяет настраивать фильтры, теги, тесты и глобальные переменные. Предоставляет возможность добавлять логику в шаблоны, что сокращает объемы кода.
Рассмотрим важные теги Jinja2:
{# Это комментарий, он выделяется решеткой и фигурными скобками. #}
{# Так можно добавить переменную: #}
{{title}}
{# Так можно определить именованный блок, который можно заменить #}
{# на шаблон-потомок. #}
{% block head %}
This is the default heading.
{% endblock %}
{# Так можно выполнить итерирование: #}
{% for item in list %}
{{ item }}
{% endfor %}
Рассмотрим пример сайта в комбинации с веб-сервером Tornado, описанным в подразделе «Tornado» текущего раздела:
# импортируем Jinja2
from jinja2 import Environment, FileSystemLoader
# импортируем Tornado
import tornado.ioloop
import tornado.web
# Загружаем файл шаблона templates/site.html
TEMPLATE_FILE = "site.html"
templateLoader = FileSystemLoader(searchpath="templates/")
templateEnv = Environment(loader=templateLoader)
template = templateEnv.get_template(TEMPLATE_FILE)
# Список популярных фильмов
movie_list = [
····[1,"The Hitchhiker's Guide to the Galaxy"],
····[2,"Back to the Future"],
····[3,"The Matrix"]
]
# Метод template.render() возвращает строку, содержащую отрисованный HTML
html_output = template.render(list=movie_list, title="My favorite movies")
# Обработчик для основной страницы
class MainHandler(tornado.web.RequestHandler):
····def get(self):
····# Возвращает отрисованную строку шаблона запросу браузера
········self.write(html_output)
# Присваиваем обработчик на сервер (127.0.0.1:PORT/)
Читать дальше