web-dev-qa-db-fra.com

Jekyll sélectionne l'URL de la page courante et change sa classe

J'ai utilisé Jekyll pour un site statique (pour que ce soit facile à entretenir) et j'ai été bloqué avec la fonctionnalité suivante:

Voici ma barre de liens:

<ul id="links">
    <li class="first"><a class="active" href="/">Home</a></li>
    <li><a href="./associate.html">Associate With Us</a></li>
    <li><a href="./media.html">Media</a></li>
    <li><a href="./clients.html">Clients</a></li>
    <li class="last"><a  href="./contact.html">Contact Us</a></li>
</ul>       

La classe active gère la coloration. Ce que je veux, c'est que cette classe soit appliquée par jekyll en fonction d'un ensemble de variables utilisant liquid/YAML.

Existe-t-il un moyen simple de procéder?

Étant donné que la barre est commune à toutes les pages, elle est désormais dans la disposition par défaut. Je pourrais faire le tour en utilisant Javascript pour détecter l'url et faire la mise en évidence mais je me demandais s'il y avait un moyen de le faire dans Jekyll.

51
Nemo

Je le fais dans deux pages que j'ai installées dans Jekyll.

La première chose que je fais est de créer une entrée dans _config.yml avec les informations de toutes les pages:

# this goes inside _config.yml. Change as required
navigation:
- text: What we do
  url: /en/what-we-do/
- text: Who we are
  url: /en/who-we-are/
- text: Projects
  url: /en/projects/
  layout: project
- text: Blog
  url: /en/blog/
  layout: post

Ensuite, sur ma mise en page principale, j'utilise ces informations pour générer les liens de navigation. Sur chaque lien, je compare l'url du lien avec l'url de la page courante. S'ils sont égaux, la page est active. Sinon, ils ne le sont pas.

Il y a quelques cas particuliers: tous les articles de blog doivent mettre en évidence le lien "blog", et les premières pages (anglais et espagnol) ne doivent pas présenter la barre de navigation. Dans les deux cas, je m'appuie sur le fait que les articles de blog et les premières pages ont des mises en page spécifiques (notez que les liens "Blog" et "Projet" sur le yaml ont un paramètre supplémentaire appelé "mise en page")

Le code de navigation est généré comme ceci:

{% unless page.layout == 'front' %}
  <ul class="navigation">
    {% for link in site.navigation %}
      {% assign current = nil %}
      {% if page.url == link.url or page.layout == link.layout %}
        {% assign current = 'current' %}
      {% endif %}

      <li class="{% if forloop.first %}first{% endif %} {{ current }} {% if forloop.last %}last{% endif %}">
        <a class="{{ current }}" href="{{ link.url }}">{{ link.text }}</a>
      </li>
    {% endfor %}
  </ul>
{% endunless %}

Je dois encore me rappeler d'avoir ajouté une entrée à _config.yaml chaque fois que j'ajoute une nouvelle page, puis redémarre Jekyll, mais cela se produit très rarement maintenant.

I pensez la navigation yaml pourrait aller à l'intérieur d'un _include appelé "navigation" ou quelque chose de similaire, mais je n'ai pas essayé d'utiliser yaml à l'intérieur de ceux-ci, donc je ne sais pas si cela fonctionnera. Dans mon cas, puisque j'ai un site multilingue, il est plus facile d'avoir tout à l'intérieur de la configuration (les traductions manquantes sont plus faciles à repérer)

J'espère que ça aide.

53
kikito

Comme une extension supplémentaire sur le travail de l'autre, voici un moyen de le faire fonctionner sans détrempe index.html montrant sur toutes vos belles URL:

---
navigation:
 - text: Home
   url: /
 - text: Blah
   url: /blah/
---
{% assign url = page.url|remove:'index.html' %}
{% for link in page.navigation %}
<li {% if url == link.url %}class="active"{% endif %}>
    <a href="{{link.url}}" title="{{link.title}}">{{link.text}}</a>
</li>
{% endfor %}

L'or se trouve dans l'instruction assign qui obtient l'URL de la page (qui inclut naturellement l'index.html, puis la supprime pour correspondre aux jolies URL page.navigation.

50
Oli

Cela peut être une nouvelle fonctionnalité depuis que la question est apparue pour la première fois, mais j'ai découvert que cela peut être fait dans un seul fichier:

  1. définir la navigation comme une variable dans l'en-tête yaml
  2. boucle sur la variable à l'aide de liquide

Donc dans mon _layouts/base.html J'ai:

---
navigation:
- text: Home
  url: /index.html
- text: Travel
  title: Letters home from abroad
  url: /travel.html
---

<ul>
    {% for link in page.navigation %}
    <li {% if page.url == link.url %}class="current"{% endif %}>
       <a href="{{link.url}}" title="{{link.title}}">{{link.text}}</a></li>
    {% endfor %}
</ul>

Ce qui génère cela sur la page Home:

<ul>
    <li class="current"><a href="/index.html" title="">Home</a></li>
    <li><a href="/travel.html" title="Letters home from abroad">Travel</a></li>
</ul>

Et ceci sur la page Travel:

<ul>
    <li><a href="/index.html" title="">Home</a></li>
    <li class="current"><a href="/travel.html" title="Letters home from abroad">Travel</a></li>
</ul>
18
John Mee

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.

12
RobertKenny

Même navigation sur toutes les pages

