在配置文件

时间:2018-02-02 19:18:19

标签: hugo

我一直遇到问题,只要我使用它(至少两年),就可以在Hugo中突出显示'当前菜单项'。

如果我在内容文件中使用frontmatter定义菜单(即单独将每个内容添加到菜单中),似乎是可能的。但是我不想使用这些信息丢弃我的内容文件的前端,特别是看看如何使用主配置文件定义菜单。

以下是我在配置文件中声明菜单的方式(我更喜欢使用JSON而不是YAML):

"menu": {
  "main": [
    {
      "name": "Home",
      "weight": 1,
      "url": "/"
    },
    {
      "name": "About",
      "weight": 2,
      "url": "/about"
    },
    {
      "name": "Blog",
      "weight": 3,
      "url": "/blog"
    },
    {
      "name": "Contact",
      "weight": 4,
      "url": "/contact"
    }
  ]
},

这是我的菜单模板

<ul class="nav">
  {{ $currentPage := . }}
  {{ range .Site.Menus.main }}
    {{ if .HasChildren }}
      <li class="nav-item nav-item--has-submenu{{ if $currentPage.HasMenuCurrent "main" . }} nav-item--active{{ end }}">
        <a class="nav-link" href="javascript:;" title="{{ .Name }}">
          {{ .Pre }}
          <span>{{ .Name }}</span>
        </a>
        <ul class="nav-submenu">
          {{ range .Children }}
            <li class="nav-item{{ if $currentPage.IsMenuCurrent "main" . }} nav-item--active{{ end }}">
              <a class="nav-link" href="{{ .URL }}" title="{{ .Name }}">
                <span>{{ .Name }}</span>
              </a>
            </li>
          {{ end }}
        </ul>
      </li>
    {{else}}
      <li class="nav-item">
        <a class="nav-link" href="{{ .URL }}" title="{{ .Name }}">
          {{ .Pre }}
          <span>{{ .Name }}</span>
        </a>
      </li>
    {{end}}
  {{end}}
</ul>

我知道上面的标记是专门检查每个内容的前端,我理解为什么它不起作用。我想知道的是,为了突出显示当前菜单项,我必须做出哪些更改。

我认为通过配置文件定义菜单是为了将非Hugo链接添加到菜单中,因此无需突出显示这些项目。这是否可能,或者我将不得不接受我需要在我的内容中使用frontmatter来构建我的菜单?

由于

1 个答案:

答案 0 :(得分:2)

我看到了两个问题,两个都可能引起问题。

第一个问题,也是我认为正在引起麻烦的一个问题,是您没有以斜杠结束URL。 Hugo将所有URL规范化为以斜杠结尾,并将重定向到正确的URL,但是当.IsMenuCurrent.HasMenuCurrent比较URL以查看它们是否引用相同的资源时,他们不会将其纳入帐户;他们只会看到/blog/blog/不同。

尝试使用:

"menu": {
  "main": [
    {
      "name": "Home",
      "weight": 1,
      "url": "/"
    },
    {
      "name": "About",
      "weight": 2,
      "url": "/about/"
    },
    {
      "name": "Blog",
      "weight": 3,
      "url": "/blog/"
    },
    {
      "name": "Contact",
      "weight": 4,
      "url": "/contact/"
    }
  ]
},

第二个问题是.IsMenuCurrent.HasMenuCurrent方法没有考虑到您可能正在运行一个多语言站点,该站点中来自您的单个标准URL(例如/blog/菜单配置可以通过/en/blog/重写/es/blog/relLangURL,以便正确链接到当前语言的相应页面。因此,如果您尝试将菜单配置保持为DRY,则可能会发现这两种方法仅(最多)适用于您的主要语言。

根据您提供的模板,这似乎并不适用于您,但是我将为发现此问题的其他人提供解决方案。

为了解决此问题,您要么需要为每种语言维护单独的菜单(这很痛苦),要么使用自己的逻辑来确定菜单项是否指向当前页面。幸运的是,它非常简单:

{{ $currentPage := . }}
{{ range .Site.Menus.main }}

    {{ $menu_item_url := .URL | relLangURL }}
    {{ $page_url:= $currentPage.RelPermalink | relLangURL }}

    {{ if eq $menu_item_url $page_url }}
        {{/* the menu item links to the current page (with relLangURL) */}}
    {{ end }}

{{ end }}