Як завантажити шаблон jinja безпосередньо з файлової системи


85

Документ API jinja на сайті pocoo.org говорить:

Найпростіший спосіб налаштувати Jinja2 для завантаження шаблонів для вашого додатку виглядає приблизно так:
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
Це створить середовище шаблону із налаштуваннями за замовчуванням та завантажувач, який шукає шаблони в папці шаблонів усередині пакету python yourapplication .

Як виявляється, це не так просто, тому що вам доводиться створювати / встановлювати пакет python зі своїми шаблонами, що вносить багато непотрібної складності, особливо якщо ви не маєте наміру розповсюджувати свій код. Ви можете звернутися до SO питань за темою тут і тут , але відповіді є розмитими і незадовільними.

Очевидно, що наївний новачок хоче просто завантажити шаблон безпосередньо з файлової системи, а не як ресурс у пакеті. Як це робиться?

Відповіді:


124

Ось як : використовуйте FileSystemLoaderзамість a PackageLoader. Я знайшов приклади в Інтернеті тут і тут . Скажімо, у вас є файл python у тому самому каталозі, що і ваш шаблон:

./index.py
./template.html

Цей index.py знайде шаблон і відтворить його:

#!/usr/bin/python
import jinja2

templateLoader = jinja2.FileSystemLoader(searchpath="./")
templateEnv = jinja2.Environment(loader=templateLoader)
TEMPLATE_FILE = "template.html"
template = templateEnv.get_template(TEMPLATE_FILE)
outputText = template.render()  # this is where to put args to the template renderer

print(outputText)

Виявляється, у документі jinja2 API є розділ, в якому розглядаються всі вбудовані навантажувачі , тому незручно не помітити цього відразу. Але вступ сформульований таким чином, що, PackageLoaderздається, є "найпростішим" методом за замовчуванням. Для новачків пітону це може призвести до переслідування диких гусей.


94
Начебто смішно, але ви не можете завантажити шаблон із файлу в один рядок, наприкладjinja2.load_template('template.html')
Метт

4
У мене завжди є Обгортка, яку я просто називаю Jinja2 у своїх додатках, де я вкладаю всю цю багатослівність, а потім називаю це так:Jinja2.render(template_name, data)
Сераф,

11
Важливий ризик безпеки! Ви майже напевно хочете зателефонувати jinja2.Environment(loader=templateLoader, autoescape=True). Або перегляньте документи api для отримання додаткової інформації. Щойно дізнався, що у мене виникла серйозна вразливість XSS, слідуючи цій відповіді: /
andrewdotn

Обидва посилання вгорі порушені.
шоу

76

Більш простий спосіб - це безпосередній виклик jinj2.Templateконструктора та використання openдля завантаження файлу:

from jinja2 import Template
with open('template.html.jinja2') as file_:
    template = Template(file_.read())
template.render(name='John')

1
На жаль, це не дозволяє налаштовувати власні фільтри. Завантаження шаблону генерує помилку під час ініціалізації, оскільки спеціальний фільтр ще не існує. І таким чином ви маєте доступ до середовища (включаючи фільтр) лише після ініціалізації.
Ronan Paixão,

17

Ось один лайнер:

template = Template(open('template_file.j2').read())

Потім ви можете відтворити шаблон на іншому рядку або для всіх в одному рядку:

rendered = Template(open('template_file.j2').read()).render(var="TEXT")

1
На жаль, це зламається, якщо існує успадкування шаблону, оскільки Jinja не зможе знайти шаблони, на які посилаються.
Бемму,

3
Але на щастя, це просто і досить, якщо ви не використовуєте спадщину, а просто не хочете, наприклад, надіслати якийсь простий електронний лист .. :)
smido

2

Якщо використовується Python 3.4+ та Jinja2 - v2.11 + - ми можемо поєднати pathlib python та файлову систему для спрощення потоку

from pathlib import Path
...

p = Path(__file__).parent.parent / 'templates' # sample relative path
env = Environment(
    loader=FileSystemLoader(Path(p)))
template = env.get_template('your_file.jinja2')

Мені неприємно користуватися безпосередньо, Template(file)оскільки обробка шаблону спадщини Jinja може не працювати належним чином.

Підтримка Pathlib додана лише в останній версії Jinja - v2.11 +

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.