Jekyll - Aktuelle Registerkarte in der Menüleiste automatisch markieren


81

Ich verwende Github, um eine statische Site zu hosten, und Jekyll, um sie zu generieren.

Ich habe eine Menüleiste (as <ul>) und möchte, dass der <li>entsprechenden aktuellen Seite eine andere Klasse für die CSS-Hervorhebung zugewiesen wird.

Also so etwas wie Pseudocode:

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

Oder vielleicht sogar das Ganze <ul>in Jekyll erzeugen .

Wie kann dies mit minimalen Änderungen außerhalb der Straftat geschehen <ul>?


Antworten:


115

Ja, das kannst du machen.
Um dies zu erreichen, werden wir die Tatsache ausnutzen, dass die aktuelle Seite immer durch die flüssige Variable dargestellt wird: pagein der Vorlage, und dass jeder Beitrag / jede Seite eine eindeutige Kennung in ihrem page.urlAttribut hat.

Dies bedeutet, dass wir nur eine Schleife verwenden müssen, um unsere Navigationsseite zu erstellen, und auf diese Weise page.urlgegen jedes Mitglied der Schleife prüfen können . Wenn eine Übereinstimmung gefunden wird, kann dieses Element hervorgehoben werden. Auf geht's:

  {% 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 %}

Dies funktioniert wie erwartet. Allerdings möchten Sie wahrscheinlich nicht alle Ihre Seiten in Ihrer Navigationsleiste haben. Um die "Gruppierung" der Seite zu emulieren, können Sie Folgendes tun:

## 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 %}

Jetzt können Seiten "gruppiert" werden. Um einer Seite eine Gruppe zuzuweisen, müssen Sie diese auf den Seiten YAML Front Matter angeben:

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

Endlich können Sie Ihren neuen Code verwenden! Wo immer Sie Ihre Navigation für Ihre Vorlage benötigen, "rufen" Sie einfach Ihre Include-Datei auf und übergeben Sie ihr einige Seiten und die Gruppe, die Sie anzeigen möchten:

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

Beispiele

Diese Funktionalität ist Teil des Jekyll-Bootstrap- Frameworks. Die genaue Dokumentation zu dem hier beschriebenen Code finden Sie unter: http://jekyllbootstrap.com/api/bootstrap-api.html#jbpages_list

Endlich können Sie es auf der Website selbst in Aktion sehen. Schauen Sie sich einfach die rechte Navigation an und Sie werden sehen, dass die aktuelle Seite grün hervorgehoben ist: Beispiel hervorgehobener Navigationslink


1
Tolle Frage, tolle Antwort, danke. Es war einfach, dies auch für eine manuell ausgewählte Liste von Registerkarten zu ändern. Es dauerte einen Moment, bis klar wurde, dass page.url das '/' enthält, z. "/index.html", nicht "index.html"
cboettig

Dieser Ansatz führt für mich zu einem Jekyll-Fehler. jekyll 2.4.0 | Error: The included file '/Users/joelglovier/project/jekyllsite/_includes/pages_list' should exist and should not be a symlink
Joel Glovier

Viel zu komplex für etwas, das in Jekyll eingebaut werden sollte.
Cameron

@ Camerononjroe versuchen, die .htmlErweiterung zu pages_list hinzuzufügen und diese stattdessen
einzuschließen

48

Ich denke, für die einfachste Navigationsanforderung sind die aufgeführten Lösungen zu komplex. Hier ist eine Lösung, die keine Frontmaterie, Javascript, Schleifen usw. beinhaltet.

Da wir Zugriff auf die Seiten-URL haben, können wir die URL normalisieren und aufteilen und anhand der Segmente testen, wie folgt:

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

Dies ist natürlich nur dann sinnvoll, wenn statische Segmente die Möglichkeit bieten, die Navigation abzugrenzen. Alles ist komplizierter, und Sie müssen Front-Materie verwenden, wie @RobertKenny demonstriert hat.


Das habe ich gesucht, aber sollte es nicht sein classs="active"?
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

@CiroSantilli your 事件 法轮功 Wenn Ihr CSS den Stil hat .active, dann ja. In der obigen Antwort sagt der Autor, dass die Klasse, die in seinem Stylesheet aufgerufen werden soll, lautet .current. Keine große Sache.
Brian Zelip

3
@BrianZ es ist offiziell: zu viel Bootstrap schmilzt dein Gehirn :)
Ciro Santilli 法轮功 冠状 病 六四 事件 法轮功

Für die Homepage musste ich {% setzen, wenn aktuell [1] == null%}
GorvGoyl

17

Ähnlich der Lösung von @ ben-Foster, jedoch ohne Verwendung von jQuery

Ich brauchte etwas Einfaches, das habe ich getan.

In meiner vorderen Angelegenheit habe ich eine Variable namens hinzugefügt active

z.B

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

Ich habe ein Navigations-Include mit folgendem Abschnitt

    <ul class="nav navbar-nav">
        {% if page.active == "home" %}
            <li class="active"><a href="#">Home</a></li>
        {% else %}
            <li><a href="https://stackoverflow.com/">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>

Dies funktioniert bei mir, da die Anzahl der Links in der Navigation sehr gering ist.


Danke @SurenderLohia Ich mag es, die Dinge so einfach wie möglich zu halten.
RobertKenny

16

Hier ist meine Lösung, die meiner Meinung nach der beste Weg ist, um die aktuelle Seite hervorzuheben:

Definieren Sie eine Navigationsliste in Ihrer _config.yml wie folgt :

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

Dann müssen Sie in Ihrer Datei _includes / header.html die Liste durchlaufen, um zu überprüfen, ob die aktuelle Seite ( page.url ) einem Element der Navigationsliste ähnelt. Wenn ja, legen Sie einfach die aktive Klasse fest und fügen sie dem <a>Tag hinzu:

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

