Question

J'ai un modèle base.html contenant une liste de liens.

Exemple:

   <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>

Ensuite, j'ai dans mes views.py une définition pour chacun des fichiers index.html, stuff.html, about.html et contact.html. Chacun de ces modèles dérive simplement d’un modèle base.html et définit ses propres titres et contenus.

Ma question concerne les éléments ci-dessus / j'ai une classe = "actuelle".

J'aimerais que la page en cours sur laquelle je me trouve ait cet attribut de classe.

Je pourrais définir une variable différente dans chaque vue, par exemple current_page = " about " puis effectuez une comparaison dans le modèle avec {% ifequal%} dans chaque élément de classe de chaque lien, mais cela semble être un travail en double (à cause de la variable de vue supplémentaire).

Y a-t-il un meilleur moyen? Peut-être que s'il existe un moyen d'obtenir le nom de la fonction d'affichage à partir duquel le modèle a été rempli automatiquement, je n'aurais pas besoin de définir la variable supplémentaire? En outre, cela semble être beaucoup d’équivalent.

Était-ce utile?

La solution

Voici une manière élégante de le faire, que j'ai copiée quelque part et que j'aimerais seulement pouvoir me rappeler où, pour pouvoir leur donner le crédit. 8 -)

J'attribue un id à chacune de mes pages (ou à toutes les pages d'une section) comme suit:

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

Et ensuite un id pour les liens correspondants:

<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>

Et dans le CSS, je fixe une règle comme celle-ci:

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

Cela fonctionne donc essentiellement de manière déclarative pour contrôler le style du lien auquel appartient la page actuelle. Vous pouvez le voir en action ici: http://entrian.com/source-search/

C'est un système très propre et simple une fois que vous l'avez configuré, car:

  • Vous n'avez pas besoin de vous occuper du balisage de modèle dans vos liens
  • Vous ne finissez pas par utiliser de grosses déclarations switch ou des instructions if / else / else
  • Ajout de pages à une section Just Works [TM]
  • Changer l'apparence des choses signifie toujours changer le CSS, pas le balisage.

Je n'utilise pas Django, mais ce système fonctionne n'importe où. Dans votre cas, vous définissez "leurs propres titres et contenus". vous devez également définir l'identifiant du corps , et aucun autre balisage Django n'est requis.

Cette idée s’applique facilement à d’autres situations, par exemple. "Je souhaite un lien de téléchargement dans la barre latérale de chaque page, à l'exception des pages de téléchargement elles-mêmes." Vous pouvez le faire en CSS comme ceci:

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

plutôt que de mettre du balisage de modèle conditionnel dans la barre latérale HTML.

Autres conseils

Je n'ai pas utilisé Django, mais j'ai traité le même problème dans Kohana (PHP) et Rails. .

Ce que je fais à 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>

Ce que je fais dans 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>

Je ne vois que deux façons de le faire, tout en évitant les répétitions égales:

  1. Javascript. Quelque chose dans les lignes de (jQuery):

    var parts = window.location.pathname.split('/');
    var page = parts[parts.length-1];
    $('#sidebar1 a[href*=' + page + ']').addClass('current');
    
  2. Modifiez vos vues pour qu'elles contiennent une liste de pages avec leurs titres et URL associés et créez une boucle {% pour%} dans votre modèle, qui parcourra cette liste et ajoutera un seul {% ifequal%}. .

Option 2 étant le favori de ma position. Si la logique de toutes vos pages est identique et que seuls les modèles diffèrent, vous pouvez envisager d'utiliser le modèle FlatPages pour chacune de vos pages. Si la logique est différente et que vous avez besoin de modèles différents, vous pouvez envisager d'utiliser une application de menu. Un plug éhonté: je possède une application de menu de mon propre

.

Si vous ajoutez le processeur de contexte request , c'est assez simple:

settings.py:

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

Vous avez maintenant accès au HttpRequest , qui contient le chemin de la demande. Pour mettre en surbrillance la page actuelle, il suffit de vérifier si le chemin correspond à la destination du lien, c’est-à-dire que vous y êtes déjà:

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top