Jekyll - Автоматичне виділення поточної вкладки в рядку меню


81

Я використовую github для розміщення статичного сайту, а Jekyll для його створення.

У мене є рядок меню (як <ul>), і я хотів би, щоб <li>відповідній поточній сторінці був присвоєний інший клас для підсвічування CSS.

Отже, щось на зразок псевдокоду:

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

Або, можливо, навіть генерують ціле <ul>в Джекіллі.

Як це можна зробити з мінімальними змінами за межами порушника <ul>?


1
Для того, щоб вибрати , які сторінки використовувати, копіювати вставити з: stackoverflow.com/a/17215331/895245
Чіро Сантіллі郝海东冠状病六四事件法轮功

Відповіді:


116

Так, ви можете це зробити.
Для цього ми скористаємось тим, що поточна сторінка завжди представлена ​​рідинною змінною: pageу шаблоні, а також що кожна публікація / сторінка має унікальний ідентифікатор в своєму page.urlатрибуті.

Це означає, що нам просто потрібно використовувати цикл для побудови нашої навігаційної сторінки, і цим ми можемо перевірити page.urlкожен член циклу. Якщо він знаходить відповідність, він знає виділити цей елемент. Ось і ми:

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

Це працює, як очікувалося. Однак ви, мабуть, не хочете, щоб усі ваші сторінки знаходились у вашій навігаційній панелі. Для емуляції "групування" сторінки ви можете зробити щось на зразок цього:

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

Тепер сторінки можна "згрупувати". Щоб надати сторінці групу, потрібно вказати її на сторінках YAML Front Matter:

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

Нарешті, ви можете використовувати свій новий код! Скрізь, де вам потрібна навігація для вашого шаблону, просто "зателефонуйте" своєму файлу включення та передайте йому деякі сторінки та групу, яку ви хочете відобразити:

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

Приклади

Ця функціональність є частиною фреймворку Jekyll-Bootstrap . Ви можете побачити точну документацію для коду, викладеного тут: http://jekyllbootstrap.com/api/bootstrap-api.html#jbpages_list

Нарешті, ви можете побачити це в дії на самому веб-сайті. Просто подивіться на праворуч навігацію, і ви побачите, що поточна сторінка виділена зеленим кольором: Приклад виділеного навігаційного посилання


1
Чудове запитання, чудова відповідь, дякую. Це було просто змінити це для вручну вибраного списку вкладок. знайшов хвилину, щоб зрозуміти, що page.url включає символ '/', наприклад. "/index.html", а не "index.html"
cboettig,

Такий підхід призводить до помилки Джекіла для мене. jekyll 2.4.0 | Error: The included file '/Users/joelglovier/project/jekyllsite/_includes/pages_list' should exist and should not be a symlink
Джоель Гловір,

Надто складний для чогось, що повинно бути вбудоване в Джекілл.
Cameronroe

@cameronjroe спробуйте додати .htmlрозширення до pages_list та включити це замість цього
HotelCalifornia

48

Я вважаю, що для найпростіших вимог до навігації перелічені рішення є надто складними. Ось рішення, яке не передбачає фасад, javascript, цикли тощо.

Оскільки ми маємо доступ до URL-адреси сторінки, ми можемо нормалізувати та розділити URL-адресу та перевірити її на сегменти, наприклад:

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

Звичайно, це корисно лише в тому випадку, якщо статичні сегменти забезпечують засоби для окреслення навігації. Що завгодно складніше, і вам доведеться використовувати фасад, як @RobertKenny.


Це те, що я шукав, але чи не повинно бути classs="active"?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

@CiroSantilli 六四 事件 法轮功 якщо ваш CSS має стиль .active, то так. У відповіді вище, автор каже, що клас, який потрібно зателефонувати у свою таблицю стилів, - це .current. Нічого страшного.
Брайан Зеліп

3
@BrianZ це офіційно: занадто багато Bootstrap розтоплює твій мозок :)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

для домашньої сторінки мені довелося встановити {% if current [1] == null%}
GorvGoyl

17

Подібно до рішення @ ben-foster, але без використання будь-якого jQuery

Мені потрібно було щось просте, це те, що я зробив.

У своєму передньому плані я додав змінну з назвою 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="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>

Це працює для мене, оскільки кількість посилань у навігації дуже вузька.


Дякую @SurenderLohia Я люблю тримати речі якомога поодинокіше.
RobertKenny

