2013-04-07 6 views
28

Viele Routen rund um meine Blueprint-App müssen "Sidebar-Daten" an Jinja senden.Wie kann ich Variablen zu Jinja Vorlage von einem Flask Decorator senden?

Ich bin auf der Suche nach dem effizientesten Weg, dies zu tun. Das hat etwas Besseres sein als meine ‚generate_sidebar_data()‘ Import-Funktion in jeden Plan, immer wieder sagen:

var1, var2, var3 = generate_sidebar_data() 

und sendet sie dann mit ‚render_template‘:

return render_template('template.html', 
          var1=var1, 
          var2=var2, 
          var3=var3 
        ) 

Was ich will, es ist ein Dekorateur, den ich mit der Route setzen kann, die das gleiche tun wird, das oben genannte tut (Funktion ausführen und die vars an jinja senden), aber ich weiß nicht, ob das möglich ist. Wie sende ich Variablen aus einer Decorator-Funktion an Jinja?

@blueprint.route('/') 
@include_sidebar_data 
def frontpage(): 

    return render_template('template.html') 

Antwort

4

Sie könnten einen Dekorateur Funktion wie folgt erstellen:

def include_sidebar_data(fn): 
    template_name = fn() 
    var1, var2, var3 = generate_sidebar_data() 
    def wrapped(): 
     return render_template(template_name, var1=var2, var2=var2) 
    return wrapped 

@blueprint.route('/') 
@include_sidebar_data 
def frontpage(): 

    return 'template.html' 
11

Sie können einen Kontext-Prozessor (http://flask.pocoo.org/docs/api/#flask.Flask.context_processor):

def include_sidebar_data(fn): 
    @blueprint.context_processor 
    def additional_context(): 
     # this code work if endpoint equals to view function name 
     if request.endpoint != fn.__name__: 
      return {} 
     var1, var2, var3 = generate_sidebar_data() 
     return { 
      'var1': var1, 
      'var2': var2, 
      'var3': var3, 
     } 
    return fn 


@blueprint.route('/') 
@include_sidebar_data 
def frontpage(): 
    return render_template('template.html') 

UPD: Ich mag das nächste Beispiel mehr und es ist besser, wenn der Dekorator für verschiedene Ansichtsfunktionen verwendet wird:

sidebar_data_views = [] 


def include_sidebar_data(fn): 
    sidebar_data_views.append(fn.__name__) 
    return fn 


@blueprint.context_processor 
def additional_context(): 
    # this code work if endpoint equals to view function name 
    if request.endpoint not in sidebar_data_views: 
     return {} 
    var1, var2, var3 = generate_sidebar_data() 
    return { 
     'var1': var1, 
     'var2': var2, 
     'var3': var3, 
    } 


@blueprint.route('/') 
@include_sidebar_data 
def frontpage(): 
    return render_template('template.html') 
+0

Ich habe mit dem context_processor herumgespielt, bin aber auf dem '@blueprint' Teil aufgelegt. meine Dekorateure sind nicht in einem Blueprint, also gibt es kein '@app' oder '@blueprint' verfügbar – chrickso

+0

Also @app decorator verwenden, die Kontext für alle Anwendungen mit beliebigen Blaupausen hinzufügen. – tbicr

+0

@tbicr Alter Kommentar, ich weiß. Aber Sie haben in den Beispielen "Blaupause" falsch geschrieben. –

21

Ich werde etwas noch einfacher schlagen als eine Dekorateur oder Template-Methode oder etwas ähnliches verwenden:

def render_sidebar_template(tmpl_name, **kwargs): 
    (var1, var2, var3) = generate_sidebar_data() 
    return render_template(tmpl_name, var1=var1, var2=var2, var3=var3, **kwargs) 

Yup, nur eine Funktion. Das ist alles was du wirklich brauchst, oder? Siehe this Flask Snippet zur Inspiration. Es macht im Wesentlichen genau die gleiche Sache, in einem anderen Kontext.

+0

Sehr sauber - ich mag es. – dmonopoly

+0

Was @dmonopoly sagte. Auch 2016 noch hilfreich. Danke, +1. –

Verwandte Themen