Использование функций Python в шаблонизаторе Jinja2

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы вызвать функцию Python из шаблона Jinja2, необходимо передать эту функцию в контекст рендеринга при использовании render_template во Flask:

Python
Скопировать код
# Определите функцию
def greet(name):  
    return f"Привет, {name}"

# Передайте её в шаблон
return render_template('template.html', greet=greet)

# Вызовите функцию в шаблоне
# {{ greet('World') }}

Здесь функция greet регистрируется, передаётся в template.html и вызывается в шаблоне Jinja2.

Кинга Идем в IT: пошаговый план для смены профессии

Расширенное использование

Глобальная регистрация функций

Функции можно сделать доступными глобально во всех шаблонах, чтобы избежать повторения их определения для каждого отдельного шаблона:

Python
Скопировать код
# Присваиваем функции глобальный статус
app.jinja_env.globals['greet'] = greet

Теперь greet может быть вызвана в любом шаблоне без дополнительной передачи.

Функции контекстных процессоров Flask для автоматической подачи данных

Контекстные процессоры Flask предоставляют возможность автоматически добавлять функции или переменные во всех шаблонах:

Python
Скопировать код
@app.context_processor
def utility_processor():
    def format_price(amount, currency="$"):
        return f"{currency}{amount:.2f}"
    return dict(format_price=format_price)

Изоляция функций в модулях

Для структурирования кода удобно определить функции отдельно и импортировать их по мере необходимости:

Python
Скопировать код
# utilities.py
def compute_discount(price, discount):
    return price – price * discount

В основном файле Python:

Python
Скопировать код
from utilities import compute_discount
app.jinja_env.globals['compute_discount'] = compute_discount

Передача определённых функций в шаблоны

Можно передать функции определённым шаблонам для их эксклюзивного использования:

Python
Скопировать код
return render_template('sales.html', compute_discount=compute_discount)

Пользовательские фильтры Jinja2

Создайте собственные фильтры Jinja для выполнения определённых задач:

Python
Скопировать код
@app.template_filter('topthree')
def topthree_filter(sequence):
    return sequence[:3]

Загрузчики шаблонов Jinja2

Для загрузки шаблонов в Jinja2 используйте класс FileSystemLoader:

Python
Скопировать код
from jinja2 import Environment, FileSystemLoader

env = Environment(loader=FileSystemLoader('/path/to/templates'))
env.globals['greet'] = greet
template = env.get_template('my_template.html')
print(template.render())

Версия Jinja2

Убедитесь, что используемые функции совместимы с используемой вами версией Jinja2:

Python
Скопировать код
import jinja2
print(jinja2.__version__)

Визуализация

Можно представить вызов функции Python в Jinja2 следующим образом:

Markdown
Скопировать код
Python 🐍 определяет функцию *encrypt_message*
Jinja2 🏰 желает использовать функцию *encrypt_message*

Взаимодействие между ними:

Python
Скопировать код
{{ encrypt_message('Секретный код') }}

Результат:

Markdown
Скопировать код
🏰 получает от 🐍 'Секретный код', преобразует и отправляет обратно ➡️ '*Зашифрованное сообщение*'

Процесс будет успешным, если функция определена в Python и передана в Jinja2.

Практические сценарии и подводные камни

Генерация динамического контента

Динамическую генерацию контента можно реализовать путем вызова функций обработки данных в шаблонах:

HTML
Скопировать код
<ul>
  {% for user in users %}
    <li>{{ get_user_role(user) }}</li>
  {% endfor %}
</ul>

Кэширование для улучшения производительности

Для увеличения скорости работы приложения используйте кэширование результатов функций. Это позволит избежать повторных расчетов данных при каждом запросе.

Сохранение лаконичности шаблонов

Стремитесь к минимализму в шаблонах, избегая замешательства сложными функциями. Следуйте принципу DRY (Don't Repeat Yourself — не повторяйся).

Разделение логики приложения

Логику приложения следует разделять на бизнес-логику и логику отображения: логику в шаблонах Jinja2 следует минимизировать, предоставив обработку данных функциям Python.

Полезные материалы

  1. Документация Jinja для дизайнера шаблонов
  2. Документация по шаблонам во Flask
  3. Вызов функции Python из Jinja2 — Stack Overflow
  4. Основы работы с шаблонами в Jinja – Real Python
  5. Мега-учебник Flask, часть II: Шаблоны – miguelgrinberg.com
  6. API Jinja
  7. Hackers and Slackers