Nav

提供一个助手来构建菜单和面包屑导航。

配置参数

name string

The helper name

Default:
"nav"
order string

The default order for the children

Default:
"basename=asc-locale"

描述

这个插件注册了 nav 助手,用于在你的页面中构建导航相关的东西,例如菜单和面包屑导航。

安装

在你的 _config.ts 文件中导入这个插件来使用它:

import lume from "lume/mod.ts";
import nav from "lume/plugins/nav.ts";

const site = lume();

site.use(nav(/* Options - 选项 */));

export default site;

菜单

nav.menu() 函数返回一个树形对象,其中包含完整的站点结构,并使用页面的 URL 来定义层级关系。例如,假设我们的站点导出了以下页面:

  • /
  • /articles/
  • /articles/first-article/
  • /articles/second-article/chapter-1/
  • /articles/second-article/chapter-2/

nav.menu() 返回的对象会是这样的:

{
  data: { basename: "", ...Data },
  children: [
    {
      data: { basename: "articles", ...Data },
      children: [
        {
          data: { basename: "first-article", ...Data },
        },
        {
          data: { basename: "second-article" },
          children: [
            {
              data: { basename: "chapter-1", ...Data },
            },
            {
              data: { basename: "chapter-2", ...Data },
            },
          ],
        },
      ],
    },
  ];
}

一些有趣的点:

  • data 属性包含了页面数据对象。因此你可以访问任何页面变量,例如 data.titledata.url
  • basenamesecond-article 的项没有更多的数据,因为没有 URL 为 /articles/second-article/ 的页面。注意,在这个 URL 内部存在页面 (/articles/second-page/chapter-1//articles/second-page/chapter-2/),它们确实有 data 值。

你可以在你的模板中使用这个对象来递归地构建菜单。例如在 Vento 中:

<ul class="menu">
  {{ for item of nav.menu().children }}
    <li>
      {{ include "templates/menu_item.vto" { item } }}
    </li>
  {{ /for }}
</ul>
{{ if item.data.url }}
  <a href="{{ item.data.url }}">
    {{ item.data.title }}
  </a>
{{ else }}
  <span>{{ item.data.basename }}</span>
{{ /if }}

<ul>
  {{ for child of item.children }}
  <li>
    {{ include "templates/menu_item.vto" { item: child } }}
  </li>
  {{ /for }}
</ul>

更改初始 URL

如果你想从特定的页面开始你的菜单,只需在第一个参数中包含它的 URL:

nav.menu("/articles/");

筛选和排序

你可以像 Search 插件一样筛选和排序菜单的元素。例如,让我们构建一个包含英文页面的菜单,并按 URL 排序:

nav.menu("/", "lang=en", "url=asc");

导出为 JSON

菜单可以导出为 JSON,这对于在前端使用它很有用:

const menu = nav.menu();
JSON.stringify(menu);

下一页和上一页

使用函数 nav.nextPage()nav.previousPage() 来返回相对于当前页面的菜单中的下一页和上一页。

例如,假设我们有以下使用 nav.menu() 创建的树形结构:

docs
  |__ getting-started
        |__ installation
        |__ configuration
  |__ plugins
        |__ prettier

函数 nav.nextPage() 返回相对于提供的 URL 的下一页。例如:

const nextPage = nav.nextPage("/docs/getting-started/installation/");
console.log(nextPage.url); // /docs/getting-started/configuration/

如果页面是当前部分的最后一个同级页面,它将返回下一部分的第一个页面:

const nextPage = nav.nextPage("/docs/getting-started/configuration/");
console.log(nextPage.url); // /docs/plugins/

如果当前部分有子页面,它将返回第一个子页面:

const nextPage = nav.nextPage("/docs/plugins/");
console.log(nextPage.url); // /docs/plugins/prettier/

nav.previousPage() 的工作方式类似,但顺序相反。

这些函数的第一个参数是你想要用作当前的 URL。接下来的参数与 nav.menu() 相同,因此你可以配置基础路径、查询和排序选项以匹配菜单:

nav.menu("/", "lang=en", "url=asc");

nav.nextPage(url, "/", "lang=en", "url=asc");
nav.previousPage(url, "/", "lang=en", "url=asc");

面包屑导航

nav.breadcrumb() 函数返回一个数组,其中包含直到根目录的父项。例如,页面 /articles/second-article/chapter-2/ 返回以下面包屑导航数据:

[
  {
    slug: "chapter-2",
    data: Data,
  },
  {
    slug: "second-article",
    children: [...],
  },
  {
    slug: "articles",
    data: Data,
    children: [...],
  },
  {
    slug: "",
    data: Data,
    children: [...],
  }
]

我们可以使用这些数据,通过以下 Vento 代码生成面包屑导航:

<ul>
  {{ for item of nav.breadcrumb("/articles/second-article/chapter-2") }}
  <li>
    {{ if item.data }}
      <a href="{{ item.data.url }}">
        {{ item.data.title }}
      </a>
    {{ else }}
      <span>{{ item.slug }}</span>
    {{ /if }}
  </li>
  {{ /for }}
</ul>