Jekyll: resalte automáticamente la pestaña actual en la barra de menú

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

  •  26-10-2019
  •  | 
  •  

Pregunta

Estoy usando GitHub para alojar un sitio estático y Jekyll para generarlo.

Tengo una barra de menú (como <ul>) y me gustaría el <li> correspondiente a la página actual se le asignará una clase diferente para el resaltado CSS.

Entonces, algo como pseudo código:

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

O tal vez incluso generar todo <ul> En Jekyll.

¿Cómo se puede hacer esto con cambios mínimos fuera de la ofensa? <ul>?

¿Fue útil?

Solución

Sí, usted puede hacer esto.
Para lograr esto, aprovecharemos el hecho de que la página actual siempre está representada por la variable líquida: page en la plantilla, y también que cada publicación/página tiene un identificador único en su page.url atributo.

Esto significa que solo tenemos que usar un bucle para construir nuestra página de navegación, y al hacerlo podemos verificar page.url contra cada miembro del bucle. Si encuentra una coincidencia, sabe resaltar ese elemento. Aquí vamos:

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

Esto funciona como se esperaba. Sin embargo, probablemente no desee todas sus páginas en su barra de navegación. Para emular la "agrupación" de la página, puede algo como esto:

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

Ahora las páginas se pueden "agrupar". Para darle a una página un grupo, necesita especificarlo en las páginas Yaml Front Matter:

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

¡Finalmente puedes usar tu nuevo código! Donde sea que necesite su navegación para ir a su plantilla, simplemente "llame" su archivo de inclusión y pase algunas páginas y el grupo que desea mostrar:

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

Ejemplos

Esta funcionalidad es parte de la Jekyll-bootstrap estructura. Puede ver la documentación exacta para el código descrito aquí: http://jekyllbootstrap.com/api/bootstrap-api.html#jbpages_list

Finalmente, puede verlo en acción dentro del sitio web en sí. Solo mire la navegación directa y verá que la página actual está resaltada en verde: Ejemplo de enlace de navegación resaltado

Otros consejos

Siento que para el requisito de navegación más simple, las soluciones enumeradas son demasiado complejas. Aquí hay una solución que no implica ninguna materia frontal, JavaScript, bucles, etc.

Como tenemos acceso a la URL de la página, podemos normalizar y dividir la URL y probar contra los segmentos, así:

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

Por supuesto, esto solo es útil si los segmentos estáticos proporcionan los medios para delinear la navegación. Cualquier cosa más complicada, y tendrá que usar materia frontal como @Robertkenny demostrada.

Similar a la solución de @ben-foster pero sin usar jQuery

Necesitaba algo simple, esto es lo que hice.

En mi materia frontal agregué una variable llamada active

p.ej

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

Tengo una navegación que incluya con la siguiente sección

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

Esto funciona para mí, ya que la cantidad de enlaces en la navegación es muy limitada.

Aquí está mi solución que creo que es la mejor manera de resaltar la página actual:

Definir un lista de navegación en tu _config.yml como esto:

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

Entonces en tu _Includes/Header.html Archivo debe recorrer la lista para verificar si la página actual (URL de la página) se asemeja a cualquier elemento de la lista de navegación, si es así, simplemente establece la clase activa y lo agregue a la <a> etiqueta:

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

Y porque estás usando el contiene operador en lugar de los iguales = operador, no tiene que escribir código adicional para que funcione con URL como '/Blog/Post-Name/' o 'Projects/Project-Name/'. Entonces funciona muy bien.

PD: No olvides establecer el enlace permanente variable en tus páginas.

Usé un poco de JavaScript para lograr esto. Tengo la siguiente estructura en el 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>

Este fragmento de JavaScript destaca la página actual correspondiente:

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

Mi enfoque es definir una variable personalizada en la materia frontal Yaml de la página y obtener esto en el <body> elemento:

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

Mis enlaces de navegación incluyen el identificador de la página a la que vinculan:

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

En la materia frontal de la página establecemos la identificación de la página:

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

Y finalmente un poco de jQuery para establecer el enlace activo:

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

Muchas respuestas confusas aquí. Simplemente uso un if:

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

Me refiero directamente a la página y poniéndola dentro de la clase que quiero

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

Hecho. Rápido.

He estado usando page.path y saliendo del nombre de archivo.

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

Muchas buenas respuestas ya están ahí.

Prueba esto.

Altero ligeramente las respuestas anteriores.

_data/navigation.yaml

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

En una página -> portfolio.html (Lo mismo para todas las páginas con un nombre relativo de página activa)

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

La navegación de su sitio web debe ser una lista desordenada. Para que los elementos de la lista se aligeren cuando estén activos, el siguiente script líquido les agrega una clase 'activa'. Esta clase debe estar diseñada con CSS. Para detectar qué enlace está activo, el script usa 'contiene', como puede ver en el código a continuación.

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

Este código es compatible con todos los estilos de enlace permanente en Jekyll. La declaración 'contiene' resalta con éxito el primer elemento de menú en las siguientes URL:

  • empezando/
  • siendo iniciado.html
  • siendo iniciado/index.html
  • siendo iniciado/subpage/
  • siendo iniciado/subpage.html

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

Aquí hay un método jQuery para hacer lo mismo

  var pathname = window.location.pathname;

  $(".menu.right a").each(function(index) {
    if (pathname === $(this).attr('href') ) {
      $(this).addClass("active");
    }
  });
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top