Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Шаблонизация HTML Python: Веб-разработка (Flask)

Ранее в примерах мы возвращали HTML в виде строковых литералов. Выглядело это как-то так:

return '''<html>
  <head>
    <title>Hello!</title>
  </head>
  <body>
    <h1>World</h1>
  </body>
</html>
'''

Многострочные литералы нам, конечно же, помогают в этом деле. Но большие объёмы HTML-разметки становится сложно редактировать, да и код засоряется. Можно вынести HTML в файл, читать его и отдавать содержимое. Но как быть, если мы хотим изменить что-то в тексте? Можно использовать регулярные выражения или замену подстрок, но, как говорится, есть способ лучше — шаблонизация!

Напомню, шаблонизацией называется превращение некоей заготовки (шаблона), содержащей неизменную часть некоего текста, в финальную версию этого текста путём подстановки значений и выполнения других преобразований, описанных в шаблоне с использованием специального языка.

Flask, хоть и позиционирует себя как микрофреймворк, поставляется вместе с шаблонизатором (большинство микрофреймворков так не делает) Jinja2. Jinja2 — это популярный и мощный шаблонизатор, используемый повсеместно, от web-фреймворков до генераторов конфигурационных файлов (да, Jinja2 может формировать не только HTML!). Но именно во Flask он уже настроен так, чтобы начать использовать его было максимально просто!

Вызов шаблонизатора

Для того, чтобы вернуть из обработчика HTML, построенный на базе шаблона, вам нужен этот самый шаблон. Предположим, что у нас есть таковой — файл index.html:

<html>
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    {% if header %}
    <h1>{{ header }}</h1>
    {% endif %}
    {{ text }}
  </body>
</html>

В коде же мы пишем что-то такое:

from flask import render_template

@app.route('/')
def index():
    return render_template(
        'index.html',
        title='Hello, World!',
        header='Welcome',
        text='TODO'
    )

Разберём сначала код. Функция render_template принимает имя файла шаблона — это обязательный позиционный аргумент. Все именованные аргументы становятся контекстом шаблонизации (ниже я расскажу про контекст).

Теперь посмотрим на шаблон. В основном, содержимое шаблона представляет собой обычный HTML. Для шаблонизатора важны только подстановки значений вида {{ title }} и управляющие конструкции вида {% if header %}. В этом конкретном шаблоне подставляются заголовок страницы title, заголовок перед текстом header и текст страницы text. При этом условие if header позволяет не вставлять тег h1, если заголовок header не задан. Значения для подстановки ищутся по соответствующим именам в том самом контексте. В примере кода выше заданы все три значения, поэтому сервер отдаст такой HTML:

<html>
  <head>
    <title>Hello, World!</title>
  </head>
  <body>
    <h1>Welcome</h1>
    TODO
  </body>
</html>

Поиск шаблонов

Когда я выше упоминал содержимое шаблона и кода, его использующего, я не сказал, как следует располагать файлы с шаблонами относительно кода. По умолчанию принято шаблоны помещать в поддиректорию templates в директории с точкой входа вашего web-приложения. Например, если ваше приложение определено в файле hello_world.py, а шаблон называется index.html, то структура файлов и директорий будет такой:

tree

.
├── hello_world.py
└── templates/
    └── index.html

Безопасность шаблонов

Когда значение подставляется в шаблон, всё, хоть отдалённо похожее на HTML-теги, экранируется. Это защищает пользователя сайта от злонамеренной вставки в контент страницы невидимых блоков со скриптами и другого "опасного" содержимого. Такая защита особенно важна, когда шаблонизатор отображает данные, введённые другими пользователями.

Если же вы уверены, что знаете, что делаете, то вы можете указать при подстановке в конкретном месте суффикс |safe и значение из контекста будет подставлено "как есть":

<div>{{ content|safe }}</div>

Суффиксы вроде |safe называются фильтрами и их существует довольно много. Можно даже делать свои фильтры и тем самым расширять возможности шаблонизатора.

Прочие возможности

Я специально не стал здесь даже просто перечислять все возможности Jinja2, а только лишь показал, как начать использовать простые шаблоны. У Jinja2 есть прекрасная документация с множеством примеров. Кроме того в Интернете можно найти множество статей по использованию именно этого шаблонизатора — повторю, он очень популярен!

Ссылки

  • Официальный сайт Jinja2.

Задание

  1. В созданном ранее Flask-приложении добавьте обработчик пути /99-bottles, который должен будет отдать HTML-страницу, построенную с помощью шаблонизатора.
  2. Сделайте так, чтобы страница содержала маркированный список <ul> c элементами <li>. Элементы должны содержать строки "99 бутылок чего-то стояло на столе, одна упала и разбилась.", "98 бутылок..." и так далее вплоть до "Нет больше бутылок на столе.". Вам пригодится цикл for в его шаблонной версии.

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
18 мая 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»