menu: allow menuPageRef, menu.pageRef and sidebarmenus.pageRef to be decorated URLs #1008

meaning: having a query string and fragments
This commit is contained in:
Sören Weber 2025-02-05 08:33:02 +01:00
parent 66bc366c47
commit 14c19bb13c
No known key found for this signature in database
GPG key ID: BEC6D55545451B6D
20 changed files with 311 additions and 212 deletions

View file

@ -111,29 +111,52 @@ summaryLength = 10
name = 'GitHub Repo'
url = 'https://github.com/McShelby/hugo-theme-relearn'
weight = 10
[[languages.en.menu.shortcuts]]
name = 'Showcases'
pageRef = '/showcase'
weight = 20
[[languages.en.menu.shortcuts]]
name = 'Credits'
pageRef = '/more/credits'
weight = 30
[[languages.en.menu.shortcuts]]
pre = '<i class="fa-fw fas fa-tags"></i> '
name = 'Tags'
pageRef = '/tags'
weight = 40
[[languages.en.menu.shortcuts]]
pre = '<i class="fa-fw fas fa-layer-group"></i> '
name = 'Categories'
pageRef = '/categories'
weight = 50
[[languages.en.menu.devshortcuts]]
identifier = 'devshortcuts'
name = 'Dev Shortcuts'
[[languages.en.menu.devshortcuts]]
parent = 'devshortcuts'
pre = '<i class="fa-fw fab fa-hackerrank"></i> '
name = 'Hugo'
url = 'https://gohugo.io/documentation/'
[[languages.en.menu.devshortcuts]]
parent = 'devshortcuts'
pre = '<i class="fa-fw fas fa-puzzle-piece"></i> '
identifier = 'theme'
name = 'Theme'
[[languages.en.menu.devshortcuts.params]]
alwaysopen = true
[[languages.en.menu.devshortcuts]]
parent = 'theme'
pre = '<i class="fa-fw fas fa-gears"></i> '
identifier = 'configoptions'
pageRef = 'configuration/reference'
[[languages.en.menu.devshortcuts]]
parent = 'theme'
pre = '<i class="fa-fw fab fa-markdown"></i> '
identifier = 'frontmatter'
title = 'Front Matter Reference'
pageRef = 'authoring/frontmatter/reference#annotated-front-matter'
# this is ourrr way t' showcase th' multilang settings by
# doing autotrrranlat'n of th' english content; we are
# lazy and don't supporrt furrrther trrranslations; arrr,
@ -153,35 +176,59 @@ summaryLength = 10
#contentDir = 'content/pir'
[languages.pir.params]
landingPageName = '<i class="fa-fw fas home"></i> Arrr! Home'
errorignore = ['.*']
[[languages.pir.menu.shortcuts]]
pre = '<i class="fa-fw fab fa-github"></i> '
name = 'GitHub Repo'
url = 'https://github.com/McShelby/hugo-theme-relearn'
weight = 10
[[languages.pir.menu.shortcuts]]
pre = '<i class="fa-fw fas fa-camera"></i> '
name = 'Showcases'
pageRef = '/showcase'
weight = 20
[[languages.pir.menu.shortcuts]]
name = 'Crrredits'
pageRef = '/more/credits'
weight = 30
[[languages.pir.menu.shortcuts]]
name = 'Arrr! Tags'
pageRef = '/tags'
weight = 40
[[languages.pir.menu.shortcuts]]
pre = '<i class="fa-fw fas fa-layer-group"></i> '
name = 'Categorrries'
pageRef = '/categories'
weight = 50
[[languages.pir.menu.devshortcuts]]
identifier = 'devshortcuts'
name = 'Dev Shortcuts'
[[languages.pir.menu.devshortcuts]]
parent = 'devshortcuts'
pre = '<i class="fa-fw fab fa-hackerrank"></i> '
name = "Cap'n Hugo"
url = 'https://gohugo.io/documentation/'
[[languages.pir.menu.devshortcuts]]
parent = 'devshortcuts'
pre = '<i class="fa-fw fas fa-puzzle-piece"></i> '
identifier = 'theme'
name = "Th' Theme"
[[languages.pir.menu.devshortcuts.params]]
alwaysopen = true
[[languages.pir.menu.devshortcuts]]
parent = 'theme'
pre = '<i class="fa-fw fas fa-gears"></i> '
identifier = 'configoptions'
pageRef = 'configuration/reference'
[[languages.pir.menu.devshortcuts]]
parent = 'theme'
pre = '<i class="fa-fw fab fa-markdown"></i> '
identifier = 'frontmatter'
title = 'Front Matter Reference'
pageRef = 'authoring/frontmatter/reference#annotated-front-matter'
# mounts are only needed in this showcase to access the publicly available screenshots and CHANGELOG;
# remove this section if you don't need further mounts
[module]

View file

