Jekyll выбирает URL текущей страницы и меняет ее класс - PullRequest
51 голосов
/ 16 июня 2011

Я использую 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 в зависимости от некоторой переменной, установленной с использованием liquid / YAML.

Есть ли простой способ сделать это?

Поскольку панель является общей для всех страниц, она теперь находится в макете по умолчанию. Я мог бы использовать Javascript для определения URL-адреса и выделения, но мне было интересно, есть ли способ сделать это в Jekyll.

Ответы [ 10 ]

53 голосов
/ 16 июня 2011

Я делаю это на двух страницах, которые я настроил в Джекиле.

Первое, что я делаю, это создаю запись внутри _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 текущей страницы. Если они равны, страница активна. В противном случае они не являются.

Существует пара особых случаев: во всех сообщениях блога должна быть ссылка «блог», а на первых страницах (на английском и испанском языках) не должна быть навигационная панель. В обоих случаях я полагаюсь на тот факт, что сообщения блога и первые страницы имеют определенные макеты (обратите внимание, что ссылки «Блог» и «Проект» в yaml имеют дополнительный параметр «макет»)

Код навигации генерируется так:

{% 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, но сейчас это происходит очень редко.

Я думаю, навигационный yaml может входить в _include под названием "навигация" или что-то подобное, но я не пробовал использовать yaml внутри них, поэтому я не знаю, будет ли это работать. В моем случае, так как у меня есть многоязычный сайт, в конфигурации все проще (пропущенные переводы легче обнаружить)

Надеюсь, это поможет.

50 голосов
/ 20 июня 2013

В качестве дальнейшего расширения работы другого, вот способ заставить его работать без скучного 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-адресами page.navigation.

18 голосов
/ 22 января 2013

Это может быть новая функция с тех пор, как вопрос впервые появился, но я обнаружил, что все это можно сделать в одном файле:

  1. определить навигацию как переменную в заголовке yaml
  2. переберите переменную, используя жидкость

Так что в моем _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>
12 голосов
/ 11 сентября 2013

Мне нужно было что-то простое, это то, что я сделал.

В начале я добавил переменную с именем 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>

Это работает для меня, так как количество ссылок в навигации очень узкое.

4 голосов
/ 13 июля 2013

Та же навигация по всем страницам

Прочитав все эти ответы, я нашел новое и более простое в обслуживании решение:

  1. Добавьте {% include nav.html %} к вашему _layouts/layout.htmlfile
  2. Добавьте файл nav.html в папку _includes
  3. Добавьте следующее содержимое в файл 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>
    
  4. Затем добавьте массив ссылок навигациив ваш файл _config.yml, как показано ниже.Обратите внимание на правильные отступы, поскольку YAML довольно требователен к этому (также Джекилл).

    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 s 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>
3 голосов
/ 16 мая 2013

Логика подсветки навигации - последнее, что я бы сделал на стороне сервера. Я бы предпочел придерживаться красивого, чистого и ненавязчивого подхода с использованием JS / jQuery (если этот вариант работает для вас).

  1. Элементы, которые необходимо выделить, входят в общий макет, подобный следующему:

    <nav>
      <a id="section1" href="#">Section 1</a>
      <a id="section2" href="#">Section 2</a>
      <a id="section3" href="#">Section 3</a>
    </nav>
    
  2. На вашей странице (или даже во вложенных макетах) вы размещаете элемент с data-ref="#section1" (фактически, любой селектор jQuery будет работать).

  3. Теперь включите следующий фрагмент JS (показанный как jQuery, но подойдет любой фреймворк) в <head>:

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

Этот подход хорош, потому что он не делает никаких предположений о базовой архитектуре, платформах, языках и шаблонизаторах.

Обновление: Как и некоторые люди указали , вы можете пропустить часть $(function() { ... }), которая связывает скрипт с событием готовности DOM - и просто толкните скрипт вниз вашего <body>.

2 голосов
/ 30 марта 2017

С 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>
2 голосов
/ 07 марта 2017

Это работает для меня (извините за не английский код):

<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>
1 голос
/ 05 января 2016

Я выбрал простой CSS-подход. Во-первых, добавьте идентификатор в начале вопроса ...

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

Добавьте это как класс в <body> и your nav ...

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

и

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

Затем свяжите их для всех страниц в CSS, например:

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

Основным недостатком является необходимость жесткого кодирования правил стиля.

1 голос
/ 02 декабря 2015

Если добавить к решению incarnate, простейшая возможная строка кода с помощью jQuery:

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

У меня отлично работает.

...