Выделение CurrentMenuItem в меню Hugo, которое определено в файле конфигурации

У меня были проблемы с выделением «текущего пункта меню» в Hugo, пока я его использую (не менее двух лет).

Это представляется возможным, если я определяю меню, используя передний план в моих файлах содержимого (т.е. индивидуально добавляю каждую часть содержимого в меню). Однако я не хочу засорять переднюю часть моих файлов содержимого этой информацией, особенно учитывая то, как можно определять свои меню с помощью основного файла конфигурации.

Вот как я объявляю свое меню в моем файле конфигурации (я предпочитаю использовать 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, и, следовательно, нет необходимости выделять эти элементы. Возможно ли это вообще, или мне придется признать, что мне нужно использовать фронтматтер в моем контенте, чтобы создавать свои меню?

Спасибо


person Donny Burnside    schedule 02.02.2018    source источник
comment
Вы что-то придумали?   -  person LostBalloon    schedule 20.01.2019
comment
Нет, к сожалению нет.   -  person Donny Burnside    schedule 27.01.2019


Ответы (1)


Я вижу две проблемы, каждая из которых может вызвать проблемы.

Первая проблема, которая, как мне кажется, вызывает у вас проблемы, заключается в том, что вы не заканчиваете свои URL-адреса косой чертой. Хьюго нормализует все 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, чтобы правильно связать на соответствующую страницу для текущего языка. Итак, если вы пытаетесь сохранить конфигурацию меню в СУХОМ виде, вы, вероятно, обнаружите, что эти два метода работают только (в лучшем случае) для вашего основного языка.

Судя по предоставленному вами шаблону, это не относится к вам, но я включу решение для тех, кто найдет этот вопрос.

Чтобы исправить это, вам нужно либо поддерживать отдельные меню для каждого языка, что является проблемой, либо использовать собственную логику, чтобы определить, указывает ли вход меню на текущую страницу. К счастью, это довольно просто:

{{ $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 }}
person Dan Welty    schedule 05.06.2019