在配置文件中定义的 Hugo 菜单中突出显示 CurrentMenuItem
Highlighting CurrentMenuItem in a Hugo menu that is defined in config file
自从我使用 Hugo 以来(至少两年),我一直无法让 'current menu item' 在 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>
我知道上面的标记是专门检查每段内容的 frontmatter,我明白为什么它不起作用。我只想知道我必须进行哪些更改才能突出显示当前菜单项。
我认为通过配置文件定义菜单是为了向菜单添加非 Hugo 链接,因此无需突出显示这些项目。这甚至可能吗,或者我是否必须接受我需要在我的内容中使用 frontmatter 来构建我的菜单?
谢谢
我看到两个问题,其中任何一个都可能导致问题。
第一个问题,也是我认为给您带来麻烦的一个问题,是您没有以斜线结束 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 like /blog/
从你的菜单配置可以重写 /en/blog/
或 /es/blog/
通过 relLangURL
为了正确地 link 到当前语言的适当页面。因此,如果您试图让菜单配置保持干爽,您可能会发现这两种方法(至多)仅适用于您的主要语言。
根据您提供的模板,这似乎不适用于您,但我会为找到此问题的其他人提供解决方案。
为了解决这个问题,您要么需要为每种语言维护单独的菜单,这很麻烦,要么使用您自己的逻辑来确定菜单入口是否指向当前页面。幸运的是,它非常简单:
{{ $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 }}
自从我使用 Hugo 以来(至少两年),我一直无法让 'current menu item' 在 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>
我知道上面的标记是专门检查每段内容的 frontmatter,我明白为什么它不起作用。我只想知道我必须进行哪些更改才能突出显示当前菜单项。
我认为通过配置文件定义菜单是为了向菜单添加非 Hugo 链接,因此无需突出显示这些项目。这甚至可能吗,或者我是否必须接受我需要在我的内容中使用 frontmatter 来构建我的菜单?
谢谢
我看到两个问题,其中任何一个都可能导致问题。
第一个问题,也是我认为给您带来麻烦的一个问题,是您没有以斜线结束 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 like /blog/
从你的菜单配置可以重写 /en/blog/
或 /es/blog/
通过 relLangURL
为了正确地 link 到当前语言的适当页面。因此,如果您试图让菜单配置保持干爽,您可能会发现这两种方法(至多)仅适用于您的主要语言。
根据您提供的模板,这似乎不适用于您,但我会为找到此问题的其他人提供解决方案。
为了解决这个问题,您要么需要为每种语言维护单独的菜单,这很麻烦,要么使用您自己的逻辑来确定菜单入口是否指向当前页面。幸运的是,它非常简单:
{{ $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 }}