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

Установка Flask и создание проекта

Для начала работы установим Flask:

bash

pip install Flask

Теперь создадим минимальное Flask-приложение:

python

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')

def index():

return render_template('index.html')

if __name__ == '__main__':

app.run(debug=True)

Использование Jinja в HTML

Jinja встроен в Flask и позволяет нам вставлять переменные и логические конструкции прямо в HTML-шаблоны:

html

<!-- templates/index.html -->

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Flask Jinja Example</title>

</head>

<body>

<h1>Hello, {{ name }}!</h1>

</body>

</html>

Что такое контекстный процессор?

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

Пример контекстного процессора

python

from flask import Flask, render_template, request

app = Flask(__name__)

# Контекстный процессор для добавления переменной 'user_agent' в контекст

@app.context_processor

def inject_user_agent():

return dict(user_agent=request.user_agent)

@app.route('/')

def index():

return render_template('index.html', name='John Doe')

if __name__ == '__main__':

app.run(debug=True)

Использование переменных в HTML

Теперь мы можем использовать переменные из контекста в шаблоне:

html

<!-- templates/index.html -->

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Flask Jinja Example</title>

</head>

<body>

<h1>Hello, {{ name }}!</h1>

<p>Your user agent is: {{ user_agent.browser }} on {{ user_agent.platform }}</p>

</body>

</html>

Передача списков и циклы

Jinja поддерживает передачу списков и использование циклов в шаблонах. Рассмотрим пример передачи списка и отображения его элементов:

python

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')

def index():

fruit_list = ['Apple', 'Banana', 'Orange']

return render_template('fruits.html', fruits=fruit_list)

if __name__ == '__main__':

app.run(debug=True)

html

<!-- templates/fruits.html -->

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Fruit List</title>

</head>

<body>

<h1>Fruits:</h1>

<ul>

{% for fruit in fruits %}

<li>{{ fruit }}</li>

{% endfor %}

</ul>

</body>

</html>

Условные выражения

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

python

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')

def index():

user_status = 'authenticated'

return render_template('user.html', status=user_status)

if __name__ == '__main__':

app.run(debug=True)

html

<!-- templates/user.html -->

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>User Status</title>

</head>

<body>

{% if status == 'authenticated' %}

<h1>Welcome, User!</h1>

{% else %}

<h1>Access Denied</h1>

{% endif %}

</body>

</html>

Фильтры Jinja

Jinja предоставляет множество встроенных фильтров для обработки данных. Пример использования фильтра capitalize:

html

<!-- templates/capitalize.html -->

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Capitalized Text</title>

</head>

<body>

<p>{{ text|capitalize }}</p>

</body>

</html>

python

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')

def index():

sample_text = 'this text will be capitalized'

return render_template('capitalize.html', text=sample_text)

if __name__ == '__main__':

app.run(debug=True)

Расширение функциональности с собственным фильтром

Вы также можете создать собственный фильтр Jinja для уникальных операций. Рассмотрим пример создания фильтра для замены пробелов на подчеркивания:

python

from flask import Flask, render_template

app = Flask(__name__)

# Собственный фильтр для замены пробелов на подчеркивания

def replace_spaces(value):

return value.replace(' ', '_')

app.jinja_env.filters['replace_spaces'] = replace_spaces

@app.route('/')

def index():

sample_text = 'replace spaces with underscores'

return render_template('custom_filter.html', text=sample_text)

if __name__ == '__main__':

app.run(debug=True)

html

<!-- templates/custom_filter.html -->

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Custom Filter</title>

</head>

<body>

<p>{{ text|replace_spaces }}</p>

</body>

</html>

Заключение

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