Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/guides/menu-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ in one place.

This theme offers a `main` menu, a `footer` menu and a `secondary` menu. You can
create menu entries for contents created by this theme and your custom contents
(e.g. an imprint). When the menus get rendered, this theme tries to translate
each menu entry by its identifier (`menu.` + identifier). If no translation is
available, the name of the menu entry will be used.
(e.g. an imprint). When the menus get rendered, user defined name properties will
take presedence over predefined translations. If the name is empty or not set by
Comment on lines +15 to +16
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "presedence" should be "precedence" (and consider hyphenating "user-defined").

Suggested change
(e.g. an imprint). When the menus get rendered, user defined name properties will
take presedence over predefined translations. If the name is empty or not set by
(e.g. an imprint). When the menus get rendered, user-defined name properties will
take precedence over predefined translations. If the name is empty or not set by

Copilot uses AI. Check for mistakes.
the user this theme tries to translate each menu entry by its identifier
(`menu.` + identifier). If no translation is available, a default name based on
the identifier of the menu entry will be used.

**Note:** A maximum of four menu items can be displayed in the `secondary` menu.

Expand All @@ -28,6 +30,7 @@ languages:
menus:
main:
- identifier: sessions
name: Program
pageRef: /sessions
weight: 10
- identifier: code_of_conduct
Expand All @@ -48,6 +51,7 @@ languages:
menus:
main:
- identifier: sessions
name: Programm
pageRef: /sessions
weight: 10
- identifier: code_of_conduct
Expand Down
10 changes: 9 additions & 1 deletion layouts/miscellaneous/about.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@

<div class="section-container">
<section class="section about">
<h1 class="heading heading--1">{{- T "about_page.heading" }}</h1>
<h1 class="heading heading--1">
{{- partial "menus/menu_label.html"
(dict
"menus" .Site.Menus.main
"pageRef" "/about"
"translationKey" "about_page.heading"
)
}}
</h1>
{{ with $event.aboutUs }}
<div class="markdown about__text">
{{ . | markdownify }}
Expand Down
8 changes: 7 additions & 1 deletion layouts/miscellaneous/location.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@
<div class="section-container">
<section class="section">
<h1 class="heading heading--1">
{{- T "location_page.heading" }}
{{- partial "menus/menu_label.html"
(dict
"menus" .Site.Menus.main
"pageRef" "/location"
"translationKey" "location_page.heading"
)
}}
</h1>

{{ with $event.address }}
Expand Down
2 changes: 1 addition & 1 deletion layouts/partials/menus/footer.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
{{- range $input.menu }}
<li>
<a class="footer-menu__link" href="{{ .URL }}" aria-label="{{- or (T (printf "menu.%s" .Identifier)) .Name }}">
{{- or (T (printf "menu.%s" .Identifier)) .Name }}
{{- or .Name (T (printf "menu.%s" .Identifier)) }}
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now prefers .Name over the menu.<identifier> translation. If menu items are generated automatically (e.g. via sectionPagesMenu), .Name will be set even without a user-configured name, which can bypass translations and break localization. Consider using the translation by default and only using .Name when it’s explicitly configured / differs from the default.

Suggested change
{{- or .Name (T (printf "menu.%s" .Identifier)) }}
{{- or (T (printf "menu.%s" .Identifier)) .Name }}

Copilot uses AI. Check for mistakes.
Comment on lines 7 to +8
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The link text now prefers .Name, but aria-label still prefers the translation. This can produce a mismatch between visible text and the accessible name. Make aria-label follow the same precedence as the rendered label (or derive it from the same $title variable).

Copilot uses AI. Check for mistakes.
</a>
</li>
{{- end }}
Expand Down
2 changes: 1 addition & 1 deletion layouts/partials/menus/header.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
{{- else }}
class="header-menu__link"
{{- end }}>
{{- or (T (printf "menu.%s" .Identifier)) .Name | safeHTML }}
{{- or .Name (T (printf "menu.%s" .Identifier)) | safeHTML }}
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preferring .Name over the menu.<identifier> translation will break the default localization when menus are generated automatically (e.g. via sectionPagesMenu: main from the docs), since Hugo will populate .Name from the page/section title even if the user didn’t explicitly configure a name. Consider only preferring .Name when it’s explicitly set by the user (or when it differs from the default/identifier), otherwise fall back to the translation first.

Suggested change
{{- or .Name (T (printf "menu.%s" .Identifier)) | safeHTML }}
{{- $i18nKey := printf "menu.%s" .Identifier -}}
{{- $i18nLabel := T $i18nKey -}}
{{- if ne $i18nLabel $i18nKey -}}
{{ $i18nLabel | safeHTML }}
{{- else if .Name -}}
{{ .Name | safeHTML }}
{{- else -}}
{{ .Identifier | safeHTML }}
{{- end }}

