web-dev-qa-db-fra.com

Jekyll - Mettre en surbrillance automatiquement l'onglet actuel dans la barre de menus

J'utilise github pour héberger un site statique et Jekyll pour le générer.

J'ai une barre de menus (comme <ul>) Et je voudrais que le <li> Correspondant à la page en cours se voit attribuer une classe différente pour la mise en évidence CSS.

Donc, quelque chose comme un pseudo-code:

<li class={(hrefpage==currentpage)?"highlight":"nothighlight"} ...>

Ou peut-être même générer l'ensemble <ul> Dans Jekyll.

Comment cela peut-il être fait avec un minimum de changements en dehors du <ul> Incriminé?

75
paperjam

Oui, vous pouvez le faire.
Pour ce faire, nous profiterons du fait que la page courante est toujours représentée par la variable liquide: page dans le modèle, et aussi que chaque article/page a un identifiant unique dans son page.url attribut.

Cela signifie que nous devons simplement utiliser une boucle pour créer notre page de navigation et, ce faisant, nous pouvons vérifier page.url contre chaque membre de la boucle. S'il trouve une correspondance, il sait mettre en évidence cet élément. Et c'est parti:

  {% for node in site.pages %}
    {% if page.url == node.url %}
      <li class="active"><a href="{{node.url}}" class="active">{{node.title}}</a></li>
    {% else %}
      <li><a href="{{node.url}}">{{node.title}}</a></li>
    {% endif %}
  {% endfor %}

Cela fonctionne comme prévu. Cependant, vous ne voulez probablement pas que toutes vos pages soient dans votre barre de navigation. Afin d'émuler le "regroupement" des pages, vous pouvez quelque chose comme ceci:

## Put the following code in a file in the _includes folder at: ./_includes/pages_list

{% for node in pages_list %}
  {% if group == null or group == node.group %}
    {% if page.url == node.url %}
      <li class="active"><a href="{{node.url}}" class="active">{{node.title}}</a></li>
    {% else %}
      <li><a href="{{node.url}}">{{node.title}}</a></li>
    {% endif %}
  {% endif %}
{% endfor %}
{% assign pages_list = nil %}
{% assign group = nil %}

Les pages peuvent désormais être "groupées". Pour donner à une page un groupe, vous devez le spécifier dans les pages YAML Front Matter:

---
title: blah
categories: blah
group: "navigation"
---    

Enfin, vous pouvez utiliser votre nouveau code! Partout où vous avez besoin de votre navigation pour aller dans votre modèle, il vous suffit d'appeler votre fichier include et de lui passer quelques pages et le groupe que vous souhaitez afficher:

<ul>
  {% assign pages_list = site.pages %}
  {% assign group = 'navigation' %}
  {% include pages_list %}
</ul>

Exemples

Cette fonctionnalité fait partie du cadre Jekyll-Bootstrap . Vous pouvez voir la documentation exacte du code décrit ici: http://jekyllbootstrap.com/api/bootstrap-api.html#jbpages_list

Enfin, vous pouvez le voir en action dans le site Web lui-même. Regardez simplement la navigation de droite et vous verrez que la page actuelle est surlignée en vert: Exemple de lien de navigation en surbrillance

111
superjadex12

Je pense que pour l'exigence de navigation la plus simple, les solutions répertoriées sont trop complexes. Voici une solution qui n'implique aucun sujet, javascript, boucles, etc.

Puisque nous avons accès à l'URL de la page, nous pouvons normaliser et diviser l'URL et tester par rapport aux segments, comme ceci:

{% assign current = page.url | downcase | split: '/' %}

<nav>
  <ul>
    <li><a href='/about' {% if current[1] == 'about' %}class='current'{% endif %}>about</a></li>
    <li><a href='/blog' {% if current[1] == 'blog' %}class='current'{% endif %}>blog</a></li>
    <li><a href='/contact' {% if current[1] == 'contact' %}class='current'{% endif %}>contact</a></li>
  </ul>
</nav>

Bien sûr, cela n'est utile que si les segments statiques permettent de délimiter la navigation. Quoi de plus compliqué, et vous devrez utiliser des informations préliminaires comme @RobertKenny l'a démontré.

45
Jonplussed

Semblable à la solution de @ Ben-Foster mais sans utiliser de jQuery

J'avais besoin de quelque chose de simple, c'est ce que j'ai fait.

Dans ma première page, j'ai ajouté une variable appelée active

par exemple.

---
layout: generic
title:  About
active: about
---

J'ai une navigation incluse avec la section suivante

    <ul class="nav navbar-nav">
        {% if page.active == "home" %}
            <li class="active"><a href="#">Home</a></li>
        {% else %}
            <li><a href="/">Home</a></li>
        {% endif %}
        {% if page.active == "blog" %}
            <li class="active"><a href="#">Blog</a></li>
        {% else %}
            <li><a href="../blog/">Blog</a></li>
        {% endif %}
        {% if page.active == "about" %}
            <li class="active"><a href="#">About</a></li>
        {% else %}
            <li><a href="../about">About</a></li>
        {% endif %}
    </ul>

Cela fonctionne pour moi car la quantité de liens dans la navigation est très étroite.

17
RobertKenny

Voici ma solution qui, je pense, est la meilleure façon de mettre en évidence la page actuelle:

