Como carregar o template jinja diretamente do sistema de arquivos

87

O documento da API jinja em pocoo.org afirma:

A maneira mais simples de configurar o Jinja2 para carregar modelos para seu aplicativo é mais ou menos assim:
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
Isso criará um ambiente de modelo com as configurações padrão e um carregador que procura os modelos na pasta de modelos dentro do pacote python de seu aplicativo .

Acontece que isso não é tão simples porque você tem que fazer / instalar um pacote Python com seus modelos nele, o que apresenta muita complexidade desnecessária, especialmente se você não tem intenção de distribuir seu código. Você pode consultar as perguntas do SO sobre o tópico aqui e aqui , mas as respostas são vagas e insatisfatórias.

O que um novato ingênuo quer fazer, obviamente, é apenas carregar o modelo diretamente do sistema de arquivos, não como um recurso em um pacote. Como isso é feito?

Juan Tomas
fonte

Respostas:

129

Veja como : use a em FileSystemLoadervez de a PackageLoader. Encontrei exemplos na web aqui e aqui . Digamos que você tenha um arquivo python no mesmo diretório do seu modelo:

./index.py
./template.html

Este index.py encontrará o modelo e o renderizará:

#!/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)

Acontece que o documento da API jinja2 tem uma seção que discute todos os carregadores integrados , então é meio constrangedor não ter notado isso imediatamente. Mas a introdução está redigida de tal forma que PackageLoaderparece ser o método padrão, "mais simples". Para os recém-chegados ao python, isso pode levar a uma caça ao ganso selvagem.

Juan Tomas
fonte
96
Meio ridículo, você não pode carregar um modelo de um arquivo em uma linha, por exemplojinja2.load_template('template.html')
Matt
4
Sempre tenho um Wrapper que chamo de Jinja2 em meus aplicativos, onde coloco toda essa verbosidade, e chamo-o assim:Jinja2.render(template_name, data)
Seraf
11
Risco de segurança importante! Você quase certamente deseja ligar jinja2.Environment(loader=templateLoader, autoescape=True). Ou consulte os documentos da API para obter mais informações. Acabei de descobrir que acabei com uma grande vulnerabilidade XSS por seguir esta resposta: /
andrewdotn
Ambos os links no topo estão quebrados.
sshow
77

Uma maneira mais simples é chamar diretamente o jinj2.Templateconstrutor e usar openpara carregar o arquivo:

from jinja2 import Template
with open('template.html.jinja2') as file_:
    template = Template(file_.read())
template.render(name='John')
Cas
fonte
1
Infelizmente, isso não permite a configuração de filtros personalizados. O carregamento do modelo gera um erro durante a inicialização porque o filtro personalizado ainda não existe. E desta forma você só tem acesso ao ambiente (para incluir o filtro) após a inicialização.
Ronan Paixão
18

Aqui está o único forro:

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

Em seguida, você pode renderizar o modelo em outra linha ou para todos em uma linha:

rendered = Template(open('template_file.j2').read()).render(var="TEXT")
bcarroll
fonte
1
Infelizmente, isso será interrompido se houver herança de modelo, pois Jinja não conseguirá encontrar os modelos referenciados.
Bemmu
4
Mas, felizmente, isso é simples e suficiente se você não usar herança e apenas quiser enviar algum e-mail simples, por exemplo .. :)
smido
5

Se estiver usando Python 3.4+ e Jinja2 - v2.11 + - podemos combinar pathlib do python e o sistema de arquivos para simplificar o fluxo

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')

Não me sinto confortável com o uso direto, Template(file)pois o processamento de herança de modelo do Jinja pode não funcionar bem.

O suporte a Pathlib foi adicionado apenas na versão mais recente do Jinja - v2.11 +

Sairam Krish
fonte