Jekyll Seleccione URL de la página actual y cambie su clase
Pregunta
He estado usando Jekyll para un sitio estático (para que sea fácil de mantener), y me he quedado atrapado en la siguiente función:
Esta es mi barra de enlace:
<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>
los active
La clase maneja la coloración. Lo que quiero es que esta clase sea aplicada por Jekyll dependiendo de alguna variable establecida con Liquid/Yaml.
¿Hay alguna manera fácil de hacerlo?
Dado que la barra es común a todas las páginas, ahora está en el diseño predeterminado. Podría dar la vuelta usando JavaScript para detectar la URL, y hacer lo destacado, pero me preguntaba si había alguna forma de hacerlo en Jekyll.
Solución
Hago esto en dos páginas que he configurado en Jekyll.
Lo primero que hago es crear una entrada dentro _config.yml con la información de todas las páginas:
# 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
Luego, en mi diseño principal, uso esa información para generar los enlaces de navegación. En cada enlace, comparo la URL del enlace con la URL de la página actual. Si son iguales, la página está activa. De lo contrario, no lo son.
Hay un par de casos especiales: todas las publicaciones de blog deben resaltar el enlace "Blog", y las páginas delanteras (inglés y español) no deben presentar la barra de Nav. Para ambos casos, confío en el hecho de que las publicaciones de blog y las páginas delanteras tienen diseños específicos (observe que los enlaces "Blog" y "Proyecto" en el YAML tienen un parámetro adicional llamado "diseño")
El código de navegación se genera así:
{% 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 %}
Todavía tengo que recordar haber agregado una entrada a _config.yaml cada vez que agrego una nueva página, y luego reiniciar Jekyll, pero ahora sucede con poca frecuencia.
yo pensar La navegación YAML podría entrar en un _Include llamado "navegación" o algo similar, pero no he intentado usar YAML dentro de ellos, así que no sé si funcionará. En mi caso, dado que tengo un sitio multilingüe, es más fácil tener todo dentro de la configuración (las traducciones que faltan son más fáciles de detectar)
Espero que esto ayude.
Otros consejos
Como una extensión adicional en el trabajo del otro, aquí hay una forma de hacerlo funcionar sin empapado index.html
Mostrando todas tus hermosas 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 %}
El oro está en el assign
Declaración que obtiene la URL de la página (que naturalmente incluye el index.html y luego la elimina para que coincida con la página.
Esta puede ser una característica nueva desde que apareció la pregunta por primera vez, pero descubrí que todo esto se puede hacer en un archivo:
- Defina la navegación como una variable en el encabezado YAML
- Entren sobre la variable usando líquido
Entonces en mi _layouts/base.html
Tengo:
---
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>
Que genera esto en el Home
página:
<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>
Y esto en el Travel
página:
<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>
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.
Misma navegación en todas las páginas
Después de leer todas esas respuestas, se me ocurrió una solución nueva y más fácil de mantener:
- Agregar
{% include nav.html %}
para usted_layouts/layout.html
expediente - Agrega un
nav.html
Archivo a su_includes
carpeta Agregue el siguiente contenido a su
nav.html
expediente. Determinará si su enlace está en la página actual y agregará una clase deactive
así como eliminarindex.html
Desde su enlace. También funcionará con una subcarpeta como/repo-name
, que se necesita para Githubgh-pages
Rama de páginas.<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>
Luego agregue la matriz de enlace de navegación a su
_config.yml
Archivo según lo siguiente. Tenga en cuenta la sangría adecuada, ya que Yaml es bastante exigente en eso (Jekyll también).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
Navegación solo en casa - "Volver" para otros
Suponiendo que el enlace a su "hogar" (index.html
) es la primera parte de la matriz dentro del _config.html
s navigation
Array, puede usar el siguiente fragmento para mostrar la navegación a las diferentes páginas en la página principal/de inicio y un enlace de regreso a la página de inicio en todas las demás páginas:
<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>
La lógica de resaltado de navegación es lo último que haría en el lado del servidor. Prefiero seguir con un enfoque agradable, limpio y discreto usando JS/JQuery (si esta opción funciona para usted).
Los elementos que deben resaltarse van dentro de un diseño común como este:
<nav> <a id="section1" href="#">Section 1</a> <a id="section2" href="#">Section 2</a> <a id="section3" href="#">Section 3</a> </nav>
En su página (o incluso en diseños anidados) coloca un elemento con
data-ref="#section1"
(De hecho, cualquier selector de jQuery funcionará).Ahora, incluya el siguiente fragmento JS (que se muestra como jQuery, pero cualquier marco funcionará) en
<head>
:$(function() { $("[data-ref]").each(function() { $($(this).attr("data-ref")).addClass("current"); }); });
Este enfoque es bueno, porque no hace suposiciones sobre la arquitectura subyacente, los marcos, los idiomas y los motores de plantilla.
Actualizar: Como Algunas personas señalaron Es posible que desee omitir el $(function() { ... })
parte que une el script al evento listo para DOM, y simplemente presione el script hacia la parte inferior de su <body>
.
Con Jekyll 3.4.3, esto funciona:
<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>
Esto funciona para mí (perdón por el código no inglés):
<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>
Además de la solución de Encarnate, la línea de código más simple posible con jQuery es esta:
$( "a[href='{{ page.url | remove: "index.html" }}']" ).addClass("current");
Funciona perfectamente para mí.
Tomé un enfoque simple de CSS. Primero, agregue un identificador en la materia frontal ...
---
layout: page
title: Join us
permalink: /join-us/
nav-class: join <-----
---
Agregue esto como una clase en <body>
y Tu navegación ...
<body class="{{ page.nav-class }}">
y
<li class="{{ page.nav-class }}">...</a></li>
Luego vincule estos para todas las páginas en CSS, por ejemplo:
.about .about a,
.join .join a,
.contact .contact a {
color: #fff;
}
El principal inconveniente es que necesitas codificar las reglas de estilo.