Django: esiste un modo migliore per mettere in grassetto il collegamento alla pagina corrente

StackOverflow https://stackoverflow.com/questions/1024168

Domanda

Ho un modello base.html che contiene un elenco di collegamenti.

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>

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

La mia domanda riguarda quanto sopra / cose che ho un class = " corrente " ;.

Vorrei che la pagina corrente in cui mi trovo avesse quell'attributo di classe.

Potrei impostare una variabile diversa in ciascuna vista come current_page = " about " e quindi fare un confronto nel modello con {% ifequal%} in ciascun elemento di classe di ciascun collegamento, ma sembra duplicare il lavoro (a causa della variabile di visualizzazione aggiuntiva).

C'è un modo migliore? Forse se c'è un modo per ottenere il nome della funzione di visualizzazione da cui il modello è stato compilato automaticamente non avrei bisogno di impostare la variabile aggiuntiva? Inoltre sembra un sacco di ifequals.

È stato utile?

Soluzione

Ecco un modo elegante per farlo, che ho copiato da qualche parte e vorrei solo ricordare dove, in modo da potergli dare il merito. 8 -)

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

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 collegamenti corrispondenti:

<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 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 funziona in modo prevalentemente dichiarativo per controllare lo stile del collegamento a cui appartiene la pagina corrente. Puoi vederlo in azione qui: http://entrian.com/source-search/

È un sistema molto pulito e semplice dopo averlo configurato, perché:

  • Non è necessario pasticciare con il markup del modello nei collegamenti
  • Non finisci per usare grosse brutte istruzioni switch o if / else / else
  • Aggiunta di pagine a una sezione Funziona solo [TM]
  • Cambiare l'aspetto delle cose significa sempre e solo cambiare il CSS, non il markup.

Non sto usando Django, ma questo sistema funziona ovunque. Nel tuo caso, in cui "imposti i loro rispettivi titoli e contenuti" devi anche impostare body id e non è richiesto alcun altro markup Django.

Questa idea si estende facilmente anche ad altre situazioni, ad es. " Voglio un link per il download nella barra laterale di ogni pagina tranne le pagine di download stesse. " Puoi farlo in CSS in questo modo:

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

anziché dover inserire il markup del modello condizionale nell'HTML della barra laterale.

Altri suggerimenti

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

Cosa faccio in 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>

Cosa faccio in 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>

Vedo solo un paio di modi per farlo, evitando ripetuti uguali:

  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. Modifica le tue visualizzazioni in modo da contenere un elenco di pagine con i titoli e gli URL associati e crea un ciclo {% for%} nel tuo modello, che passerà attraverso tale elenco e aggiunga un singolo {% ifequal%} .

L'opzione 2 è la preferita da dove mi trovo. Se la logica di tutte le tue pagine è la stessa e solo i modelli differiscono, 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'uso di un'app di menu di qualche tipo. Una spina spudorata: ho una la mia app di menu

Se aggiungi il processore di contesto request , è abbastanza semplice:

settings.py:

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

Ora hai accesso al HttpRequest , che contiene il percorso della richiesta. Evidenziare la pagina corrente è una semplice questione di verificare se il percorso corrisponde alla destinazione del collegamento, ovvero, 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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top