Copilot uses AI. Check for mistakes.
</a>
</li>
{{- end }}
Expand Down
13 changes: 13 additions & 0 deletions layouts/partials/menus/menu_label.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{{- $pageRef := .pageRef -}}
{{- $translationKey := .translationKey -}}

{{- range .menus }}
{{- if eq .PageRef $pageRef }}
{{ if ne (lower .Name) .Identifier }}
{{- or .Name (T $translationKey) }}
{{ else }}
{{- or (T $translationKey) .Name }}
{{ end }}
{{- break }}
{{- end }}
{{- end }}
Comment on lines +3 to +13
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

menu_label.html renders nothing if .Site.Menus.main is empty or if no menu item matches the given pageRef, which will make page headings blank (previously these headings always rendered via T <key>). Add a default fallback to the translation (e.g., initialize to T $translationKey and override only when a matching menu item is found).

Suggested change
{{- range .menus }}
{{- if eq .PageRef $pageRef }}
{{ if ne (lower .Name) .Identifier }}
{{- or .Name (T $translationKey) }}
{{ else }}
{{- or (T $translationKey) .Name }}
{{ end }}
{{- break }}
{{- end }}
{{- end }}
{{- $label := T $translationKey -}}
{{- range .menus }}
{{- if eq .PageRef $pageRef }}
{{- if ne (lower .Name) .Identifier }}
{{- $label = or .Name (T $translationKey) -}}
{{- else }}
{{- $label = or (T $translationKey) .Name -}}
{{- end }}
{{- break }}
{{- end }}
{{- end }}
{{- $label -}}

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +13
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are Playwright tests for menu rendering (e.g. tests/secondary-menu.spec.ts), but this change introduces new behavior (name override vs translation, and headings derived from menu config) without coverage. Add/update tests to assert: (1) default menus still render translated labels, and (2) setting name in menu config overrides the translation for that entry.

Copilot uses AI. Check for mistakes.
2 changes: 1 addition & 1 deletion layouts/partials/menus/secondary.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{{- $firstFour := first 4 $input.menu }}
{{- range $index, $item := $firstFour }}
<li>
{{- $title := or (T (printf "menu.%s" $item.Identifier)) $item.Name }}
{{- $title := or $item.Name (T (printf "menu.%s" $item.Identifier)) }}
<a
class="menu-item__link"
href="{{- $item.URL }}"
Expand Down
2 changes: 1 addition & 1 deletion layouts/partials/menus/sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class="sidebar-menu__link"
{{- end }}
aria-label="{{- or (T (printf " menu.%s" .Identifier)) .Name }}">
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aria-label still prefers the translation key (and includes a leading space in printf " menu.%s"), while the visible link text now prefers .Name. This can cause assistive tech to announce a different label than what’s displayed, and the leading space will also break the i18n lookup. Update aria-label to use the same label expression as the link text, and remove the leading space in the translation key format string.

Suggested change
aria-label="{{- or (T (printf " menu.%s" .Identifier)) .Name }}">
aria-label="{{- or .Name (T (printf "menu.%s" .Identifier)) }}">

Copilot uses AI. Check for mistakes.
{{- or (T (printf "menu.%s" .Identifier)) .Name | safeHTML }}
{{- or .Name (T (printf "menu.%s" .Identifier)) | safeHTML }}
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like the header menu, this now prefers .Name over the menu.<identifier> translation. With automatically generated menus (e.g. sectionPagesMenu: main), .Name is populated from page/section titles even when the user didn’t explicitly set name, which can break localization. Consider using the translation by default and only using .Name as an override when explicitly configured / when it differs from the default identifier.

Copilot uses AI. Check for mistakes.
</a>
</li>
{{- end }}
Expand Down
10 changes: 9 additions & 1 deletion layouts/sessions/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,15 @@

<header class="section-container">
<div class="section">
<h1 class="heading heading--1">{{ T "sessions_page.heading" }}</h1>
<h1 class="heading heading--1">
{{- partial "menus/menu_label.html"
(dict
"menus" .Site.Menus.main
"pageRef" "/sessions"
"translationKey" "sessions_page.heading"
)
}}
</h1>
<div class="session-list-filters">
{{- if gt ($sessionsGroupedByDay | len) 1 }}
<article class="session-list-filter">
Expand Down
10 changes: 9 additions & 1 deletion layouts/speakers/list.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
{{ define "main" }}
<section class="speaker-list">
<div class="section">
<h1 class="heading heading--1">{{ T "speakers_page.heading" }}</h1>
<h1 class="heading heading--1">
{{- partial "menus/menu_label.html"
(dict
"menus" .Site.Menus.main
"pageRef" "/speakers"
"translationKey" "speakers_page.heading"
)
}}
</h1>
<menu class="speaker-list__menu">
{{ range .Pages.GroupByParam "lastName" }}
{{ range .Pages.ByParam "firstName" }}
Expand Down