Templating With Jinja2 in Flask Advanced

Nella prima parte di questa serie di tutorial in tre parti, abbiamo visto come disporre la struttura del template in un'applicazione basata su Flask usando Jinja2. Abbiamo anche visto come i blocchi possono essere utilizzati per sfruttare l'ereditarietà nei modelli. In questa parte vedremo come scrivere un filtro personalizzato, un processore di contesto personalizzato e una macro.

Iniziare

Costruirò l'applicazione del catalogo che abbiamo creato nella prima parte di questa serie. Per prima cosa aggiungerò un processore di contesto Jinja2 personalizzato per mostrare un nome descrittivo per ciascun prodotto. Quindi creerò un filtro Jinja2 personalizzato per fare lo stesso lavoro del processore di contesto personalizzato. Quindi mostrerò come creare una macro Jinja2 personalizzata per i campi dei moduli regolari.

Creazione di un processore di contesto Jinja2 personalizzato

A volte, potremmo voler calcolare o elaborare un valore direttamente nei modelli. Jinja2 mantiene la nozione che l'elaborazione della logica dovrebbe essere gestita in viste e non in modelli e, quindi, mantiene i template puliti. In questo caso un processore di contesto diventa uno strumento utile. Possiamo passare i nostri valori a un metodo; questo verrà quindi elaborato in un metodo Python e verrà restituito il nostro valore risultante. Pertanto, stiamo essenzialmente aggiungendo una funzione al contesto del template (grazie a Python per averci permesso di aggirare funzioni come qualsiasi altro oggetto).

Quindi, supponiamo di voler aggiungere un nome descrittivo per ogni prodotto nel formato Categoria / nome prodotto. Per questo, è necessario aggiungere un metodo, che deve essere decorato con @ app.context_processor.

@ app.context_processor def some_processor (): def full_name (prodotto): restituisce '0 / 1'. format (product ['category'], product ['name']) return 'full_name': full_name

Tecnicamente, un contesto è solo un dizionario Python che può essere modificato per aggiungere e rimuovere valori. Qualsiasi metodo con il decoratore specificato dovrebbe restituire un dizionario che aggiornerebbe il contesto dell'applicazione corrente.

Per utilizzare questo processore di contesto, basta aggiungere il seguente tag Jinja2 nel modello.

full_name (prodotto)

Se aggiungiamo questo a quello flask_app / templates / product.html della nostra applicazione, sembrerebbe:

% estende 'home.html'% % block container% 

full_name (prodotto)

nome del prodotto'] categoria di prodotto']

$ product ['price']

% endblock%

La pagina del prodotto risultante ora sarà simile a:

Creazione di un filtro Jinja2 personalizzato

Dopo aver esaminato l'esempio precedente, gli sviluppatori esperti potrebbero pensare che fosse stupido utilizzare un processore di contesto per lo scopo. Si può semplicemente scrivere un filtro per ottenere lo stesso risultato; questo renderà le cose molto più pulite. È possibile scrivere un filtro per visualizzare il nome descrittivo del prodotto come mostrato di seguito.

@ app.template_filter ('full_name') def full_name_filter (prodotto): restituisce '0 / 1'. format (prodotto ['categoria'], prodotto ['nome'])

Questo filtro può essere usato come un normale filtro, cioè aggiungendo un | (tubo) simbolo e quindi il nome del filtro.

prodotto | nome completo

Il filtro di cui sopra produrrebbe lo stesso risultato dimostrato dal processore di contesto qualche tempo fa.

Per portare le cose a un livello superiore, creiamo un filtro che formatterà la valuta in base alla lingua locale del browser corrente. Per questo, prima dobbiamo installare un pacchetto Python chiamato CCY.

$ pip installa ccy

Ora dobbiamo aggiungere un metodo per il filtro di valuta.

import ccy da flask import request @app.template_filter ('format_currency') def format_currency_filter (amount): currency_code = ccy.countryccy (request.accept_languages.best [-2:]) restituisce '0 1'. format ( currency_code, importo)

Per utilizzare questo filtro, dobbiamo aggiungere quanto segue nel nostro modello:

product ['price'] | format_currency

Ora la pagina del prodotto sarà simile a:

Creazione di una macro Jinja2 personalizzata per i moduli

I macro ci permettono di scrivere pezzi riutilizzabili di blocchi HTML. Sono analoghi alle funzioni nei normali linguaggi di programmazione. Possiamo passare argomenti a macro come facciamo alle funzioni in Python e quindi usarli per elaborare il blocco HTML. I macro possono essere chiamati un numero qualsiasi di volte e l'output varierà secondo la logica al loro interno. Lavorare con le macro in Jinja2 è un argomento molto comune e ha molti casi d'uso. Qui vedremo semplicemente come è possibile creare una macro e poi usarla dopo l'importazione.

Uno dei pezzi di codice più ridondanti in HTML è la definizione dei campi di input nei moduli. La maggior parte dei campi ha un codice simile con alcune modifiche di stile e così via. Di seguito è una macro che crea campi di input quando viene chiamato. La migliore pratica è creare la macro in un file separato per una migliore riusabilità, per esempio, _helpers.html:

% macro render_field (name ,, type = "text") -%  % - endmacro%

Ora, questa macro dovrebbe essere importata nel file da utilizzare:

% da '_helpers.jinja' import render_field%

Quindi, può essere semplicemente chiamato usando il seguente:

render_field ('username', 'icon-user') render_field ('password', 'icon-key', type = "password") 

È sempre buona norma definire le macro in un file diverso in modo da mantenere pulito il codice e aumentare la leggibilità del codice. Se è necessaria una macro privata a cui non è possibile accedere al file corrente, denominare la macro con un carattere di sottolineatura che precede il nome.

Conclusione

In questo tutorial, abbiamo visto come scrivere un filtro personalizzato, un processore di contesto personalizzato e una macro personalizzata per i moduli. Nella parte successiva di questa serie, vedremo come implementare la formattazione avanzata di data e ora a livello di modello in Jinja2 usando moment.js.