Jekyll - Tự động đánh dấu tab hiện tại trong thanh menu


81

Tôi đang sử dụng github để lưu trữ một trang web tĩnh và Jekyll để tạo nó.

Tôi có một thanh menu (dưới dạng <ul>) và muốn phần <li>tương ứng với trang hiện tại được gán một lớp khác để đánh dấu CSS.

Vì vậy, một cái gì đó giống như mã giả:

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

Hoặc thậm chí có thể tạo ra toàn bộ <ul>trong Jekyll.

Làm thế nào điều này có thể được thực hiện với những thay đổi tối thiểu bên ngoài vi phạm <ul>?


1
Để chọn trang nào sẽ sử dụng, hãy sao chép dán từ: stackoverflow.com/a/17215331/895245
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Câu trả lời:


116

Có bạn có thể làm điều này.
Để thực hiện điều này, chúng tôi sẽ tận dụng lợi thế của thực tế là trang hiện tại luôn được đại diện bởi biến lỏng: pagetrong mẫu, và mỗi bài đăng / trang có một mã định danh duy nhất trong page.urlthuộc tính của nó .

Điều này có nghĩa là chúng tôi chỉ cần sử dụng một vòng lặp để xây dựng trang điều hướng của mình và bằng cách đó, chúng tôi có thể kiểm tra page.urlmọi thành viên của vòng lặp. Nếu nó tìm thấy một điểm trùng khớp, nó sẽ biết làm nổi bật yếu tố đó. Chúng ta bắt đầu:

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

Điều này hoạt động như mong đợi. Tuy nhiên, bạn có thể không muốn tất cả các trang của mình nằm trong thanh điều hướng. Để mô phỏng "nhóm" trang, bạn có thể làm như sau:

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

Bây giờ các trang có thể được "nhóm lại". Để cung cấp cho một nhóm trang, bạn cần chỉ định nó trong các trang YAML Front Matter:

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

Cuối cùng, bạn có thể sử dụng mã mới của mình! Bất cứ nơi nào bạn cần điều hướng để đi trong mẫu của mình, chỉ cần "gọi" tệp bao gồm của bạn và chuyển nó một số trang và nhóm bạn muốn hiển thị:

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

Ví dụ

Chức năng này là một phần của khuôn khổ Jekyll-Bootstrap . Bạn có thể xem tài liệu chính xác cho mã được nêu tại đây: http://jekyllbootstrap.com/api/bootstrap-api.html#jbpages_list

Cuối cùng, bạn có thể thấy nó hoạt động trong chính trang web. Chỉ cần nhìn vào điều hướng bên phải và bạn sẽ thấy trang hiện tại được đánh dấu màu xanh lục: Ví dụ liên kết điều hướng được đánh dấu


1
Câu hỏi tuyệt vời, câu trả lời tuyệt vời, cảm ơn. Nó cũng được thực hiện ngay để sửa đổi điều này cho một danh sách các tab được chọn theo cách thủ công. mất một chút thời gian để nhận ra rằng page.url bao gồm '/', ví dụ. "/index.html", không phải "index.html"
cboettig

Cách tiếp cận này dẫn đến lỗi Jekyll cho tôi. jekyll 2.4.0 | Error: The included file '/Users/joelglovier/project/jekyllsite/_includes/pages_list' should exist and should not be a symlink
Joel Glovier

Quá phức tạp đối với một thứ gì đó nên được tích hợp sẵn trong Jekyll.
mời

@cameronjroe thử thêm các .htmlphần mở rộng cho pages_list và trong đó có thay
HotelCalifornia

48

Tôi cảm thấy như đối với yêu cầu điều hướng đơn giản nhất, các giải pháp được liệt kê quá phức tạp. Đây là một giải pháp không liên quan đến vấn đề phía trước, javascript, vòng lặp, v.v.

Vì chúng tôi có quyền truy cập vào URL của trang, chúng tôi có thể chuẩn hóa và chia nhỏ URL và kiểm tra đối với các phân đoạn, như sau:

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

Tất nhiên, điều này chỉ hữu ích nếu các phân đoạn tĩnh cung cấp phương tiện để phân định điều hướng. Bất cứ điều gì phức tạp hơn, và bạn sẽ phải sử dụng vấn đề phía trước như @RobertKenny đã chứng minh.


Đây là những gì tôi đang tìm kiếm, nhưng không nên classs="active"?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

@CiroSantilli 六四 事件 法轮功 nếu CSS của bạn có phong cách .active, thì có. Trong câu trả lời ở trên, tác giả đang nói rằng lớp để gọi trong biểu định kiểu của cô ấy / anh ấy là .current. Không phải vấn đề lớn.
Brian Zelip

3
@BrianZ nó chính thức: quá nhiều Bootstrap làm tan chảy bộ não của bạn :)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

cho trang chủ, tôi phải đặt {% if current [1] == null%}
GorvGoyl

17

Tương tự như giải pháp của @ ben -hers nhưng không sử dụng bất kỳ jQuery nào

Tôi cần một cái gì đó đơn giản, đây là những gì tôi đã làm.

Trong vấn đề đầu tiên của tôi, tôi đã thêm một biến có tên là active

ví dụ

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

Tôi có một điều hướng bao gồm phần sau

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

Điều này phù hợp với tôi vì số lượng liên kết trong điều hướng rất hẹp.


Cảm ơn @SurenderLohia Tôi muốn giữ mọi thứ đơn nhất có thể.
RobertKenny