Après avoir lu toutes ces réponses, j'ai trouvé une solution nouvelle et plus facile à maintenir:

  1. Ajouter {% include nav.html %} à ton _layouts/layout.html fichier
  2. Ajouter un nav.html fichier dans votre _includes dossier
  3. Ajoutez le contenu suivant à votre nav.html fichier. Il déterminera si votre lien se trouve sur la page en cours et ajoutera une classe de active ainsi que supprimera index.html à partir de votre lien. Il fonctionnera également avec un sous-dossier comme /repo-name, qui est nécessaire pour GitHub gh-pages Branche Pages.

    <nav>
        <ul class="nav">
            {% assign url = page.url|remove:'index.html' %}
            {% for link in site.navigation %}
                {% assign state = '' %}
                {% if page.url == link.url %}
                    {% assign state = 'active ' %}
                {% endif %}
                <li class="{{ state }}nav-item">
                    <a href="{% if page.url == link.url %}{{ site.baseurl }}{% else %}{{ site.baseurl }}{{ link.url }}{% endif %}" title="{{ link.title }}">{{ link.text }}</a>
                </li>
            {% endfor %}
        </ul>
    </nav>
    
  4. Ajoutez ensuite le tableau de liens de navigation à votre _config.yml fichier comme suit. Attention à la bonne indentation, car YAML est assez pointilleux à ce sujet (Jekyll aussi).

    navigation:
          - text: Home
            title: Back to home page
            url: /index.html
          - text: Intro
            title: An introduction to the project
            url: /intro.html 
          - text: etc.
            title: ...
            url: /foo.html 
    

Navigation uniquement à la maison - "retour" pour les autres

En supposant que le lien vers votre page "Accueil" (index.html) est la première partie du tableau à l'intérieur du _config.htmls navigation array, vous pouvez utiliser l'extrait de code suivant pour afficher la navigation vers les différentes pages de la page principale/d'accueil et un lien vers la page d'accueil sur toutes les autres pages:

<nav>
    <ul class="grid">
        {% assign url = page.url | remove:'/index.html' %}
        {% assign home = site.navigation.first %}
        {% if url == empty %}
            {% for link in site.navigation %}
                {% assign state = '' %}
                {% if page.url == link.url %}
                    {% assign state = 'active ' %}
                {% endif %}
                {% if home.url != link.url %}
                    <li class="{{ state }}nav-item">
                        <a href="{% if page.url == link.url %}{{ site.baseurl }}{% else %}{{ site.baseurl }}{{ link.url }}{% endif %}" title="{{ link.title }}">{{ link.text }}</a>
                    </li>
                {% endif %}
            {% endfor %}
        {% else %}
            <li class="nav-item active">
                <a href="{{ home.url }}" title="{{ home.title }}">{{ home.text }}</a>
            </li>
        {% endif %}
    </ul>
</nav>
4
kaiser

La logique de mise en évidence de la navigation est la dernière chose que je ferais côté serveur. Je préfère m'en tenir à une approche agréable, propre et discrète utilisant JS/jQuery (si cette option fonctionne pour vous).

  1. Les éléments qui doivent être mis en évidence entrent dans une disposition commune comme celle-ci:

    <nav>
      <a id="section1" href="#">Section 1</a>
      <a id="section2" href="#">Section 2</a>
      <a id="section3" href="#">Section 3</a>
    </nav>
    
  2. Dans votre page (ou même dans des mises en page imbriquées), vous placez un élément avec data-ref="#section1" (En fait, tout sélecteur jQuery fonctionnera).

  3. Maintenant, incluez l'extrait JS suivant (affiché comme jQuery, mais n'importe quel framework fera l'affaire) dans <head>:

    $(function() {
      $("[data-ref]").each(function() {
        $($(this).attr("data-ref")).addClass("current");
      });
    });
    

Cette approche est agréable, car elle ne fait aucune hypothèse sur l'architecture, les cadres, les langages et les moteurs de modèle sous-jacents.

Mise à jour: Comme certaines personnes l'ont souligné vous voudrez peut-être omettre la partie $(function() { ... }) qui lie le script à l'événement DOM ready - et poussez simplement le script vers le bas de votre <body>.

3
incarnate

Avec Jekyll 3.4.3, cela fonctionne:

<ul>
    {% for my_page in site.pages %} 
        {% if my_page.title %}
            <li {% if my_page.url == page.url %} class="active" {% endif %}>
                <a href="{{ my_page.url | relative_url }}">{{ my_page.title | escape }}
                </a>
            </li>
        {% endif %} {% endfor %}
</ul>
2
Jack Morris

Cela fonctionne pour moi (désolé pour le code non anglais):

<nav>
  <a href="/kursevi" {% if page.url == '/kursevi/' %} class="active"{% endif %}>Kursevi</a>
  <a href="/radovi" {% if page.url == '/radovi/' %} class="active"{% endif %}>Radovi</a>
  <a href="/blog" {% if page.url == '/blog/' %} class="active"{% endif %}>Blog</a>
  <a href="/kontakt" {% if page.url == '/kontakt/' %} class="active"{% endif %}>Kontakt</a>
</nav>
2
Damjan Pavlica

J'ai adopté une approche CSS simple. Tout d'abord, ajoutez un identifiant au début ...

---
layout: page
title: Join us
permalink: /join-us/
nav-class: join <-----
---

Ajoutez ceci en tant que classe dans <body>et votre nav ...

<body class="{{ page.nav-class }}">

et

<li class="{{ page.nav-class }}">...</a></li>

Liez-les ensuite pour toutes les pages en CSS, par exemple:

.about .about a,
.join .join a,
.contact .contact a {
color: #fff;
}

Le principal inconvénient étant que vous devez coder en dur les règles de style.

1
Reg T

Ajoutant à la solution d'incarné, la ligne de code la plus simple possible avec jQuery est la suivante:

    $( "a[href='{{ page.url | remove: "index.html" }}']" ).addClass("current");

Fonctionne parfaitement pour moi.

1
bitconquer