@ -435,7 +435,7 @@ highlightWrap = true
# warning is printed. If set to `error` an error message is printed and the build
# is aborted.
# This can be overridden in the page's frontmatter.
include.errorlevel = 'error'
include.errorlevel = 'warning'
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Images
@ -450,7 +450,7 @@ include.errorlevel = 'error'
# aborted.
# Please note that this can not resolve files inside of your `static` directory.
# This can be overridden in the page's frontmatter.
image.errorlevel = 'error'
image.errorlevel = 'warning'
# Image effects.
# See the documentation for how you can even add your own arbitrary effects to
@ -498,7 +498,7 @@ disableExplicitIndexURLs = false
# Please note that with Hugo < 0.123.0 + `uglyURLs=true` this can lead to false
# negatives.
# This can be overridden in the page's frontmatter.
link.errorlevel = 'error'
link.errorlevel = 'warning'
# How to open external links.
# Default: '_blank'
@ -602,4 +602,4 @@ customOpenapiURL = '' # 'https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js'
# aborted.
# Please note that this can not resolve files inside of your `static` directory.
# This can be overridden in the page's frontmatter.
openapi.errorlevel = 'error'
openapi.errorlevel = 'warning'

View file

@ -2,5 +2,5 @@
description = "Setting the behavior of the menus"
title = "Menus"
weight = 2
menuPageRef = '/configuration/sidebar/menus'
menuPageRef = '/configuration/sidebar/menus#expand-state-of-submenus'
+++

View file

@ -2,5 +2,5 @@
description = "Setting the behavior of the menus"
title = "Menus"
weight = 2
menuPageRef = '/configuration/sidebar/menus'
menuPageRef = '/configuration/sidebar/menus#expand-state-of-submenus'
+++

View file

@ -5,6 +5,14 @@ hidden = true
title = "Development"
type = "chapter"
weight = 5
[[cascade]]
[cascade.params]
[[cascade.params.sidebarmenus]]
identifier = 'blog'
type = 'page'
[[cascade.params.sidebarmenus]]
identifier = 'devshortcuts'
type = 'menu'
+++
This chapter contains information only needed for development and maintaining the theme.

View file

@ -5,5 +5,13 @@ hidden = true
title = "Development"
type = "chapter"
weight = 5
[[cascade]]
[cascade.params]
[[cascade.params.sidebarmenus]]
identifier = 'blog'
type = 'page'
[[cascade.params.sidebarmenus]]
identifier = 'devshortcuts'
type = 'menu'
+++
{{< piratify >}}

View file

@ -7,12 +7,12 @@
{{- $url = replace .Permalink site.BaseURL "/" }}
{{- end }}
{{- $url = replace $url "//" "/" }}
{{- with site.Home.GetPage $url }}
{{- with site.GetPage $url }}
{{- /* if defaultContentLanguageInSubdir=false we are ending here for home page of the default language */}}
{{- $url = partial "permalink.gotmpl" (dict "to" .) }}
{{- else }}
{{- $url_alt := replaceRE "^/[^/]*(/.*)" "${1}" $url }}
{{- with site.Home.GetPage $url_alt }}
{{- with site.GetPage $url_alt }}
{{- /* if defaultContentLanguageInSubdir=true we are ending here for home page */}}
{{- $url = partial "permalink.gotmpl" (dict "to" .) }}
{{- else }}

View file

