Выбрать главу
Таблица 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

Мы рекомендуем выбирать Jinja2 (http://jinja.pocoo.org/) в качестве библиотеки шаблонов для новых веб-приложений Python. Используется в качестве движка по умолчанию в Flask и генераторе документации для Python Sphinx (http://www.sphinx-doc.org/), может применяться в Django, Pyramid и Tornado. Она работает с основанным на тексте языком шаблонов, поэтому подойдет для генерации любой разметки, а не только HTML.

Позволяет настраивать фильтры, теги, тесты и глобальные переменные. Предоставляет возможность добавлять логику в шаблоны, что сокращает объемы кода.

Рассмотрим важные теги Jinja2:

{# Это комментарий, он выделяется решеткой и фигурными скобками. #}

{# Так можно добавить переменную: #}

{{title}}

{# Так можно определить именованный блок, который можно заменить #}

{# на шаблон-потомок. #}

{% block head %}

<h1>This is the default heading.</h1>

{% endblock %}

{# Так можно выполнить итерирование: #}

{% for item in list %}

<li>{{ item }}</li>

{% 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/)

application = tornado.web.Application([

····(r"/", MainHandler),

])

PORT=8884

if __name__ == "__main__":

····# Настраиваем сервер

····application.listen(PORT)

····tornado.ioloop.IOLoop.instance(). start()

Файл base.html может быть использован в качестве основы для всех страниц сайта. В этом примере они могли бы быть реализованы в блоке content (в данный момент пуст):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">

<html lang="en">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

····<link rel="stylesheet" href="style.css" />

····<title>{{title}} — My Web Page</title>

</head>

<body>

<div id="content">

····{# В следующей строке будет добавлено содержимое шаблона site.html #}

····{% block content %}{% endblock %}

</div>

<div id="footer">

····{% block footer %}

····&copy; Copyright 2013 by <a href="http://domain.invalid/">you</a>.