Jekyll выбрать текущий URL страницы и изменить ее класс
Я использую Jekyll для статического сайта (так что его легко поддерживать), и он застрял в следующей функции:
Это моя панель ссылок:
<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>
Класс active
обрабатывает раскраску. Я хочу, чтобы этот класс применялся jekyll в зависимости от некоторого набора переменных с использованием жидкости /YAML.
Есть ли простой способ сделать это?
Поскольку панель является общей для всех страниц, она теперь находится в макете по умолчанию. Я мог бы обойтись, используя Javascript, чтобы обнаружить URL-адрес и сделать выделение, но задавался вопросом, есть ли способ сделать это в Jekyll.
Ответы
Ответ 1
Я делаю это на двух страницах, которые я создал в Джекиле.
Первое, что я делаю, это создать запись внутри _config.yml с информацией обо всех страницах:
# 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
Затем, на моем основном макете, я использую эту информацию для создания навигационных ссылок. По каждой ссылке я сравниваю URL-адрес ссылки с URL-адресом текущей страницы. Если они равны, страница активна. В противном случае это не так.
Есть пара особых случаев: все сообщения в блоге должны указывать на ссылку "блог", а на первых страницах (на английском и испанском языках) не должна отображаться панель навигации. В обоих случаях я полагаюсь на то, что в сообщениях блога и на передних страницах есть определенные макеты (обратите внимание, что ссылки "Блог" и "Проект" на ямле имеют дополнительный параметр, называемый "макет" )
Код навигации создается следующим образом:
{% 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 %}
Мне все равно нужно помнить о добавлении записи в _config.yaml каждый раз, когда я добавляю новую страницу, а затем перезапускаю Jekyll, но это происходит очень редко.
Я думаю, что навигационный ямл мог войти в _include, называемый "навигация" или что-то подобное, но я не пробовал использовать yaml внутри них, поэтому я не знаю, будет ли это работать. В моем случае, поскольку у меня есть многоязычный сайт, проще иметь все внутри конфигурации (отсутствующие переводы легче обнаружить)
Надеюсь, это поможет.
Ответ 2
В качестве дальнейшего расширения работы другого, вот способ заставить его работать без soggy index.html
, отображающего все ваши красивые 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 %}
Золото находится в выражении assign
, который получает URL-адрес страницы (который, естественно, включает index.html, а затем удаляет его, чтобы соответствовать URL-адресам страницы. navigation.
Ответ 3
Это может быть новая функция, поскольку вопрос появился впервые, но я обнаружил, что все это можно сделать в одном файле:
- определяет навигацию как переменную в заголовке yaml
- цикл по переменной с использованием жидкости
Итак, в моем _layouts/base.html
у меня есть:
---
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>
Что генерирует это на странице 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>
И это на странице 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>
Ответ 4
Мне нужно было что-то простое, вот что я сделал.
В моем первом вопросе я добавил переменную с именем active
например.
---
layout: generic
title: About
active: about
---
У меня есть навигация, включающая следующий раздел
<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>
Это работает для меня, поскольку количество ссылок в навигации очень узкое.
Ответ 5
Логика подсветки навигации - последнее, что я сделал бы на стороне сервера. Я предпочел бы придерживаться приятного, чистого и ненавязчивого подхода с использованием JS/jQuery (если этот параметр работает для вас).
-
Элементы, которые необходимо выделить, входят в общий макет, например:
<nav>
<a id="section1" href="#">Section 1</a>
<a id="section2" href="#">Section 2</a>
<a id="section3" href="#">Section 3</a>
</nav>
-
На вашей странице (или даже в вложенных макетах) вы помещаете элемент с data-ref="#section1"
(на самом деле любой селектор jQuery будет работать).
-
Теперь включите следующий фрагмент JS (показан как jQuery, но любая инфраструктура будет делать) в <head>
:
$(function() {
$("[data-ref]").each(function() {
$($(this).attr("data-ref")).addClass("current");
});
});
Этот подход хорош, поскольку он не делает предположений о базовой архитектуре, фреймворках, языках и механизмах шаблонов.
Обновление: Как некоторые люди указали, вы можете опустить часть $(function() { ... })
, которая связывает script к событию готовности DOM - и просто нажмите script до нижней части <body>
.
Ответ 6
Та же навигация по всем страницам
Прочитав все ответы, я придумал новое и более легкое в обслуживании решение:
- Добавить
{% include nav.html %}
в ваш _layouts/layout.html
файл
- Добавьте файл
nav.html
в папку _includes
-
Добавьте следующий файл в ваш nav.html
файл. Он определит, находится ли ваша ссылка на текущей странице и добавьте класс active
, а также удалите index.html
из вашей ссылки. Он также будет работать с подпапкой, такой как /repo-name
, которая необходима для GitHub gh-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>
-
Затем добавьте массив ссылок навигации в файл _config.yml
следующим образом. Имейте в виду правый отступ, поскольку YAML довольно придирчив к этому (Jekyll также).
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
Навигация только на дому - "назад" для других
Предполагая, что ссылка на вашу "домашнюю страницу" (index.html
) является первой частью массива внутри массива _config.html
navigation
, вы можете использовать следующий фрагмент, чтобы отобразить навигацию на разные страницы на главная/главная страница и ссылка на домашнюю страницу на всех других страницах:
<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>
Ответ 7
Добавляя к решению инкарнации, простейшая возможная строка кода с jQuery такова:
$( "a[href='{{ page.url | remove: "index.html" }}']" ).addClass("current");
Отлично работает для меня.
Ответ 8
Я сделал простой подход CSS. Во-первых, добавьте идентификатор в передний элемент...
---
layout: page
title: Join us
permalink: /join-us/
nav-class: join <-----
---
Добавьте это как класс в <body>
и ваш навигатор...
<body class="{{ page.nav-class }}">
и
<li class="{{ page.nav-class }}">...</a></li>
Затем свяжите их для всех страниц в CSS, например:
.about .about a,
.join .join a,
.contact .contact a {
color: #fff;
}
Основной недостаток - вам нужно жестко закодировать правила стиля.
Ответ 9
Я сделал это (извините за не-английский код):
<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>
Ответ 10
С Jekyll 3.4.3 это работает:
<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>