从 Jekyll 导航栏中排除页面

问题描述 投票:0回答:4

我正在建立一个基本的 Github 托管 Jekyll 网站(非常小,我什至懒得更改默认主题)。我有一个嵌套网站,其中有少量第一层页面,我希望它们出现在导航栏中(即默认操作模式)。我还有一些第二层页面,我不想把它们弄乱导航栏。

虽然多级导航系统会很好,但我试图避免使用插件。因此,我认为最简单的解决方案就是从导航系统中完全排除第二层页面。

这是一个假设的页面结构(减去其他 Jekyll 文件):

jekyllsite
jekyllsite/bar
jekyllsite/bar/alice
jekyllsite/bar/alice/index.md
jekyllsite/bar/bob
jekyllsite/bar/bob/index.md
jekyllsite/bar/index.md
jekyllsite/baz
jekyllsite/baz/index.md
jekyllsite/foo
jekyllsite/foo/eggs
jekyllsite/foo/eggs/index.md
jekyllsite/foo/index.md
jekyllsite/foo/spam
jekyllsite/foo/spam/index.md
jekyllsite/index.md

按照很棒的降序排列,这就是我希望的方式:

  1. 最好的情况,上下文敏感的导航(不认为没有插件就不可能):当访问 jekyllsite/index.md 时,我会得到一个单层导航栏,为我提供 foo、bar 和 baz 的链接。当访问 jekyllsite/bar/index.md 时,我会看到一个双层导航栏,顶层包含 foo、bar 和 baz,第二层包含 alice 和 bob。

  2. 对我来说,下一个最佳选择是全局更改某些内容,以便仅将顶级目录(foo、bar、baz)添加到导航栏。 alice、bob、spam 和 Eggs 等子目录将自动从导航栏中排除。

  3. 最后(我认为这可能是最简单的)是使用 YAML frontmatter 标志来排除页面。要排除的页面前面的类似

    nonav: true
    的内容。

这似乎是一个相当常见的用例,尽管我还没有找到任何看起来像这三个选项中任何一个的捷径的东西。我希望更熟悉 Jekyll 的人能给出“阻力最小的路径”的答案。

jekyll liquid
4个回答
18
投票

我个人也这样做;

主菜单中出现的页面的正面内容

---
layout: default
title: Home
menu: main
weight: 10
---

主菜单模板(类来自 twitter bootstrap):

<ul class="nav navbar-nav">
  {% comment %}Jekyll can now sort on custom page key{% endcomment %}
  {% assign pages = site.pages | sort: 'weight' %} 
  {% for p in pages %}
    {% if p.menu == 'main' %}
      <li{% if p.url == page.url %} class="active"{% endif %}>
         <a href="{{ site.baseurl }}{{ p.url }}">{{ p.title }}</a>
      </li>
    {% endif %}
  {% endfor %}
</ul>

然后,您可以通过在 yaml 前面的内容中设置自定义变量来在任何级别复制该内容:

menu : foo

并将值传递给菜单模板

{% include navbar.html  menuLevel="foo" %}

然后像这样拦截它:

{% if p.menu == menuLevel %}

任何不公开 菜单:toto 的页面都不会出现在导航中。


18
投票

如果您来自基本 Jekyll 主题,从标题站点导航中排除页面的最简单方法是添加

unless page.exclude
例外。

page.exclude
是一个新的 Yaml frontmatter 属性。)

默认情况下,这是在

_includes/header.html
:

{% for page in site.pages %}
    {% unless page.exclude %}
       {% if page.title %}
         <a class="page-link" href="{{ page.url | prepend: site.baseurl }}">{{ page.title }}</a>
       {% endif %}
    {% endunless %}
{% endfor %}

以及任何页面的 Yaml frontmatter 的相应标签:

---
... other attributes ...
exclude: true
---

归功于迈克尔·查德威克


13
投票

可以创建一个多层次的、上下文相关的导航,就像你所描述的,无需插件,我已经做到了。

唯一需要注意的是,您需要使用菜单层次结构维护一个 YAML 数据文件 - 按照我的方法,不可能从目录结构自动生成此文件。

我将在这里展示简短的版本,但我的博客上有更详细的解释:


1.创建一个包含菜单层次结构的 YAML 数据文件 (
/_data/menu.yml
):

- text: Home
  url: /
- text: First menu
  url: /first-menu/
  subitems:
    - text: First menu (sub)
      url: /first-menu/first-menu-sub/
      subitems:
        - text: First menu (sub-sub)
          url: /first-menu/first-menu-sub/first-menu-sub-sub/
- text: Second menu
  url: /second-menu/
  subitems:
    - text: Second menu (sub)
      url: /second-menu/second-menu-sub/

2.创建一个包含以下内容的 include 文件 (
/_includes/nav.html
):

{% assign navurl = page.url | remove: 'index.html' %}
<ul>
{% for item in include.nav %}
    <li>
        <a href="{{ item.url }}">
            {% if item.url == navurl %}
                <b>{{ item.text }}</b>
            {% else %}
                {{ item.text }}
            {% endif %}
        </a>
    </li>
    {% if item.subitems and navurl contains item.url %}
        {% include nav.html nav=item.subitems %}
    {% endif %}
{% endfor %}
</ul>

此包含文件将负责显示每个页面的正确导航:

  • 仅显示当前页面的下一级子项目
  • 以粗体显示当前页面

如果您不明白包含文件到底在幕后做什么,请阅读我的博客文章 - 我在那里详细解释了(在“递归包含文件”部分)


3.在您的主布局文件中,嵌入包含文件:

{% include nav.html nav=site.data.menu %}

这将显示导航。
请注意,我将完整的数据文件从步骤 1 传递到包含文件。


仅此而已!

正如我一开始所说:

这种方法的唯一缺点是,每次创建新页面时,您需要将页面的标题和 URL 插入到数据文件中。

但另一方面,这使得从导航中排除某些页面变得非常容易:您只需不将它们添加到数据文件中即可。


0
投票

在 _pages > blog.md 中,可以设置 nav:false。


布局:默认 永久链接:/博客/ 标题:博客 导航:假

© www.soinside.com 2019 - 2024. All rights reserved.