Come caricare il template jinja direttamente dal filesystem


87

Il documento API jinja su pocoo.org afferma:

Il modo più semplice per configurare Jinja2 per caricare i modelli per la tua applicazione è più o meno così:
from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader('yourapplication', 'templates'))
Questo creerà un ambiente modello con le impostazioni predefinite e un caricatore che cerca i modelli nella cartella dei modelli all'interno del pacchetto Python dell'applicazione .

A quanto pare, non è così semplice perché devi creare / installare un pacchetto python con i tuoi modelli al suo interno, il che introduce molta complessità inutile, specialmente se non hai intenzione di distribuire il tuo codice. Puoi fare riferimento a domande SO sull'argomento qui e qui , ma le risposte sono vaghe e insoddisfacenti.

Quello che un principiante ingenuo vuole fare, ovviamente, è semplicemente caricare il modello direttamente dal filesystem, non come una risorsa in un pacchetto. Come si fa?

Risposte:


129

Ecco come : usa a FileSystemLoaderinvece di PackageLoader. Ho trovato esempi sul web qui e qui . Supponiamo che tu abbia un file python nella stessa directory del tuo modello:

./index.py
./template.html

Questo index.py troverà il modello e lo visualizzerà:

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

Si scopre che il documento API jinja2 ha una sezione che discute tutti i caricatori integrati , quindi è un po 'imbarazzante non averlo notato subito. Ma l'introduzione è formulata in modo tale da PackageLoadersembrare il metodo predefinito, "più semplice". Per i nuovi arrivati ​​a Python, questo può portare a una caccia all'oca selvaggia.


96
Un po 'ridicolo non puoi caricare un modello da un file in una riga, ad esempiojinja2.load_template('template.html')
Matt

4
Ho sempre un wrapper che chiamo Jinja2 nelle mie applicazioni in cui metto tutta questa verbosità, quindi lo chiamo come:Jinja2.render(template_name, data)
Seraf

11
Rischio per la sicurezza importante! Quasi sicuramente vorrai chiamare jinja2.Environment(loader=templateLoader, autoescape=True). Oppure consulta i documenti api per maggiori informazioni. Ho appena scoperto di essermi ritrovato con una grave vulnerabilità XSS seguendo questa risposta: /
andrewdotn

Entrambi i collegamenti in alto sono interrotti.
sshow

77

Un modo più semplice è chiamare direttamente il jinj2.Templatecostruttore e utilizzare openper caricare il file:

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

1
Purtroppo ciò non consente l'impostazione di filtri personalizzati. Il caricamento del modello genera un errore durante l'inizializzazione perché il filtro personalizzato non esiste ancora. E in questo modo hai accesso all'ambiente (per includere il filtro) solo dopo l'inizializzazione.
Ronan Paixão

18

Ecco l'unico liner:

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

Quindi puoi eseguire il rendering del modello su un'altra riga o per tutto in una riga:

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

1
Purtroppo questo si interromperà se c'è l'ereditarietà dei modelli, poiché Jinja non sarà in grado di trovare i modelli di riferimento.
Bemmu

4
Ma fortunatamente questo è semplice e sufficiente se non usi l'ereditarietà e non vuoi semplicemente inviare qualche semplice email per esempio .. :)
smido

5

Se si utilizza Python 3.4+ e Jinja2 - v2.11 + - possiamo combinare pathlib e Filesystem di python per semplificare il flusso

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

Non mi sento a mio agio con l'utilizzo diretto Template(file)poiché l'elaborazione dell'ereditarietà del modello di Jinja potrebbe non funzionare bene.

Il supporto Pathlib è stato aggiunto solo nell'ultima versione di Jinja - v2.11 +

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.