2009-06-21 15 views
7

Ho un modello base.html che contiene un elenco di collegamenti.Django: C'è un modo migliore per evidenziare il link della pagina corrente

Esempio:

<div id="sidebar1"> 
     <ul> 
     <li><a href="/" title="">Index</a></li> 
     <li><a href="/stuff/" title="" class="current">Stuff</a></li> 
     <li><a href="/about/" title="">About Me</a></li> 
     <li><a href="/contact/" title="">Contact Me</a></li> 
    </div> 

Poi ho nel mio views.py una definizione per ciascuno dei index.html, stuff.html, about.html e contact.html. Ciascuno di questi modelli deriva semplicemente da un modello base.html e imposta i rispettivi titoli e contenuti.

La mia domanda riguarda quanto sopra/cose ho una classe = "corrente".

Mi piacerebbe che la pagina corrente su cui sono presente abbia quell'attributo di classe.

È possibile impostare una variabile diversa in ogni vista come current_page = "about" e quindi eseguire un confronto nel modello con {% ifequal %} in ogni elemento di classe di ciascun collegamento, ma sembra un lavoro di duplicazione (a causa della variabile di visualizzazione aggiuntiva).

C'è un modo migliore? Forse se c'è un modo per ottenere il nome della funzione vista che il modello è stato riempito automaticamente non avrei bisogno di impostare la variabile extra? Inoltre sembra un sacco di ifequals.

risposta

16

Ecco un modo elegante per farlo, che ho copiato da qualche parte e vorrei solo poter ricordare dove, così ho potuto dare loro il merito. 8-)

assegno un id a ciascuna delle mie pagine (o tutte le pagine all'interno di una sezione) come questo:

In index.html: <body id='section-intro'>... 
In faq.html:  <body id='section-faq'>... 
In download.html: <body id='section-download'>... 

E poi un id per i corrispondenti link:

<li id='nav-intro'><a href="./">Introduction</a></li> 
<li id='nav-faq'><a href="./faq.html">FAQ</a></li> 
<li id='nav-download'><a href="./download.html">Download</a></li> 

E l'nel CSS ho impostato una regola come questa:

#section-intro #nav-intro, 
#section-faq #nav-faq, 
#section-download #nav-download { 
    font-weight: bold; 
    /* And whatever other styles the current link should have. */ 
} 

Quindi questo funziona in modo prevalentemente dichiarativo per controllare lo stile del link a cui appartiene la pagina corrente. Puoi vederlo in azione qui: http://entrian.com/source-search/

È un sistema molto semplice e pulito una volta impostato, perché:

  • non è necessario pasticciare con il codice del modello nei tuoi link
  • non si finisce per usare grande brutta switch privacy o if/else/else dichiarazioni
  • Aggiunta di pagine a una sezione Just Works [TM]
  • Cambiare il modo in cui le cose sembrano sempre e solo significa cambiare il CSS, non il markup.

Non sto utilizzando Django, ma questo sistema funziona ovunque. Nel tuo caso, dove "imposti i rispettivi titoli e contenuti", devi anche impostare body id e non è richiesto nessun altro markup Django.

Questa idea si estende facilmente anche ad altre situazioni, ad es. "Voglio un collegamento per il download nella barra laterale di ogni pagina tranne le pagine di download."Si può fare in CSS in questo modo:

#section-download #sidebar #download-link { 
    display: none; 
} 

piuttosto che dover mettere condizionale il codice del modello nel codice HTML barra laterale

+0

questo non significa un sacco di contenuti duplicati nel CSS però? –

+0

... Intendo lo stile per ogni id di collegamento. –

+0

È una riga di CSS per ogni pagina/sezione. Lo stile stesso appare solo una volta, con un elenco separato da virgola di coppie di sezioni/nav prima di esso. – RichieHindle

2

non hanno usato Django, ma ho affrontato lo stesso problema in. Kohana (PHP) e Rails

che cosa fai nel Kohana:.

<li><a href="/admin/dashboard" <?= (get_class($this) == 'Dashboard_Controller') ? "class=\"active\"" : NULL ?>>Dashboard</a></li> 
<li><a href="/admin/campaigns" <?= (get_class($this) == 'Campaigns_Controller') ? "class=\"active\"" : NULL ?>>Campaigns</a></li> 
<li><a href="/admin/lists" <?= (get_class($this) == 'Lists_Controller') ? "class=\"active\"" : NULL ?>>Lists</a></li> 

che cosa fai nel Rails:

<li><a href="/main" <%= 'class="active"' if (controller.controller_name == 'main') %>>Overview</a></li> 
<li><a href="/notifications" <%= 'class="active"' if (controller.controller_name == 'notifications') %>>Notifications</a></li> 
<li><a href="/reports" <%= 'class="active"' if (controller.controller_name == 'reports') %>>Reports</a></li> 
1

vedo solo un paio di modi per farlo, evitando ifequals ripetuti:

  1. Javascript. Qualcosa sulla falsariga di (jQuery):

    var parts = window.location.pathname.split('/'); 
    var page = parts[parts.length-1]; 
    $('#sidebar1 a[href*=' + page + ']').addClass('current'); 
    
  2. Cambia i tuoi viste per contenere un elenco di pagine con i loro titoli associati e gli URL e creare un {% per%} ciclo nel modello, che andrà attraverso quella elenca e aggiungi un singolo {% ifequal%}.

L'opzione 2 è il preferito da dove mi trovo. Se la logica di tutte le tue pagine è la stessa e solo i modelli sono diversi, potresti prendere in considerazione l'utilizzo del modello FlatPages per ciascuna delle tue pagine. Se la logica è diversa e hai bisogno di modelli diversi, potresti prendere in considerazione l'utilizzo di un'app di menu di qualche tipo. Una spina spudorato: Ho un menuing app of my own

1

Se si aggiunge il processore request contesto, è abbastanza semplice:

settings.py: 

TEMPLATE_CONTEXT_PROCESSORS = (
    'django.core.context_processors.request', 
    'django.contrib.auth.context_processors.auth' # admin app wants this too 
) 

Ora avete accesso al HttpRequest, che contiene il percorso di richiesta. Evidenziando la pagina corrente è una semplice questione di verificare se il percorso corrisponde destinazione del link, vale a dire, sei già lì:

<li><a class="{% if request.path == '/' %}current{% endif %}" href="/">Index</a></li> 
<li><a class="{% if request.path == '/stuff/' %}current{% endif %}" href="/stuff/">Stuff</a></li> 
<li><a class="{% if request.path == '/about/' %}current{% endif %}" href="/about/">About Me</a></li> 
<li><a class="{% if request.path == '/contact/' %}current{% endif %}" href="/contact/">Contact Me</a></li> 
Problemi correlati