Jekyll-自动突出显示菜单栏中的当前选项卡

我使用 github 托管一个静态站点,Jekyll 生成它。

我有一个菜单栏(作为 <ul>) ,并希望对应于当前页面的 <li>被分配一个不同的 CSS 突出显示类。

比如伪代码:

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

或者甚至可能在 Jekyll 生成整个 ABc0。

如何做到这一点,以最小的变化之外的违规 <ul>

31701 次浏览

Yes you can do this.
To accomplish this we will take advantage of the fact that the current page is always represented by the liquid variable: page in the template, and also that each post/page has a unique identifier in its page.url attribute.

This means that we just have to use a loop to build our navigation page, and by doing so we can check page.url against every member of the loop. If it finds a match, it knows to highlight that element. Here we go:

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

This works as expected. However you probably don't want all your page's in your nav bar. In order to emulate page "grouping" you can something like this:

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

Now pages can be "grouped". To give a page a group you need to specify it in the pages YAML Front Matter:

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

Finally you can use your new code! Wherever you need your navigation to go in your template, simply "call" your include file and pass it some pages and the group you want to display:

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

Examples

This functionality is part of the Jekyll-Bootstrap framework. You can see exact documentation for the code outlined here: http://jekyllbootstrap.com/api/bootstrap-api.html#jbpages_list

Finally you can see it in action within the website itself. Just look at the righthand navigation and you will see the current page is highlighted in green: Example highlighted nav link

I used a little bit of JavaScript to accomplish this. I have the following structure in the 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>

This javascript snippet highlights the current corresponding page:

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

My approach is to define a custom variable in the YAML front matter of the page and output this on the <body> element:

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

My navigation links include the identifier of the page that they link to:

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

In the page front matter we set the page id:

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

And finally a bit of jQuery to set the active link:

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

Similar to @ben-foster's solution but without using any jQuery

I needed something simple, this is what I did.

In my front matter I added a variable called active

e.g.

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

I have a navigation include with the following section

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

This works for me as the amount of links in the navigation are very narrow.

I feel like for the simplest navigation requirement, the listed solutions are overly complex. Here's a solution that involves no front matter, javascript, loops, etc.

Since we have access to the page URL, we can normalize and split the URL and test against the segments, like so:

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

Of course, this is only useful if static segments provide the means to delineate the navigation. Anything more complicated, and you'll have to use front matter like @RobertKenny demonstrated.

Here's my solution which I think is the best way to highlight the current page:

Define a navigation list on your _config.yml like this:

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

Then in your _includes/header.html file you must loop through the list to check if the current page (page.url) resembles any item of the navigation list, if so then you just set the active class and add it to the <a> tag:

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

And because you're using the contains operator instead of the equals = operator, you don't have to write extra code to make it work with URLs such as '/blog/post-name/' or 'projects/project-name/'. So it works really well.

P.S: Don't forget to set the permalink variable on your pages.

Here is a jQuery method to do the same

  var pathname = window.location.pathname;


$(".menu.right a").each(function(index) {
if (pathname === $(this).attr('href') ) {
$(this).addClass("active");
}
});

Lot of good answers are already there.

Try this.

I slightly alter the above answers.

_data/navigation.yaml

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

In a page -> portfolio.html (Same for all pages with a relative active page name)

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

I've been using page.path and going off the filename.

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

The navigation of your website should be an unordered list. To get the list items to lighten up when they are active, the following liquid script adds an 'active' class to them. This class should be styled with CSS. To detect which link is active, the script uses ‘contains’, as you can see in the code below.

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

This code is compatible with all permalink styles in Jekyll. The ‘contains’ statement succesfully highlights the first menu item at the following URL’s:

  • getting-started/
  • getting-started.html
  • getting-started/index.html
  • getting-started/subpage/
  • getting-started/subpage.html

Source: http://jekyllcodex.org/without-plugin/simple-menu/

Lot's of confusing answers here. I simply use an if:

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

I refer directly to the page and putting it inside the class I want to

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

Done. Quick.

if you're using the Minima theme for jekyll, you only need to add a ternary on the class attribute in header.html:

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

the full excerpt:

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

add this to your _config.yml

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

And then of course your css:

   a.active {
color: #e6402a;
}