2012-11-18 10 views
7

Desidero pane briciole per navigare nella mia app Flask. Un'opzione potrebbe essere quella di utilizzare un modulo generale di Python come bread.py:Implementazione di breadcrumb in Python usando Flask?

L'oggetto pane accetta una stringa URL e concede l'accesso all'URL briciole (parti) o collegamenti URL (lista di HREF a ogni briciola).

bread.py genera il breadcrumb dal percorso dell'URL, ma voglio che gli elementi del breadcrumb siano il titolo e il collegamento delle pagine visitate in precedenza.

In Flask, forse questo può essere fatto usando un decoratore o estendendo il decoratore @route.

C'è un modo per avere ogni chiamata di un route() aggiungere il titolo e il collegamento della pagina (definito nella funzione/classe decorata con @route) al breadcrumb? Ci sono altri modi per farlo? Qualche esempio di breadcrumb implementato per Flask?

risposta

10

Quindi, dopo il "percorso/cronologia", i "breadcrumb" anziché i "percorsi" per utilizzare la terminologia da wikipedia article?

Se si desidera accedere alla cronologia dell'utente dei collegamenti visitati, è necessario salvarli in una sessione. Ho avuto un tentativo di creare un decoratore per fare questo.

breadcrumb.py:

import functools 
import collections 

import flask 

BreadCrumb = collections.namedtuple('BreadCrumb', ['path', 'title']) 

def breadcrumb(view_title): 
    def decorator(f): 
     @functools.wraps(f) 
     def decorated_function(*args, **kwargs): 
      # Put title into flask.g so views have access and 
      # don't need to repeat it 
      flask.g.title = view_title 
      # Also put previous breadcrumbs there, ready for view to use 
      session_crumbs = flask.session.setdefault('crumbs', []) 
      flask.g.breadcrumbs = [] 
      for path, title in session_crumbs: 
       flask.g.breadcrumbs.append(BreadCrumb(path, title)) 

      # Call the view 
      rv = f(*args, **kwargs) 

      # Now add the request path and title for that view 
      # to the list of crumbs we store in the session. 
      flask.session.modified = True 
      session_crumbs.append((flask.request.path, view_title)) 
      # Only keep most recent crumbs (number should be configurable) 
      if len(session_crumbs) > 3: 
       session_crumbs.pop(0) 

      return rv 
     return decorated_function 
    return decorator 

Ed ecco un'applicazione di test che lo dimostra. Nota che ho appena usato la sessione lato client integrata di Flask, probabilmente vorrai usare una sessione lato server più sicura in produzione, come ad esempio Flask-KVsession.

#!/usr/bin/env python 
import flask 
from breadcrumb import breadcrumb 

app = flask.Flask(__name__) 

@app.route('/') 
@breadcrumb('The index page') 
def index(): 
    return flask.render_template('page.html') 

@app.route('/a') 
@breadcrumb('Aardvark') 
def pagea(): 
    return flask.render_template('page.html') 

@app.route('/b') 
@breadcrumb('Banana') 
def pageb(): 
    return flask.render_template('page.html') 

@app.route('/c') 
@breadcrumb('Chimp') 
def pagec(): 
    return flask.render_template('page.html') 

@app.route('/d') 
@breadcrumb('Donkey') 
def paged(): 
    return flask.render_template('page.html') 

if __name__ == '__main__': 
    app.secret_key = '83cf5ca3-b1ee-41bb-b7a8-7a56c906b05f' 
    app.debug = True 
    app.run() 

Ed ecco il contenuto del templates/page.html:

<!DOCTYPE html> 
<html> 
    <head><title>{{ g.title }}</title></head> 
    <body> 
     <h1>{{ g.title }}</h1> 
     <p>Breadcrumbs: 
     {% for crumb in g.breadcrumbs %} 
      <a href="{{ crumb.path }}">{{ crumb.title }}</a> 
      {% if not loop.last %}&raquo;{% endif %} 
     {% endfor %} 
     </p> 
     <p>What next?</p> 
     <ul> 
      <li><a href="/a">Aardvark</a>?</li> 
      <li><a href="/b">Banana</a>?</li> 
      <li><a href="/c">Chimp</a>?</li> 
      <li><a href="/d">Donkey</a>?</li> 
     </ul> 
    </body> 
</html> 
+0

questo è impressionante, ma cosa succede se si sta cercando di fare la 'location' briciole basate? potresti aggiungere anche una risposta? penserei che sarebbe molto più facile. – chrickso

+0

@chrisckso: Penso che le briciole di "posizione" siano ciò che [bread.py] (http://russell.ballestrini.net/a-homegrown-python-bread-crumb-module/) (come menzionato in [la domanda] (http://stackoverflow.com/q/13444666/445073)) fa? Hai provato? – Day

+0

sì, l'ho guardato, ma non sono un fan di questo, semplicemente estraendo l'url come vorrei personalizzare le parole. sto cercando il modo più semplice per fare un decoratore come @breadtrail (['Crumb A', url_for ('...)], [' Crumb B ', url_for (' ...)]) e passare sempre un breadtrail var riempito con quei dati a jinja senza dover digitare breadtrail = breadtrail per ogni percorso. – chrickso