2012-09-05 9 views
16

Ho un file jinja_filters.py con alcune dozzine di filtri personalizzati che ho scritto. Ora ho più app Flask che devono usare questi filtri. (Non sono sicuro se il mio problema è Flask-specifica o no.)Come importare filtri jinja2 personalizzati da un altro file (e usando Flask)?

Un modo hacky per realizzare quello che voglio è fare:

app = Flask(__name__) 

import jinja_filters 

@app.template_filter('filter_name1') 
def filter_name1(arg): 
    return jinja_filters.filter_name1(arg) 

@app.template_filter('filter_name2') 
def filter_name2(arg): 
    return jinja_filters.filter_name2(arg) 

... 

Qual è il modo "giusto" per fare questo?

MODIFICA: Idealmente, non avrei bisogno di elencare ogni nome di filtro. Quindi, quando aggiungo un nuovo filtro a jinja_filters.py, non devo aggiornare nessun altro codice: tutte le mie app sarebbero in grado di usarlo subito.

risposta

25

Ove tu stia configurando l'oggetto app (app.py, forse), è sufficiente importare i filtri personalizzati e quindi modificare l'attributo dell'ambiente Jinja.

import jinja_filters 

app = Flask(__name__) 
app.jinja_env.filters['filter_name1'] = jinja_filters.filter_name1 
app.jinja_env.filters['filter_name2'] = jinja_filters.filter_name2 

e così via.

Un'altra possibilità è quella di utilizzare il modulo inspect per trovare tutti i metodi di jinja_filters in questo modo:

from inspect import getmembers, isfunction 
import jinja_filters 

app = Flask(__name__) 

my_filters = {name: function 
       for name, function in getmembers(jinja_filters) 
       if isfunction(function)} 

app.jinja_env.filters.update(my_filters) 

Quel codice non è testato, ma l'idea è quella di costruire un dizionario di nomi delle funzioni e delle funzioni che esistono in i tuoi file jinja_filters e quindi aggiorna il dizionario dei filtri dell'ambiente Jinja con i tuoi filtri.

+0

Questo è decisamente migliore di quello che ho. Ma c'è un modo in cui non devo elencare esplicitamente ogni nome di filtro? –

+0

Ho aggiornato la mia risposta con un'altra soluzione che potrebbe aggiungere dinamicamente i filtri usando il modulo 'inspect'. – aezell

+1

Bene, il lavoro va bene :) Ma non riesco ancora a credere che gli autori di Jinja2/Flask non avessero un modo più succinto di farlo. (Darò un segno di spunta alla tua risposta tra un paio di giorni se nessun altro vi entra). –

28

Esiste un metodo consigliato per farlo utilizzando Flask blueprints. Una delle sue casi d'uso è questa funzionalità specificamente:

  • Fornire filtri template, file statici, modelli e altre utilità attraverso i modelli. Un progetto non deve implementare applicazioni o visualizzare funzioni.

Hai solo bisogno di creare un oggetto flask.Blueprint e utilizzarlo per registrare i tuoi filtri in maniera simile a come si farebbe con flask.Flask oggetto app, utilizzando il decoratore Blueprint.app_template_filter o Blueprint.add_app_template_filter metodo.

# filters.py 

import jinja2 
import flask 

blueprint = flask.Blueprint('filters', __name__) 

# using the decorator 
@jinja2.contextfilter 
@blueprint.app_template_filter() 
def filter1(context, value): 
    return 1 

# using the method 
@jinja2.contextfilter 
def filter2(context, value): 
    return 2 

blueprint.add_app_template_filter(filter2) 

Poi basta registrare il progetto sul vostro oggetto app:

# app.py 

import flask 
import filters 

app = flask.Flask(__name__) 
app.register_blueprint(filters.blueprint) 

E voilà, sono registrati i filtri.

Problemi correlati