i18n Menu

Assuming you had enabled i18n for your HUGO repository, managing menus for language specific websites can be very painful due to the confusing documentations. There are 2 known ways:

Configuration files

Editing config/*ANY*/languages.toml

If you are like me who uses separated config files, especially config/*ANY*/languages.toml, you're in luck. The idea is to add the array item under the language definition. Example:

[en]
languageCode = "en_US"
languageName = "English"
contentDir = "../docs/en"
title = "My New Hugo Site"
weight = 0

[[en.menu.main]]
url = "/"
name = "Home"
weight = 0


[zh_cn]
languageCode = "zh_CN"
languageName = "Chinese (Simplified)"
contentDir = "../docs/zh_cn"
title = "我的Hugo网站"
weight = 1

[[ zh_cn.menu.main ]]
url = "/"
name = "总站"

NOTE

  • Each menu item has a minimum of compulsory variables like:
    • url
    • name
    • weight
  • Optional variables are:
    • parent (for sub-menu item)
    • identifier (for parent linking)
    • your variables like pre for icon codes.


Separate Menus Configuration Files

These configuration files follow a common pattern:

menus.<language symbol>.toml

NOTE

  • It's plural menu, not singular.
  • language symbol should be the same as the one you declared in languages.toml.


Inside the menu configuration files, you can add the menu items easily using the following example:

[[main]]
url = "/"
identifier = "总站"
name = "菜单总站"
weight = 0  

NOTE

  • Make sure you use [[ ... ]] not [ ... ]. It's TOML's array element, not array.

Rendering with Language Keywords

Now, since we're using i18n, we need to make sure the rendering is using language processor (e.g. absLangURL or relLangURL). Here's an example based on the template:

{{ $currentPage := . -}}
{{ range .Site.Menus.main -}}
{{ if .HasChildren }}
<li class="{{- if $currentPage.HasMenuCurrent "main" . -}}active{{- end -}}">
        <a href="#">{{ .Pre }}<span>{{ .Name }}</span></a>
        <ul class="sub-menu">
        {{- range .Children }}
                <li class="{{- if $currentPage.IsMenuCurrent "main" . -}}
                        active
                {{- end -}}">
                <a href="{{ .URL | absLangURL }}">{{ .Name }}</a>
                </li>
        {{- end }}
        </ul>
</li>
{{ else }}
<li>
        <a href="{{ .URL | absLangURL }}">{{ .Pre }}<span>{{ .Name }}</span></a>
</li>
{{- end }}
{{- end }}

IMPORTANT NOTE

  1. If you are using baseURL that has a default path, example: https://www.example.com:8080/project, you can't use absLangURL. Refer to Link.

That's all about i18n menu.