Шаблонизация в 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.