16

Ось моє рішення, яке, на мою думку, є найкращим способом виділити поточну сторінку:

Визначте список навігації на _config.yml таким чином:

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

Тоді у вашому файлі _includes / header.html ви повинні прокрутити список, щоб перевірити, чи нагадує поточна сторінка ( page.url ) будь-який елемент списку навігації, якщо так, тоді ви просто встановите активний клас і додасте його до <a>тегу:

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

І оскільки ви використовуєте оператор містить замість оператора equals = , вам не потрібно писати додатковий код, щоб він працював із такими URL-адресами, як '/ blog / post-name /' або 'projects / project-name / ' . Тож це працює дуже добре.

PS: Не забудьте встановити змінну постійного посилання на своїх сторінках.


Це моє улюблене рішення, оскільки це означає, що я можу вибрати порядок сторінок.

Мені подобається це рішення, але воно не працює, якщо у вас є навігаційне посилання з url, /оскільки всі URL-адреси сторінок містять провісну риску. Наступні роботи: {% 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 %}
JamesWilson

6

Для цього я використав трохи JavaScript. У мене така структура в меню:

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

Цей фрагмент JavaScript підкреслює поточну відповідну сторінку:

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

Я особисто вважаю, що це чистіше, ніж описаний вище спосіб. Наведений вище спосіб починає ставати потворним, якщо ви хочете впорядкувати сторінки у навігаційній системі або якщо ви хочете, щоб за замовчуванням було виділено "Індекс".
Верхоген

Це просто і легко розпочати з додавання класу до поточного елемента сторінки. "Прийнята" відповідь зайняла близько години, щоб зрозуміти, як і чому. Дякуємо за поділ
Ashwin

4

Мій підхід полягає у визначенні користувацької змінної в передній частині сторінки YAML та виведенні її на <body>елемент:

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

Мої навігаційні посилання містять ідентифікатор сторінки, на яку вони посилаються:

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

У передній частині сторінки ми встановлюємо ідентифікатор сторінки:

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

І, нарешті, трохи jQuery для встановлення активного посилання:

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

Я вважав, що цього методу дуже легко дотримуватися і дозволяє легко сортувати пункти меню. Я дуже новачок у Jekyll, тому інші методи мене трохи залякали, але мені дуже зручно з jQuery. Можливо, це не на 100% ідеально для пуриста, але це працює і працює добре.
TheBrockEllis

Якщо ви хочете лише рідкий розчин, ви можете спробувати це: stackoverflow.com/a/46984009/2397550
JoostS

2

Навігація вашим веб-сайтом має бути невпорядкованим списком. Щоб елементи списку полегшилися, коли вони активні, наступний рідкий скрипт додає до них клас «активний». Цей клас повинен бути стилізований під CSS. Щоб визначити активне посилання, скрипт використовує "містить", як ви можете бачити в коді нижче.

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

Цей код сумісний з усіма стилями постійних посилань у Jekyll. Заява "містить" успішно виділяє перший пункт меню за такими URL-адресами:

  • починаємо/
  • get-started.html
  • get-started / index.html
  • початок роботи / підсторінка /
  • get-started / subpage.html

Джерело: http://jekyllcodex.org/without-plugin/simple-menu/


2

Тут багато заплутаних відповідей. Я просто використовую if:

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

Я посилаюся безпосередньо на сторінку та розміщую її всередині класу, до якого я хочу

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

Готово. Швидко.


Не могли б ви детальніше розказати, куди ви помістили кожен із цих елементів? header.html, або?
Жорж

1

Я використовував page.pathі відключав ім'я файлу.

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

0

Багато хороших відповідей вже є.

Спробуйте це.

Я трохи змінюю наведені вище відповіді.

_data/navigation.yaml

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

На сторінці -> portfolio.html(Те саме для всіх сторінок із відносно активною назвою сторінки)

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

якщо ви використовуєте тему Minima для jekyll, вам потрібно лише додати тернар до атрибуту class у header.html:

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

повний уривок:

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

додайте це до вашого _config.yml

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

І тоді, звичайно, ваш css:

   a.active {
                color: #e6402a;
            }

-2

Ось метод jQuery, щоб зробити те саме

  var pathname = window.location.pathname;

  $(".menu.right a").each(function(index) {
    if (pathname === $(this).attr('href') ) {
      $(this).addClass("active");
    }
  });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.