16

Đây là giải pháp của tôi mà tôi nghĩ là cách tốt nhất để làm nổi bật trang hiện tại:

Xác định danh sách điều hướng trên _config.yml của bạn như sau:

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

Sau đó, trong tệp _includes / header.html của bạn, bạn phải lặp qua danh sách để kiểm tra xem trang hiện tại ( page.url ) có giống với bất kỳ mục nào của danh sách điều hướng hay không, nếu vậy bạn chỉ cần đặt lớp đang hoạt động và thêm nó vào <a>thẻ:

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

Và bởi vì bạn đang sử dụng toán tử chứa thay vì toán tử bằng = , bạn không phải viết thêm mã để làm cho nó hoạt động với các URL như '/ blog / post-name /' hoặc 'project / project-name / ' . Vì vậy, nó hoạt động thực sự tốt.

Tái bút: Đừng quên đặt biến liên kết cố định trên các trang của bạn.


Đây là giải pháp yêu thích của tôi vì nó có nghĩa là tôi có thể chọn thứ tự của các trang.

Tôi thích giải pháp này, nhưng nó không hoạt động nếu bạn có liên kết điều hướng với url /vì tất cả các url của trang đều chứa dấu gạch chéo ở đầu. Các công việc sau: {% 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 %}
James Wilson

6

Tôi đã sử dụng một chút JavaScript để thực hiện điều này. Tôi có cấu trúc sau trong menu:

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

Đoạn mã javascript này đánh dấu trang tương ứng hiện tại:

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

Cá nhân tôi nghĩ rằng cách này sạch hơn phương pháp trên. Phương pháp trên bắt đầu trở nên tồi tệ nếu bạn muốn sắp xếp thứ tự các trang trong điều hướng của mình hoặc nếu bạn muốn đánh dấu "Chỉ mục" theo mặc định.
Verhogen

Điều này đơn giản và dễ dàng để bắt đầu với việc thêm lớp vào phần tử trang hiện tại. Câu trả lời "được chấp nhận" mất khoảng giờ để tìm ra cách thức và lý do. Cảm ơn vì đã chia sẻ
Ashwin 20/09/13

4

Cách tiếp cận của tôi là xác định một biến tùy chỉnh trong nội dung YAML của trang và xuất biến này trên <body>phần tử:

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

Các liên kết điều hướng của tôi bao gồm mã nhận dạng của trang mà chúng liên kết đến:

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

Trong vấn đề đầu trang, chúng tôi đặt id trang:

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

Và cuối cùng là một chút jQuery để đặt liên kết hoạt động:

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

Tôi nghĩ rằng phương pháp này rất dễ làm theo và cho phép dễ dàng phân loại các món trong thực đơn. Tôi còn rất mới với Jekyll nên các phương pháp khác khiến tôi hơi sợ, nhưng tôi rất thoải mái với jQuery. Có thể không hoàn hảo 100% cho những người theo chủ nghĩa thuần túy, nhưng nó hoạt động và hoạt động tốt.
TheBrockEllis

Nếu bạn muốn có một giải pháp duy nhất chất lỏng, bạn có thể thử này: stackoverflow.com/a/46984009/2397550
JoostS

2

Điều hướng của trang web của bạn phải là một danh sách không có thứ tự. Để làm cho các mục trong danh sách sáng lên khi chúng hoạt động, tập lệnh lỏng sau đây sẽ thêm một lớp 'hoạt động' vào chúng. Lớp này nên được tạo kiểu bằng CSS. Để phát hiện liên kết nào đang hoạt động, tập lệnh sử dụng 'chứa', như bạn có thể thấy trong đoạn mã bên dưới.

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

Mã này tương thích với tất cả các kiểu liên kết cố định trong Jekyll. Câu lệnh 'chứa' làm nổi bật thành công mục menu đầu tiên tại URL sau:

  • bắt đầu/
  • get-started.html
  • get-started / index.html
  • bắt đầu / trang con /
  • get-started / subpage.html

Nguồn: http://jekyllcodex.org/without-plugin/simple-menu/


2

Rất nhiều câu trả lời khó hiểu ở đây. Tôi chỉ đơn giản sử dụng if:

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

Tôi tham khảo trực tiếp trang và đưa nó vào bên trong lớp học mà tôi muốn

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

Làm xong. Nhanh chóng.


Bạn có thể nói rõ hơn về nơi bạn đặt từng yếu tố đó không? header.html hoặc?
Georges

1

Tôi đã sử dụng page.pathvà tắt tên tệp.

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

0

Đã có rất nhiều câu trả lời hay.

Thử đi.

Tôi hơi thay đổi các câu trả lời ở trên.

_data/navigation.yaml

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

Trong một trang -> portfolio.html(Giống nhau cho tất cả các trang có tên trang hoạt động tương đối)

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

nếu bạn đang sử dụng chủ đề Minima cho jekyll, bạn chỉ cần thêm một bậc ba trên thuộc tính lớp trong header.html:

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

toàn bộ đoạn trích:

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

thêm cái này vào _config.yml của bạn

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

Và tất nhiên sau đó css của bạn:

   a.active {
                color: #e6402a;
            }

-2

Đây là một phương thức jQuery để làm điều tương tự

  var pathname = window.location.pathname;

  $(".menu.right a").each(function(index) {
    if (pathname === $(this).attr('href') ) {
      $(this).addClass("active");
    }
  });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.