Und da Sie den Operator " enthält" anstelle des Operators "equals =" verwenden , müssen Sie keinen zusätzlichen Code schreiben, damit er mit URLs wie "/ blog / post-name /" oder "projects / project-name /" funktioniert. ' . Es funktioniert also sehr gut.

PS: Vergessen Sie nicht, die Permalink- Variable auf Ihren Seiten festzulegen .


Dies ist meine Lieblingslösung, da ich die Reihenfolge der Seiten auswählen kann.

Ich mag diese Lösung, aber sie funktioniert nicht, wenn Sie einen Navigationslink mit URL haben, /da alle Seiten-URLs den führenden Schrägstrich enthalten. Die folgenden Arbeiten: {% for link in site.navigation %} {% assign class = nil %} {% if page.url == link.url %} {% assign class = 'active' %} {% elsif page.url != '/' and page.url contains link.url %} {% assign class = 'active parent' %} {% endif %} <a href="{{link.url}}" class="{{class}}">{{link.title}}</a> {% endfor %}
James Wilson

6

Ich habe ein bisschen JavaScript verwendet, um dies zu erreichen. Ich habe folgende Struktur im Menü:

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

Dieses Javascript-Snippet hebt die aktuell entsprechende Seite hervor:

$(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");
});

Ich persönlich denke, das ist sauberer als die obige Methode. Die obige Methode wird hässlich, wenn Sie die Seiten in Ihrem Navigationsgerät bestellen möchten oder wenn "Index" standardmäßig hervorgehoben werden soll.
Verhogen

Dies ist einfach und leicht zu beginnen, indem Sie dem aktuellen Seitenelement eine Klasse hinzufügen. Die "akzeptierte" Antwort dauerte ungefähr eine Stunde, um herauszufinden, wie und warum. Vielen Dank für das Teilen
Ashwin

4

Mein Ansatz besteht darin, eine benutzerdefinierte Variable in der YAML-Titelseite der Seite zu definieren und diese für das <body>Element auszugeben :

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

Meine Navigationslinks enthalten die Kennung der Seite, auf die sie verlinken:

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

In der Titelseite setzen wir die Seiten-ID:

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

Und zum Schluss noch ein bisschen jQuery, um den aktiven Link zu setzen:

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

Ich dachte, dass diese Methode sehr einfach zu befolgen ist und eine einfache Sortierung von Menüelementen ermöglicht. Ich bin sehr neu in Jekyll, daher haben mich die anderen Methoden ein wenig eingeschüchtert, aber ich bin sehr zufrieden mit jQuery. Vielleicht nicht 100% perfekt für Puristen, aber es funktioniert und funktioniert gut.
TheBrockEllis

Wenn Sie eine Lösung nur für Flüssigkeiten wünschen, können Sie dies versuchen: stackoverflow.com/a/46984009/2397550
JoostS

2

Die Navigation Ihrer Website sollte eine ungeordnete Liste sein. Das folgende flüssige Skript fügt ihnen eine 'aktive' Klasse hinzu, damit die Listenelemente aufgehellt werden, wenn sie aktiv sind. Diese Klasse sollte mit CSS gestaltet sein. Um festzustellen, welcher Link aktiv ist, verwendet das Skript "enthält", wie Sie im folgenden Code sehen können.

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

Dieser Code ist mit allen Permalink-Stilen in Jekyll kompatibel. Die Anweisung 'enthält' hebt den ersten Menüpunkt unter den folgenden URLs erfolgreich hervor:

  • beginnen/
  • Erste Schritte.html
  • Erste Schritte / index.html
  • Erste Schritte / Unterseite /
  • Erste Schritte / subpage.html

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


2

Viele verwirrende Antworten hier. Ich benutze einfach ein if:

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

Ich verweise direkt auf die Seite und füge sie in die Klasse ein, die ich möchte

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

Erledigt. Schnell.


Könnten Sie näher erläutern, wo Sie jedes dieser Elemente platziert haben? header.html oder?
Georges

1

Ich habe page.pathden Dateinamen verwendet und bin davon ausgegangen.

<a href="https://stackoverflow.com/" class="{% if page.path == 'index.html' %}active{% endif %}">home</a>

0

Viele gute Antworten sind bereits da.

Versuche dies.

Ich ändere die obigen Antworten leicht.

_data/navigation.yaml

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

Auf einer Seite -> portfolio.html(Gleich für alle Seiten mit einem relativ aktiven Seitennamen)

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

Wenn Sie das Minima-Thema für Jekyll verwenden, müssen Sie dem Klassenattribut in header.html nur einen Ternär hinzufügen:

 <a {% if my_page.url == page.url %} class="active"{% endif %} href="{{ my_page.url | relative_url }}">

der vollständige Auszug:

        <div class="trigger">
        {%- for path in page_paths -%}
          {%- assign my_page = site.pages | where: "path", path | first -%}
          {%- if my_page.title -%}
          <a {% if my_page.url == page.url %} class="active"{% endif %} href="{{ my_page.url | relative_url }}">{{ my_page.title | escape }}</a>
          {%- endif -%}
        {%- endfor -%}
      </div>

Fügen Sie dies Ihrer _config.yml hinzu

header_pages:
  - classes.markdown
  - activities.markdown
  - teachers.markdown

Und dann natürlich dein CSS:

   a.active {
                color: #e6402a;
            }

-2

Hier ist eine jQuery-Methode, um dasselbe zu tun

  var pathname = window.location.pathname;

  $(".menu.right a").each(function(index) {
    if (pathname === $(this).attr('href') ) {
      $(this).addClass("active");
    }
  });
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.