Définissez une liste de navigation sur votre _ config.yml comme ceci:

navigation:
  - title: blog
    url: /blog/
  - title: about
    url: /about/
  - title: projects
    url: /projects/

Ensuite, dans votre fichier _ includes/header.html, vous devez parcourir la liste pour vérifier si la page actuelle ( page.url ) ressemble à n'importe quel élément de la liste de navigation, si c'est le cas, il vous suffit de définir la classe active et de l'ajouter à la <a> tag:

<nav>
  {% for item in site.navigation %}
      {% assign class = nil %}
      {% if page.url contains item.url %}
          {% assign class = 'active' %}
      {% endif %}
      <a href="{{ item.url }}" class="{{ class }}">
          {{ item.title }}
      </a>
  {% endfor %}
</nav>

Et parce que vous utilisez l'opérateur contient au lieu des égaux = , vous n'avez pas besoin d'écrire de code supplémentaire pour le faire fonctionner avec des URL telles que '/ blog/post-name /' ou 'projets/nom-projet /' . Cela fonctionne donc très bien.

P.S: N'oubliez pas de définir la variable permalien sur vos pages.

15
chomba

J'ai utilisé un peu de JavaScript pour y parvenir. J'ai la structure suivante dans le menu:

<ul id="navlist">
  <li><a id="index" href="index.html">Index</a></li>
  <li><a href="about.html">About</a></li>
  <li><a href="projects.html">Projects</a></li>
  <li><a href="videos.html">Videos</a></li>
</ul>

Cet extrait javascript met en évidence la page correspondante actuelle:

$(document).ready(function() {
    var pathname = window.location.pathname;

    $("#navlist a").each(function(index) {
        if (pathname.toUpperCase().indexOf($(this).text().toUpperCase()) != -1)
            $(this).addClass("current");
    });

    if ($("a.current").length == 0)
        $("a#index").addClass("current");
});
6
stian

Mon approche consiste à définir une variable personnalisée dans la première page YAML de la page et à la produire sur le <body> élément:

<body{% if page.id %} data-current-page="{{ page.id }}"{% endif %}> 

Mes liens de navigation incluent l'identifiant de la page vers laquelle ils pointent:

<nav>
    <ul>
        <li><a href="artists.html" data-page-id="artists">artists</a></li>
        <li><a href="#" data-page-id="contact">contact</a></li>
        <li><a href="#" data-page-id="about">about</a></li>
    </ul>
</nav>

Dans la première page, nous avons défini l'ID de la page:

---
layout: default
title: Our artists
id: artists
---

Et enfin un peu de jQuery pour définir le lien actif:

// highlight current page
var currentPage = $("body").data("current-page");
if (currentPage) {
    $("a[data-page-id='" + currentPage + "']").addClass("active");
}
4
Ben Foster

Beaucoup de réponses déroutantes ici. J'utilise simplement un if:

{% if page.name == 'limbo-anim.md' %}active{% endif %} 

Je me réfère directement à la page et je la mets dans la classe que je veux

<li><a class="pr-1 {% if page.name == 'limbo-anim.md' %}activo{% endif %} " href="limbo-anim.html">Animación</a></li>

Terminé. Rapide.

1
dawn

J'utilise page.path et en supprimant le nom de fichier.

<a href="/" class="{% if page.path == 'index.html' %}active{% endif %}">home</a>
1
Pat Migliaccio

Beaucoup de bonnes réponses sont déjà là.

Essaye ça.

Je modifie légèrement les réponses ci-dessus.

_data/navigation.yaml

- name: Home
  url: /
  active: home
- name: Portfolio
  url: /portfolio/
  active: portfolio
- name: Blog
  url: /blog/
  active: blog

Dans une page -> portfolio.html (Identique pour toutes les pages avec un nom de page actif relatif)

---
layout: default
title: Portfolio
permalink: /portfolio/
active: portfolio
---

<div>
  <h2>Portfolio</h2>
</div>

Navigation html part

<ul class="main-menu">
  {% for item in site.data.navigation %}
    <li class="main-menu-item">
      {% if {{page.active}} == {{item.active}} %}
        <a class="main-menu-link active" href="{{ item.url }}">{{ item.name }}</a>
      {% else %}
        <a class="main-menu-link" href="{{ item.url }}">{{ item.name }}</a>
      {% endif %}
    </li>
  {% endfor %}
</ul>
0
Surender Lohia

La navigation de votre site Web doit être une liste non ordonnée. Pour que les éléments de la liste s'éclairent lorsqu'ils sont actifs, le script liquide suivant leur ajoute une classe "active". Cette classe doit être stylisée avec CSS. Pour détecter quel lien est actif, le script utilise ‘contient’, comme vous pouvez le voir dans le code ci-dessous.

<ul>
  <li {% if page.url contains '/getting-started' %}class="active"{% endif %}>
    <a href="/getting-started/">Getting started</a>
  </li>
  ...
  ...
  ...
</ul>

Ce code est compatible avec tous les styles de permalien dans Jekyll. L'instruction "contient" met en évidence avec succès le premier élément de menu aux URL suivantes:

  • commencer/
  • getting-Started.html
  • mise en route/index.html
  • mise en route/sous-page /
  • mise en route/subpage.html

Source: http://jekyllcodex.org/without-plugin/simple-menu/

0
JoostS