@ -0,0 +1,57 @@
{{- $href := partial "permalink.gotmpl" (dict "to" .linkPage) }}
{{- $silent := .silent | default false }}
{{- $hideFilepath := .hideFilepath | default false }}
{{- $u := urls.Parse .url }}
{{- with $u.RawQuery }}
{{- $href = printf "%s?%s" $href . }}
{{- end }}
{{- with $u.Fragment }}
{{- $href = printf "%s#%s" $href . }}
{{- if not $silent }}
{{- partial "inline/validate-fragment.html" (dict "origPage" $.page "page" $.linkPage "parsedURL" $u "url" $.url "param" $.param "hideFilepath" $hideFilepath) }}
{{- end }}
{{- end }}
{{- return $href }}
{{- define "partials/inline/validate-fragment.html" }}
{{- /*
Validates the fragment portion of a link destination.
*/}}
{{- /* Initialize. */}}
{{- $errorLevel := .errorLevel }}
{{- $origPage := .origPage }}
{{- $p := .page }}
{{- $url := .url }}
{{- $u := .parsedURL }}
{{- $param := .param }}
{{- $hideFilepath := .hideFilepath }}
{{- /* Validate. */}}
{{- with $u.Fragment }}
{{- if $p.Fragments.Identifiers.Contains . }}
{{- if gt ($p.Fragments.Identifiers.Count .) 1 }}
{{- $filepath := "[virtual file]" }}{{ with and $origPage $origPage.File $origPage.File.Filename }}{{ $filepath = . }}{{ end }}
{{- $msg := printf "%q: duplicate heading ID %q found" $filepath . }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" $url "page" $origPage "param" $param "msg" $msg) }}
{{- end }}
{{- else }}
{{- /* Determine target path for warning and error message. */}}
{{- $targetPath := "" }}
{{- with $p.File }}
{{- $targetPath = .Path }}
{{- else }}
{{- $targetPath = .Path }}
{{- end }}
{{- $filepath := "[virtual file]" }}{{ with and $origPage $origPage.File $origPage.File.Filename }}{{ $filepath = . }}{{ end }}
{{- $msg := printf "heading ID %q not found" . }}
{{- if not $hideFilepath }}
{{- $msg = printf "%q: %s" $filepath $msg }}
{{- end }}
{{- if or $hideFilepath (ne $origPage $p) }}
{{- $msg = printf "%s in %q" $msg $targetPath }}
{{- end }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" $url "page" $origPage "param" $param "msg" $msg) }}
{{- end }}
{{- end }}
{{- end }}

View file

@ -0,0 +1,48 @@
{{- $page := .page }}
{{- $linkPage := "" }}
{{- $u := urls.Parse .url }}
{{- $path := strings.TrimPrefix "./" $u.Path }}
{{- $searchLocal := .searchLocal | default true }}
{{- $searchGlobal := .searchGlobal | default true }}
{{- $searchPage := .searchPage | default true }}
{{- $searchResource := .searchResource | default true }}
{{- if $path }}
{{- with or
(and $searchLocal $searchPage ($page.Page.GetPage $path))
(and $searchLocal $searchPage ($page.Page.GetPage (strings.TrimRight "/" $path)))
(and $searchGlobal $searchPage (site.GetPage $path))
(and $searchGlobal $searchPage (site.GetPage (strings.TrimRight "/" $path)))
(and $searchLocal $searchResource ($page.Page.Resources.Get $path))
(and $searchGlobal $searchResource (resources.Get $path))
}}
{{- $linkPage = . }}
{{- else }}
{{- /* is it a link into another translation? */}}
{{- if strings.HasPrefix $path "/" }}
{{- range $page.AllTranslations }}
{{- $lang := .Language.Lang }}
{{- $prefix := printf "/%s" $lang }}
{{- $suffix := strings.TrimPrefix $prefix $path | default "/" }}
{{- /* with the second check we check if the prefix was finished;
eg. /pir/index.html vs. /pirate/index.html, were the latter is
an external address outside of this site */}}
{{- if and (strings.HasPrefix $path $prefix) (strings.HasPrefix $suffix "/") }}
{{- with or
(and $searchLocal $searchPage (.GetPage $suffix))
(and $searchLocal $searchPage (.GetPage (strings.TrimRight "/" $suffix)))
(and $searchGlobal $searchPage (site.GetPage $path))
(and $searchGlobal $searchPage (site.GetPage (strings.TrimRight "/" $path)))
(and $searchLocal $searchResource (.Resources.Get $suffix))
(and $searchGlobal $searchResource (resources.Get $suffix))
}}
{{- $linkPage = . }}
{{- break }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- else }}
{{- $linkPage = $page.Page }}
{{- end }}
{{- return $linkPage }}

View file

@ -0,0 +1,5 @@
{{- $linkPage := "" }}
{{- with and . .menu }}
{{- $linkPage = partial "_relearn/refPage.gotmpl" (dict "page" $.page "pageRef" .PageRef "refPage" .Page) }}
{{- end }}
{{- return $linkPage }}

View file

@ -0,0 +1,25 @@
{{- $url := "" }}
{{- /* because Hugo can not resolve a pageRef if it contains URL query params or
fragments, we simply don't access the .Page here */}}
{{- with and . .menu }}
{{- if .PageRef }}
{{- $url = .PageRef }}
{{- $linkPage := partial "_relearn/refPage.gotmpl" (dict "page" $.page "pageRef" .PageRef "refPage" .Page) }}
{{- if $linkPage }}
{{- $url = partial "_relearn/decoratedLink.gotmpl" (dict "url" .PageRef "page" $.page "linkPage" $linkPage "param" "link" "hideFilepath" true) }}
{{- else }}
{{- $msg := printf "config option 'pageRef' %q for 'menu' entry %q is not a page or a resource" .PageRef (or .KeyName .Identifier .Name .Title) }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" .PageRef "page" $.page "param" "link" "msg" $msg) }}
{{- end }}
{{- else if .URL }}
{{- $url = .URL | relLangURL }}
{{- $u := urls.Parse $url }}
{{- if $u.IsAbs }}
{{- partialCached "_relearn/urlExists.gotmpl" (dict "url" $url "page" $.page "type" "menu link") $u.String }}
{{- else }}
{{- $msg := printf "config option 'url' %q for 'menu' entry %q is a local URL; if it references a page or a resource use 'pageRef' instead" .URL (or .KeyName .Identifier .Name .Title) }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" .URL "page" $.page "param" "link" "msg" $msg) }}
{{- end }}
{{- end }}
{{- end }}
{{- return $url }}

View file

@ -0,0 +1,10 @@
{{- $title := "" }}
{{- with and . .menu }}
{{- $pagetitle := "" }}
{{- $menuPage := partial "_relearn/menuPage.gotmpl" (dict "page" $.page "menu" .) }}
{{- with $menuPage }}
{{- $pagetitle = or .LinkTitle .Title }}
{{- end }}
{{- $title = or .Title $pagetitle (.Name | safeHTML) (.Identifier | safeHTML) }}
{{- end }}
{{- return $title }}

View file

@ -0,0 +1,11 @@
{{- $linkPage := "" }}
{{- /* because Hugo can not resolve a pageRef if it contains URL query params or
fragments, we do it ourself if we detect such a case */}}
{{- with .refPage }}
{{- $linkPage = . }}
{{- else }}
{{- with .pageRef }}
{{- $linkPage = partial "_relearn/linkPage.gotmpl" (dict "url" . "page" $.page "searchLocal" false) }}
{{- end }}
{{- end }}
{{- return $linkPage }}

View file

@ -1,20 +1,23 @@
{{- $pageParam := index .page.Params .param }}
{{- $siteParam := index .page.Site.Params .param }}
{{- $siteParam := index site.Params .param }}
{{- $applyErrorIgnore := .applyErrorIgnore | default true }}
{{- $errorlevel := or (and $pageParam $pageParam.errorlevel) (and $siteParam $siteParam.errorlevel) }}
{{- $errorignore := slice | append (.page.Params.errorignore | default slice ) | append (.page.Site.Params.errorignore | default slice ) }}
{{- if and (eq $errorlevel "warning") (partial "inline/show-error" (dict "errorignore" $errorignore "url" .url)) }}
{{- $errorignore := slice | append (.page.Params.errorignore | default slice ) | append (site.Params.errorignore | default slice ) }}
{{- if and (eq $errorlevel "warning") (partial "inline/show-error" (dict "errorignore" $errorignore "url" .url "applyErrorIgnore" $applyErrorIgnore)) }}
{{- warnf .msg }}
{{- else if and (eq $errorlevel "error") (partial "inline/show-error" (dict "errorignore" $errorignore "url" .url)) }}
{{- else if and (eq $errorlevel "error") (partial "inline/show-error" (dict "errorignore" $errorignore "url" .url "applyErrorIgnore" $applyErrorIgnore)) }}
{{- errorf .msg }}
{{- end }}
{{- define "partials/inline/show-error" }}
{{- $ret := true }}
{{- if .applyErrorIgnore }}
{{- range .errorignore }}
{{- if findRE . $.url 1 }}
{{- $ret = false }}
{{- break }}
{{- end }}
{{- end }}
{{- end }}
{{- return $ret }}
{{- end }}

View file

@ -99,12 +99,21 @@
</div>
</div>
</aside>
{{- define "partials/inline/page-tree" }}
{{- $currentNode := .currentnode }}
{{- $config := .config }}
{{- $showvisitedlinks := .showvisitedlinks }}
<div id="R-shortcutmenu-{{ $config.identifier }}" class="R-sidebarmenu">
{{- with site.Home.GetPage ($config.pageRef | default "") }}
{{- $root := site.Home }}
{{- if $config.pageRef }}
{{- $root = partial "_relearn/refPage.gotmpl" (dict "page" $currentNode "pageRef" $config.pageRef) }}
{{- if not $root }}
{{- $msg := printf "config option 'pageRef' %q for 'sidebarmenus' %q is not a page or a resource" $config.pageRef $config.identifier }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" $config.pageRef "page" $currentNode "param" "link" "msg" $msg) }}
{{- end }}
{{- end }}
{{- with $root }}
{{- $entry := . }}
{{- $entries := partialCached "_relearn/pages.gotmpl" (dict "page" $entry) $entry.Path }}
{{- $title := "" }}
@ -134,8 +143,6 @@
{{- end }}
</ul>
</div>
{{- else }}
{{- warnf "WARNING: page '%s' not found for sidebar menu '%s'" ($config.pageRef | default "") $config.identifier }}
{{- end }}
{{- end }}
{{- define "partials/inline/page-walker" }}
@ -163,18 +170,18 @@
{{- $url := partial "permalink.gotmpl" (dict "to" .) }}
{{- $isCrosslink := false }}
{{- $target := "" }}
{{- $errorlevel := or $currentNode.Params.link.errorlevel $currentNode.Site.Params.link.errorlevel }}
{{- if .Params.menuPageRef }}
{{- with site.Home.GetPage (.Params.menuPageRef) }}
{{- $url = partial "permalink.gotmpl" (dict "to" .) }}
{{- $isCrosslink = true }}
{{- $url = .Params.menuPageRef }}
{{- $linkPage := partial "_relearn/refPage.gotmpl" (dict "page" . "pageRef" .Params.menuPageRef) }}
{{- if $linkPage }}
{{- $url = partial "_relearn/decoratedLink.gotmpl" (dict "url" .Params.menuPageRef "page" . "linkPage" $linkPage "param" "link" "silent" true) }}
{{- end }}
{{- else if .Params.menuUrl }}
{{- $url = .Params.menuUrl }}
{{- $isCrosslink = true }}
{{- $url = .Params.menuUrl | relLangURL }}
{{- $u := urls.Parse $url }}
{{- if $u.IsAbs }}
{{- partialCached "_relearn/urlExists.gotmpl" (dict "url" $url "page" $currentNode "type" "menu link") $u.String }}
{{- $target = "_blank" }}
{{- if isset site.Params "externallinktarget" }}
{{- $target = site.Params.externalLinkTarget }}
@ -193,7 +200,7 @@
{{- $isOpen := or $currentAlwaysopen $isSelf $isAncestor }}
<li class="{{if $isActive }}active {{end}}{{if (or $isSelf $isAncestor) }}parent {{end}}{{if $isHidden }}hidden {{end}}{{if not $url }}headless {{end}}{{if $currentAlwaysopen}}alwaysopen {{end}}" data-nav-id="{{ $url }}">
{{- if $isCollapsible }}<input type="checkbox" id="R-section-{{ $entryId }}" aria-controls="R-subsections-{{ $entryId }}"{{ if $isOpen }} checked{{ end }}><label for="R-section-{{ $entryId }}"><i class="fa-fw fas fa-chevron-right"></i><span class="a11y-only">{{ T "Submenu" $title }}</span></label>{{ end }}
{{- if $url }}<a class="padding" href="{{ $url }}"{{ if gt (len $target) 0 }} target="{{ $target }}"{{ end }}>{{ else }}<span class="padding">{{ end }}
{{- if $url }}<a class="padding" href="{{ $url }}"{{ if $target }} target="{{ $target }}"{{ end }}>{{ else }}<span class="padding">{{ end }}
{{- $pre }}{{ $title }}{{ $post }}
{{- if $url }}{{ if $showvisitedlinks }}<i class="fa-fw fas fa-check read-icon"></i>{{ end }}</a>{{ else }}</span>{{ end }}<ul id="R-subsections-{{ $entryId }}" class="collapsible-menu">
{{- $defaultAlwaysopen := site.Params.alwaysopen | default true }}
@ -211,36 +218,37 @@
{{- end }}</ul></li>
{{- else if $url }}
<li class="{{if $isActive }}active {{end}}{{if $isHidden }}hidden {{end}}{{if not $url }}headless {{end}}{{if $isCrosslink }}crosslink {{end}}" data-nav-id="{{ $url }}">
{{- if $url }}<a class="padding" href="{{ $url }}"{{ if gt (len $target) 0 }} target="{{ $target }}"{{ end }}>{{ else }}<span class="padding">{{ end }}
{{- if $url }}<a class="padding" href="{{ $url }}"{{ if $target }} target="{{ $target }}"{{ end }}>{{ else }}<span class="padding">{{ end }}
{{- $pre }}{{ $title }}{{ $post }}
{{- if $url }}{{ if $showvisitedlinks }}<i class="fa-fw fas fa-check read-icon"></i>{{ end }}</a>{{ else }}</span>{{ end }}</li>
{{- end }}
{{- end }}
{{- end }}
{{- define "partials/inline/menu-tree" }}
{{- $currentNode := .currentnode }}
{{- $config := .config }}
{{- $showvisitedlinks := .showvisitedlinks }}
{{- with index site.Menus $config.identifier }}
<div id="R-shortcutmenu-{{ $config.identifier }}" class="R-sidebarmenu">
{{- $entry := "" }}
{{- $topLevelMenu := "" }}
{{- $topLevelPage := "" }}
{{- $entries := . }}
{{- if eq (len $entries) 1 }}
{{- with index $entries 0 }}
{{- if not (partial "menupermalink.gotmpl" (dict "page" $currentNode "menu" .)) }}
{{- with and (eq (len $entries) 1) (index $entries 0) }}
{{- if and (not .PageRef) (not .URL) }}
{{- /* because in Hugo menus can not have parameter but menu entries can,
we can flag a single top level menu entry as a container; this container
entry carrys just meta information and parameter, uses its children
to build the "real" menu, and has no own `url` or `pageRef` */}}
{{- $entry = . }}
{{- $topLevelMenu = . }}
{{- $topLevelPage = partial "_relearn/menuPage.gotmpl" (dict "page" $currentNode "menu" $topLevelMenu) }}
{{- $entries = .Children }}
{{- end }}
{{- end }}
{{- end }}
{{- $title := "" }}
{{- if not ($config.disableTitle | default false) }}
{{- if $entry }}
{{- $title = partial "menutitle.gotmpl" $entry }}
{{- if $topLevelMenu }}
{{- $title = partial "_relearn/menuTitle.gotmpl" (dict "page" $currentNode "menu" $topLevelMenu) }}
{{- else if eq $config.identifier "shortcuts" }}
{{- if not site.Params.DisableShortcutsTitle }}
{{- $title = T (print $config.identifier "-menuTitle") }}
@ -257,16 +265,17 @@
{{- $classes = "enlarge morespace " }}
{{- end }}
<ul class="{{ $classes }}collapsible-menu">
{{- $root := or $entry site }}
{{- $root := or $topLevelMenu site }}
{{- $defaultAlwaysopen := site.Params.alwaysopen | default false }}
{{- range $entries }}
{{- $isSubSelf := eq .Page $currentNode }}
{{- $entriesPage := partial "_relearn/menuPage.gotmpl" (dict "page" $currentNode "menu" .) }}
{{- $isSubSelf := eq $entriesPage $currentNode }}
{{- $isSubAncestor := and (not $isSubSelf) ($currentNode.HasMenuCurrent .Menu .) }}
{{- $isSubHidden := or (.Params.hidden) (eq (partial "menutitle.gotmpl" .) "") }}
{{- $isSubHidden := or (.Params.hidden) (eq (partial "_relearn/menuTitle.gotmpl" (dict "page" $currentNode "menu" .)) "") }}
{{- $isSubCollapsible := .Params.collapsibleMenu | default $root.Params.collapsibleMenu | default site.Params.collapsibleMenu }}
{{- if or $isSubSelf $isSubAncestor }}
{{- partial "partials/inline/menu-walker" (dict "menu" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen "isSelf" $isSubSelf "isAncestor" $isSubAncestor "isHidden" $isSubHidden "root" $root) }}
{{- else if and (not $isSubHidden) (or $isSubCollapsible (not (partial "menupermalink.gotmpl" (dict "page" $currentNode "menu" $entry))) (and $entry (eq $entry.Page $currentNode)) (and $entry ($currentNode.HasMenuCurrent $entry.Menu $entry))) }}
{{- else if and (not $isSubHidden) (or $isSubCollapsible (not (partial "_relearn/menuPermalink.gotmpl" (dict "page" $currentNode "menu" $topLevelMenu))) (eq $topLevelPage $currentNode) (and $topLevelMenu ($currentNode.HasMenuCurrent $topLevelMenu.Menu $topLevelMenu))) }}
{{- $id := md5 (print .) }}
{{- partialCached "partials/inline/menu-walker" (dict "menu" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen "isSelf" $isSubSelf "isAncestor" $isSubAncestor "isHidden" $isSubHidden "root" $root) $id }}
{{- end }}
@ -275,7 +284,8 @@
</div>
{{- else }}
{{ if ne $config.identifier "shortcuts" }}
{{- warnf "WARNING: menu '%s' not found for sidebar menu '%s'" $config.identifier $config.identifier }}
{{- $msg := printf "config option 'identifier' for 'sidebarmenus' %q is not a menu" $config.identifier }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" $config.pageRef "page" $currentNode "param" "link" "msg" $msg "applyErrorIgnore" false) }}
{{- end }}
{{- end }}
{{- end }}
@ -289,20 +299,22 @@
{{- $root := .root }}
{{- with .menu }}
{{- $isActive := $isSelf }}
{{- $entry := . }}
{{- $entryMenu := . }}
{{- $entryPage := partial "_relearn/menuPage.gotmpl" (dict "page" $currentNode "menu" $entryMenu) }}
{{- $entries := .Children }}
{{- $hasVisibleChildren := false }}
{{- range $entries }}
{{- $isSubSelf := eq .Page $currentNode }}
{{- $entriesPage := partial "_relearn/menuPage.gotmpl" (dict "page" $currentNode "menu" .) }}
{{- $isSubSelf := eq $entriesPage $currentNode }}
{{- $isSubAncestor := and (not $isSubSelf) ($currentNode.HasMenuCurrent .Menu .) }}
{{- $isSubHidden := or (.Params.hidden) (eq (partial "menutitle.gotmpl" .) "") }}
{{- $isSubHidden := or (.Params.hidden) (eq (partial "_relearn/menuTitle.gotmpl" (dict "page" $currentNode "menu" .)) "") }}
{{- if or $isSubAncestor $isSubSelf (not $isSubHidden) }}
{{- $hasVisibleChildren = true }}
{{- break }}
{{- end }}
{{- end }}
{{- $title := partial "menutitle.gotmpl" . }}
{{- $url := partial "menupermalink.gotmpl" (dict "page" $currentNode "menu" .) }}
{{- $title := partial "_relearn/menuTitle.gotmpl" (dict "page" $currentNode "menu" .) }}
{{- $url := partial "_relearn/menuPermalink.gotmpl" (dict "page" $currentNode "menu" .) }}
{{- $target := "" }}
{{- $u := urls.Parse $url }}
{{- if $u.IsAbs }}
@ -313,7 +325,7 @@
{{- end }}
{{- $pre := .Pre }}
{{- $post := .Post }}
{{- with .Page }}
{{- with $entryPage }}
{{- $pre = or $pre (partial "menu-pre.html" .) }}
{{- $post = or $post (partial "menu-post.html" .) }}
{{- end }}
@ -323,7 +335,7 @@
{{- if and (not $url) (not $isCollapsible) }}
{{- $currentAlwaysopen = true }}
{{- end }}
{{- $entryId := md5 (print .) }}
{{- $entryId := md5 (print $entryMenu) }}
{{- $isOpen := or $currentAlwaysopen $isSelf $isAncestor }}
<li class="{{if $isActive }}active {{end}}{{if (or $isSelf $isAncestor) }}parent {{end}}{{if $isHidden }}hidden {{end}}{{if not $url }}headless {{end}}{{if $currentAlwaysopen}}alwaysopen {{end}}" data-nav-id="{{ $url }}">
{{- if $isCollapsible }}<input type="checkbox" id="R-section-{{ $entryId }}" aria-controls="R-subsections-{{ $entryId }}"{{ if $isOpen }} checked{{ end }}><label for="R-section-{{ $entryId }}"><i class="fa-fw fas fa-chevron-right"></i><span class="a11y-only">{{ T "Submenu" $title }}</span></label>{{ end }}
@ -332,13 +344,14 @@
{{- if $url }}{{ if $showvisitedlinks }}<i class="fa-fw fas fa-check read-icon"></i>{{ end }}</a>{{ else }}</span>{{ end }}<ul id="R-subsections-{{ $entryId }}" class="collapsible-menu">
{{- $defaultAlwaysopen := site.Params.alwaysopen | default true }}
{{- range $entries }}
{{- $isSubSelf := eq .Page $currentNode }}
{{- $entriesPage := partial "_relearn/menuPage.gotmpl" (dict "page" $currentNode "menu" .) }}
{{- $isSubSelf := eq $entriesPage $currentNode }}
{{- $isSubAncestor := and (not $isSubSelf) ($currentNode.HasMenuCurrent .Menu .) }}
{{- $isSubHidden := or (.Params.hidden) (eq (partial "menutitle.gotmpl" .) "") }}
{{- $isSubHidden := or (.Params.hidden) (eq (partial "_relearn/menuTitle.gotmpl" (dict "page" $currentNode "menu" .)) "") }}
{{- $isSubCollapsible := .Params.collapsibleMenu | default $root.Params.collapsibleMenu | default site.Params.collapsibleMenu }}
{{- if or $isSubSelf $isSubAncestor }}
{{- partial "partials/inline/menu-walker" (dict "menu" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen "isSelf" $isSubSelf "isAncestor" $isSubAncestor "isHidden" $isSubHidden "root" $root) }}
{{- else if and (not $isSubHidden) (or $isSubCollapsible (not (partial "menupermalink.gotmpl" (dict "page" $currentNode "menu" $entry))) (eq $entry.Page $currentNode) ($currentNode.HasMenuCurrent $entry.Menu $entry)) }}
{{- else if and (not $isSubHidden) (or $isSubCollapsible (not (partial "_relearn/menuPermalink.gotmpl" (dict "page" $currentNode "menu" $entryMenu))) (eq $entryPage $currentNode) ($currentNode.HasMenuCurrent $entryMenu.Menu $entryMenu)) }}
{{- $id := md5 (print .) }}
{{- partialCached "partials/inline/menu-walker" (dict "menu" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen "isSelf" $isSubSelf "isAncestor" $isSubAncestor "isHidden" $isSubHidden "root" $root) $id }}
{{- end }}

View file

@ -1,25 +0,0 @@
{{- $url := "" }}
{{- with .menu }}
{{- $filepath := "[virtual file]" }}{{ with and $.page $.page.File $.page.File.Filename }}{{ $filepath = . }}{{ end }}
{{- $errorlevel := or $.page.Params.link.errorlevel $.page.Site.Params.link.errorlevel }}
{{- if .PageRef }}
{{- with .Page }}
{{- $url = partial "permalink.gotmpl" (dict "to" .) }}
{{- else }}
{{- $msg := printf "%q: config menu link '%s' is not a page" $filepath .PageRef }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" .PageRef "page" $.page "param" "link" "msg" $msg) }}
{{- end }}
{{- else }}
{{- with .URL }}
{{- $url = . | relLangURL }}
{{- $u := urls.Parse $url }}
{{- if $u.IsAbs }}
{{- partialCached "_relearn/urlExists.gotmpl" (dict "url" $url "page" $.page "type" "menu link") $u.String }}
{{- else }}
{{- $msg := printf "%q: config menu link '%s' given by 'URL' is not verified; if it is a page use 'PageRef' instead" $filepath . }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" . "page" $.page "param" "link" "msg" $msg) }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- return $url }}

View file

@ -1,12 +0,0 @@
{{- $title := "" }}
{{- with . }}
{{- $pagetitle := "" }}
{{- with .Page }}
{{- $pagetitle = or .LinkTitle .Title }}
{{- end }}
{{- $title = or .Title (.Name | safeHTML) }}
{{- if and (eq $pagetitle .Title) (ne .Name .Title) }}
{{- $title = (.Name | safeHTML) }}
{{- end }}
{{- end }}
{{- return $title }}

View file

@ -18,19 +18,21 @@
{{- $filepath := "[virtual file]" }}{{ with and .File .File.Filename }}{{ $filepath = . }}{{ end }}
{{- $errorlevel := or .Params.link.errorlevel .Site.Params.link.errorlevel }}
{{- if .Params.menuPageRef }}
{{- with site.Home.GetPage (.Params.menuPageRef) }}
{{- $url = partial "permalink.gotmpl" (dict "to" .) }}
{{- $url = .Params.menuPageRef }}
{{- $linkPage := partial "_relearn/refPage.gotmpl" (dict "page" . "pageRef" .Params.menuPageRef) }}
{{- if $linkPage }}
{{- $url = partial "_relearn/decoratedLink.gotmpl" (dict "url" .Params.menuPageRef "page" . "linkPage" $linkPage "param" "link") }}
{{- else }}
{{- $msg := printf "%q: front matter crosslink '%s' is not a page" $filepath .Params.menuPageRef }}
{{- $msg := printf "%q: front matter 'menuPageRef' %q is not a page or a resource" $filepath .Params.menuPageRef }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" .Params.menuPageRef "page" . "param" "link" "msg" $msg) }}
{{- end }}
{{- else if .Params.menuUrl }}
{{- $url = .Params.menuUrl }}
{{- $url = .Params.menuUrl | relLangURL }}
{{- $u := urls.Parse $url }}
{{- if $u.IsAbs }}
{{- partialCached "_relearn/urlExists.gotmpl" (dict "url" $url "page" . "type" "menu link") $u.String }}
{{- else }}
{{- $msg := printf "%q: front matter crosslink '%s' given by 'menuURL' is not verified; if it is a page use 'menuPageRef' instead" $filepath .Params.menuUrl }}
{{- $msg := printf "%q: front matter 'menuUrl' is a local URL; if it references a page or a resource use 'menuPageRef' instead" $filepath .Params.menuUrl }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" .Params.menuUrl "page" . "param" "link" "msg" $msg) }}
{{- end }}
{{- end }}

View file

@ -9,7 +9,7 @@
{{- $filepath := "[virtual file]" }}{{ with and $page $page.File $page.File.Filename }}{{ $filepath = . }}{{ end }}
{{- warnf "%q: WARNING you must call the ref / relref shortcode with '%% %%' instead of '< >' to work correctly for the anchor target attribute" $filepath }}
{{- end }}
{{- $attributes := dict }}
{{- $attributes := .attributes | default dict }}
{{- $title := .title | default "" }}
{{- $title = trim $title " " }}
{{- $attributes = $attributes | merge (dict "title" ($title | transform.HTMLEscape)) }}
@ -26,62 +26,11 @@
{{- end }}
{{- $attributes = $attributes | merge (dict "target" $target) }}
{{- else }}
{{- $linkPage := "" }}
{{- $path := strings.TrimPrefix "./" $u.Path }}
{{- if $path }}
{{- with or
($page.Page.GetPage $path)
($page.Page.GetPage (strings.TrimRight "/" $path))
($page.Page.Resources.Get $path)
(resources.Get $path)
}}
{{- $linkPage = . }}
{{- else }}
{{- /* is it a link into another translation? */}}
{{- if strings.HasPrefix $path "/" }}
{{- range $page.AllTranslations }}
{{- $lang := .Language.Lang }}
{{- $prefix := printf "/%s" $lang }}
{{- $suffix := strings.TrimPrefix $prefix $path | default "/" }}
{{- /* with the second check we check if the prefix was finished;
eg. /pir/index.html vs. /pirate/index.html, were the latter is
an external address outside of this site */}}
{{- if and (strings.HasPrefix $path $prefix) (strings.HasPrefix $suffix "/") }}
{{- with or
(.GetPage $suffix)
(.GetPage (strings.TrimRight "/" $suffix))
(.Resources.Get $suffix)
(resources.Get $suffix)
}}
{{- $linkPage = . }}
{{- break }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- else }}
{{- $linkPage = $page.Page }}
{{- end }}
{{- $filepath := "[virtual file]" }}{{ with and $page $page.File $page.File.Filename }}{{ $filepath = . }}{{ end }}
{{- $errorlevel := or $page.Params.link.errorlevel $page.Site.Params.link.errorlevel }}
{{- $linkPage := partial "_relearn/linkPage.gotmpl" (dict "url" $.url "page" $page) }}
{{- with $linkPage }}
{{- $href = partial "permalink.gotmpl" (dict "to" .) }}
{{- with $u.RawQuery }}
{{- $href = printf "%s?%s" $href . }}
{{- end }}
{{- with $u.Fragment }}
{{- $ctx := dict
"contentPath" $filepath
"errorLevel" $errorlevel
"page" $linkPage
"parsedURL" $u
"renderHookName" "link"
}}
{{- partial "inline/validate-fragment.html" $ctx }}
{{- $href = printf "%s#%s" $href . }}
{{- end }}
{{- $href = partial "_relearn/decoratedLink.gotmpl" (dict "url" $.url "page" $page "linkPage" . "param" "link") }}
{{- else }}
{{- $filepath := "[virtual file]" }}{{ with and $page $page.File $page.File.Filename }}{{ $filepath = . }}{{ end }}
{{- $msg := printf "%q: link '%s' is not a page or a resource" $filepath .url }}
{{- partial "_relearn/urlErrorReport.gotmpl" (dict "url" .url "page" $page "param" "link" "msg" $msg) }}
{{- end }}
@ -93,53 +42,3 @@
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
{{- end }}
{{- end }}>{{ $content | safeHTML }}</a>
{{- define "partials/inline/validate-fragment.html" }}
{{- /*
Validates the fragment portion of a link destination.
@context {string} contentPath The page containing the link.
@context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error.
@context {page} page The page corresponding to the link destination
@context {struct} parsedURL The link destination parsed by urls.Parse.
@context {string} renderHookName The name of the render hook.
*/}}
{{- /* Initialize. */}}
{{- $contentPath := .contentPath }}
{{- $errorLevel := .errorLevel }}
{{- $p := .page }}
{{- $u := .parsedURL }}
{{- $renderHookName := .renderHookName }}
{{- /* Validate. */}}
{{- with $u.Fragment }}
{{- if $p.Fragments.Identifiers.Contains . }}
{{- if gt ($p.Fragments.Identifiers.Count .) 1 }}
{{- $msg := printf "%q: duplicate heading ID %q found" $contentPath . }}
{{- if eq $errorLevel "warning" }}
{{- warnf $msg }}
{{- else if eq $errorLevel "error" }}
{{- errorf $msg }}
{{- end }}
{{- end }}
{{- else }}
{{- /* Determine target path for warning and error message. */}}
{{- $targetPath := "" }}
{{- with $p.File }}
{{- $targetPath = .Path }}
{{- else }}
{{- $targetPath = .Path }}
{{- end }}
{{- $msg := printf "%q: heading ID %q not found in %q" $contentPath . $targetPath }}
{{- if eq $targetPath $contentPath }}
{{- $msg := printf "%q: heading ID %q not found" $contentPath . }}
{{- end }}
{{- if eq $errorLevel "warning" }}
{{- warnf $msg }}
{{- else if eq $errorLevel "error" }}
{{- errorf $msg }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View file

@ -1 +1 @@
7.3.2+8b70bdf31acd361aacf17a0e775504551af67b83
7.3.2+66bc366c4727a958f3873f409550daa36932c03f