В ранних примерах HTML-код встраивался непосредственно в функции представления. Это может быть приемлемо для демонстрационных целей, но в реальных проектах подобный подход не рекомендуется. Современные веб-страницы зачастую обладают большой сложностью и динамичностью. Размещение объемных HTML-блоков в коде представлений усложняет разработку и поддержку. Вместо этого, предпочтительнее использование шаблонов.

Шаблоны

Шаблон — это файл с разметкой HTML, дополненный специальными конструкциями для указания динамического содержания, которое подставляется во время выполнения. Превращение шаблона в статическую HTML-страницу называется рендерингом. Flask использует Jinja, встроенный шаблонизатор, который выполняет это преобразование.

Jinja — это мощный и популярный шаблонизатор среди Python-разработчиков, особенно часто используется в Django. Тем не менее, Flask и Jinja являются независимыми пакетами и могут использоваться автономно в различных проектах.

Отрисовка шаблонов с помощью render_template()

По умолчанию Flask ищет файлы шаблонов в каталоге templates, который располагается в корне папки приложения. Этот путь можно изменить, указав аргумент template_folder при создании экземпляра приложения Flask.

К примеру, следующий код задает новый путь для поиска шаблонов в каталоге jinja_templates в пределах директории приложения:

app = Flask(__name__, template_folder="jinja_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>

Этот шаблон включает в себя динамический элемент {{ name }}, который при рендеринге будет заменен значением, заданным в коде. Представим, что переменная name имеет значение Jerry, и в итоге HTML-код примет следующий вид:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

  <p>Name: Jerry</p>

</body>
</html>

Функция render_template позволяет взаимодействовать с шаблонами во Flask, интегрируя Jinja. Вызов render_template() с заданными шаблоном и данными производит рендеринг. Переданные в шаблон параметры формируют контекст. В следующем примере показывается рендеринг шаблона index.html:

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.

Перейдя по адресу http://localhost:5000/, вы увидите выводимую информацию:

Отрисовка шаблонов с помощью render_template()

При необходимости передачи множества параметров в 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')
#...

В результате, перейдя по адресу http://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

Создайте экземпляр Template, передав в него содержимое шаблона в виде строки:

>>>  t = Template("Name: {{ name }}")

Для выполнения рендеринга используйте метод render() объекта Template, передавая данные в виде ключевых слов:

>>> t.render(name='Jerry')
'Name: Jerry'

В следующем уроке мы подробно рассмотрим шаблонизатор Jinja.

Вопросы для самопроверки:

  1. Что такое шаблон в контексте Flask?
  2. В каком каталоге по умолчанию Flask ищет файлы шаблонов? Как можно изменить поведение по умолчанию?
  3. Какая функция во Flask используется для рендеринга шаблонов?
  4. Как можно передать множество параметров в функцию render_template()?