До этого момента HTML-строки записывались прямо в функцию представления. Это нормально в демонстрационных целях, но неприемлемо при создании реальных приложений. Большинство современных веб-страниц достаточно длинные и состоят из множества динамических элементов. Вместо того чтобы использовать огромные блоки HTML-кода прямо в функциях (с чем еще и неудобно будет работать), применяются шаблоны.
Шаблоны
Шаблон — это всего лишь текстовый файл с HTML-кодом и дополнительными элементами разметки, которые обозначают динамический контент. Последний станет известен в момент запроса. Процесс, во время которого динамическая разметка заменяется, и генерируется статическая HTML-страница, называется отрисовкой (или рендерингом) шаблона. Во Flask есть встроенный движок шаблонов Jinja, который и занимается тем, что конвертирует шаблон в статический HTML-файл.
Jinja — один из самых мощных и популярных движков для обработки шаблонов для языка Python. Он должен быть известен пользователям Django. Но стоит понимать, что Flask и Jinja – два разных пакета, и они могут использоваться отдельно.
Отрисовка шаблонов с помощью render_template()
По умолчанию, Flask ищет шаблоны в подкаталоге templates
внутри папки приложения. Это поведение можно изменить, передав аргумент template_folder
конструктору Flask
во время создания экземпляра приложения.
Этот код меняет расположение шаблонов по умолчанию на папку jinja_templates
внутри папки приложения.
app = Flask(__name__, template_folder="jinja_templates")
Сейчас в этом нет смысла, поэтому пока стоит продолжать использовать папку templates
для хранения шаблонов.
Создаем новую папку templates
внутри папки приложения flask_app
. В templates
— файл index.html
со следующим кодом:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>Name: {{ name }}</p>
</body>
</html>
Стоит обратить внимание, что в «базовом» HTML-шаблоне есть динамический компонент {{ name }}
. Переменная name
внутри фигурных скобок представляет собой переменную, значение которой будет определено во время отрисовки шаблона. В качестве примера можно написать, что значением name
будет Jerry
. Тогда после рендеринга шаблона выйдет следующий код.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>Name: Jerry</p>
</body>
</html>
Flask предоставляет функцию rended_template
для отрисовки шаблонов. Она интегрирует Jinja во Flask. Чтобы отрисовать шаблон, нужно вызвать rended_template()
с именем шаблона и данными, которые должны быть в шаблоне в виде аргументов-ключевых слов. Аргументы-ключевые слова, которые передаются шаблонам, известны как контекст шаблона. Следующий код показывает, как отрисовать шаблон index.html
с помощью render_template()
.
from flask import Flask, request, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html', name='Jerry')
#...
Важно обратить внимание, что name
в name='Jerry'
ссылается на переменную, упомянутую в шаблоне index.html
.
Если сейчас зайти на https://localhost:5000/
, выйдет следующий ответ:
Если render_template()
нужно передать много аргументов, можно не разделять их запятыми (,
), а создать словарь и использовать оператор **
, чтобы передать аргументы-ключевые слова функции. Например:
@app.route('/')
def index():
name, age, profession = "Jerry", 24, 'Programmer'
template_context = dict(name=name, age=age, profession=profession)
return render_template('index.html', **template_context)
Шаблон index.html
теперь имеет доступ к трем переменным шаблона: name
, age
и profession
.
Что случится, если не определить контекст шаблона?
Ничего не случится, не будет ни предупреждений, ни исключений. Jinja отрисует шаблон как обычно, а на местах пропусков использует пустые строки. Чтобы увидеть это поведение, необходимо изменить функцию представления index()
следующим образом:
#...
@app.route('/')
def index():
return render_template('index.html')
#...
Теперь при открытии https://localhost:5000/
выйдет следующий ответ:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>Name: </p>
</body>
</html>
Сейчас должна сложиться картина того, как используются шаблоны во Flask, а в следующем разделе речь пойдет о том, как рендерить их в консоли.
Отрисовка шаблонов в консоли
Для тестирования рендерить шаблоны можно и в консоли. Это просто и не требует создания нескольких файлов. Для начала нужно запустить Python и импортировать класс Template
из пакета jinja2
следующим образом.
>>> from jinja2 import Template
Для создания объекта Templates
нужно передать содержимое шаблона в виде строки.
>>> t = Template("Name: {{ name }}")
Чтобы отрендерить шаблон, нужно вызвать метод render()
объекта Template
вместе с данными аргументами-ключевыми словами
>>> t.render(name='Jerry')
'Name: Jerry'
В следующем уроке речь пойдет о шаблонизаторе Jinja.