Files
FixIt/layouts/_partials/base/header.html
T
Cell 658f03d1e5 refactor(params)!: flatten [params.page] to [params], snake_case keys, more page-level params support (#805)
* refactor(params)!: snake_case config + eliminate params.page + use .Param

BREAKING CHANGE: All params keys renamed from camelCase to snake_case,
[params.page] section eliminated (moved to [params] level), and users
must update their hugo.toml and front matter accordingly.

Key changes:
- All camelCase config keys → snake_case (e.g., defaultTheme → default_theme)
- [params.page] flat keys and sub-sections moved to [params] level
- Removed function/params.html (manual merge), replaced with Hugo .Param
- New function/param.html partial for page-level section params with
  shorthand boolean support and site defaults merging
- New function/camel-case.html for string conversion
- snake2camel.html renamed to camel-case-keys.html
- New function/get-cover.html for cover image resolution
- Deprecation warnings in detection-deprecated.html for old config keys
- Front matter only params (subtitle, featured_image, password, repost,
  weight, message) use .Params.xxx instead of .Param
- Page-level sections use param.html partial
- Simplified patch.html (siteTime only) and init/index.html

Refs: camel-case-keys.html#29 (planned v1.0 breaking change)

* refactor(params)!: move params.link to page-level, simplify link guard

- Move [params.link] and [params.link.guard] to page-level section
- link.html: .Page optional, use param.html when available for
  page-level override, fall back to site config without .Page
- Remove $guardConfig variable, use $config.guard directly
- Remove unnecessary .Page from callers that don't need page override
- friends.html: use param.html for link guard instead of link_guard

* refactor(params)!: move image/codeblock/json_viewer/filetree to page-level

- Move [params.image], [params.codeblock], [params.json_viewer],
  [params.filetree] to page-level sub-sections
- Templates use param.html for merged config (page override + site defaults)
- image.html: .Page optional, falls back to site config without .Page
- Add v1- prefix to all deprecation warnidf IDs
- Fix camelCase key access in image.html (blackList, cacheRemote)
- Fix Hugo-lowered camelCase keys in code-block-wrapper.html
- Add deprecation warnings for codeblock camelCase Markdown attributes
- Add deprecation warnings for file-tree camelCase Markdown attributes
- Update render-codeblock-toggle.html for snake_case attribute names

* style: standardize @param comment style across all HTML templates

- PascalCase types: {string} → {String}, {boolean} → {Boolean},
  {int} → {Int}, {map} → {Map}, {array} → {Array}
- Add missing ` - ` separator between param name and description
- Remove extra alignment spaces between type and param name

* refactor(params)!: move params.mermaid to page-level, extract gen/ templates

- Move [params.mermaid] to page-level sub-sections
- Mermaid config injected into window.config (per-page override support)
- mermaid.ts reads config from window.config.mermaid instead of parameter
- Create _partials/gen/ directory for JS content generators
- Move mermaid-bootstrap.html from plugin/ to gen/
- Extract window.config JS generation into gen/config.html
- mermaid.html uses param.html for wrapper config

* refactor(params)!: consolidate link_to_* into params.post_link section

- Move link_to_markdown/source/edit/report/vscode into [params.post_link]
- Rename keys: markdown, source, edit, report (bool), editor (string)
- editor defaults to "vscode", supports "trae" etc. via protocol template
- footer.html uses .Param "post_link" for all link toggles
- Remove link_to_* from deprecated keys list

* fix: add fallback for deprecated camelCase attributes and expand deprecation warnings

- render-codeblock-file-tree.html: folderSlash attribute fallback
- render-codeblock-toggle.html: lineNosToggler/lineWrapToggler fallback + warnings
- code-block-wrapper.html: maxShownLines/wrapperClass fallback
- detection-deprecated.html: add nested key warnings for 13 sections
  (header, breadcrumb, navigation, watermark, busuanzi, image, mermaid,
  codeblock, filetree, math.katex, math.mathjax.options, post_summary, footer)
- detection-deprecated.html: add link_guard front matter deprecation warning

* fix(mermaid): fix rendering in hidden tab panels and neutral layer scheduling

- isRenderContextActive: check tab-panel visibility via getBoundingClientRect
  instead of panel.hidden (tab-container uses slot-based hiding, not hidden attr)
- bindTabContainerChanged: render neutral layers when switching tabs so
  print/fallback scenarios work correctly
2026-07-01 22:27:08 +08:00

306 lines
15 KiB
HTML

{{- $buildDrafts := .Page.Draft -}}
{{- $relLangURL := relLangURL "" -}}
{{- /* Desktop header */ -}}
<header class="desktop animate__faster{{ if .Site.Params.header.blur }} is-blur{{ end }}" id="header-desktop">
<div class="header-wrapper"{{ if .Site.Params.github_corner.enable }} data-github-corner="{{ .Site.Params.github_corner.position }}"{{ end }}>
<div class="header-title">
<a href="{{ $relLangURL }}" title="{{ .Site.Title }}" class="header-title-link">
{{- with .Site.Params.header.title -}}
{{- with .logo -}}
{{- dict "Src" . "Class" "logo" "Alt" $.Site.Title "Width" 32 "Height" 32 | partial "plugin/image.html" -}}
{{- end -}}
{{- with .pre -}}
<span class="header-title-pre">{{ . | safeHTML }}</span>
{{- end -}}
{{- if .typeit -}}
{{- $.Store.Set "hasTyped" true -}}
<span class="typeit" data-group="header-desktop"><template>{{ .name | default $.Site.Title }}</template></span>
{{- else -}}
<span class="header-title-text">{{ .name | default $.Site.Title }}</span>
{{- end -}}
{{- with .post -}}
<span class="header-title-post">{{ . | safeHTML }}</span>
{{- end -}}
{{- else -}}
<span class="header-title-text">{{ .Site.Title }}</span>
{{- end -}}
</a>
{{- with .Site.Params.header.subtitle -}}
{{- if .typeit -}}
{{- $.Store.Set "hasTyped" true -}}
<span class="typeit header-subtitle" data-group="header-desktop"><template>{{ .name }}</template></span>
{{- else -}}
<span class="header-subtitle">{{ .name }}</span>
{{- end -}}
{{- end -}}
</div>
<nav>
<ul class="menu">
{{- range .Site.Menus.main -}}
{{- $url := .URL -}}
{{- with $url -}}
{{- $url = . | relLangURL -}}
{{- end -}}
{{- with .Page -}}
{{- $url = .RelPermalink -}}
{{- end -}}
{{- if (ne .Params.Draft true) | or $buildDrafts | and (ne .Params.Type "mobile") -}}
<li class="menu-item{{ if $.IsMenuCurrent `main` . | or ($.HasMenuCurrent `main` .) | or (eq $.RelPermalink $url) }} active{{ end }}{{ with .Params.Class }} {{ . }}{{ end }}{{ if .HasChildren }} has-children{{ end }}">
<a class="menu-link"
{{- with $url }} href="{{ $url }}"{{ else }} href="javascript:void(0);"{{ end }}
{{- with .Title }} title="{{ . }}"{{ end }}
{{- if (urls.Parse $url).Host }} rel="noopener noreferrer" target="_blank"{{ end -}}
>
{{- with .Pre -}}{{- . | safeHTML }} {{ end }}
{{- with .Params.Icon -}}{{ dict "Class" (printf "%v fa-sm" .) | partial "plugin/icon.html" }} {{ end }}
{{- .Name }}
{{- with .Post }} {{ . | safeHTML -}}{{- end -}}
</a>
{{- if .HasChildren -}}
{{ dict "Class" "dropdown-icon fa-solid fa-chevron-down" | partial "plugin/icon.html" }}
<ul class="sub-menu">
{{- range $k, $v := .Children -}}
{{- $url := $v.URL -}}
{{- with $url -}}
{{- $url = . | relLangURL -}}
{{- end -}}
{{- with $v.Page -}}
{{- $url = .RelPermalink -}}
{{- end -}}
{{- if (ne $v.Params.Draft true) | or $buildDrafts | and (ne $v.Params.Type "mobile") -}}
{{- if $k | and $v.Params.Divided -}}
<li class="menu-item-divider" aria-hidden="true"></li>
{{- end -}}
<li class="menu-item{{ if $.IsMenuCurrent `main` $v | or ($.HasMenuCurrent `main` $v) | or (eq $.RelPermalink $url) }} active{{ end }}{{ with $v.Params.Class }} {{ . }}{{ end }}">
<a class="menu-link"
{{- with $url }} href="{{ $url }}"{{ else }} href="javascript:void(0);"{{ end }}
{{- with $v.Title }} title="{{ . }}"{{ end }}
{{- if (urls.Parse $url).Host }} rel="noopener noreferrer" target="_blank"{{ end -}}
>
{{- with $v.Pre -}}{{- . | safeHTML }} {{ end }}
{{- with $v.Params.Icon -}}{{ dict "Class" (printf "%v fa-sm" .) | partial "plugin/icon.html" }} {{ end }}
{{- $v.Name }}
{{- with $v.Post }} {{ . | safeHTML -}}{{- end -}}
</a>
</li>
{{- end -}}
{{- end -}}
</ul>
{{- end -}}
</li>
{{- end -}}
{{- end -}}
{{- if .Site.Menus.main -}}
<li class="menu-item delimiter"></li>
{{- end -}}
{{- if .Site.Params.search.enable -}}
<li class="menu-item search">
<button type="button" class="search-trigger desktop" aria-label="{{ T "assets.search" }}" title="{{ T "assets.search" }}">
{{ dict "Class" "fa-solid fa-search" | partial "plugin/icon.html" }}
{{ T "assets.search" }}
<kbd></kbd>
</button>
</li>
<li class="menu-item delimiter"></li>
{{- end -}}
<li class="menu-item theme-switch-item">
<button type="button" class="theme-switch" aria-label="{{ T "header.switchTheme" }}" title="{{ T "header.switchTheme" }}">
{{- dict "Class" "fa-solid fa-adjust" | partial "plugin/icon.html" -}}
</button>
</li>
{{- if hugo.IsMultilingual -}}
<li class="menu-item language-switch">
<button type="button" aria-label="{{ T "header.selectLanguage" }}" title="{{ T "header.selectLanguage" }}">
{{- dict "Class" "fa-solid fa-language" | partial "plugin/icon.html" -}}
</button>
<ul class="sub-menu">
{{- if (eq .Kind "404") -}}
{{- range hugo.Sites -}}
{{- if ne . $.Site -}}
{{- $link := printf "%v/404.html" .LanguagePrefix -}}
<li class="menu-item">
<a href="{{ $link }}" class="menu-link" title="{{- .Language.LanguageName -}}">
{{- .Language.LanguageName -}}
</a>
</li>
{{- end -}}
{{- end -}}
{{- else if .IsTranslated -}}
{{- range .AllTranslations -}}
<li class="menu-item">
{{- if ne .Lang $.Lang -}}
<a href="{{ .RelPermalink }}" class="menu-link" title="{{ .Language.LanguageName }}">{{ .Language.LanguageName }}</a>
{{- else -}}
<span class="text-secondary" title="{{ .Language.LanguageName }}">{{ .Language.LanguageName }}</span>
{{- end -}}
</li>
{{- end -}}
{{- else -}}
<li class="menu-item">{{- T "header.noMoretTranslations" -}}</li>
{{- end -}}
</ul>
</li>
{{- end -}}
{{- /* Custom menu items in the desktop header */ -}}
{{- block "custom-menu:desktop" . }}{{ end -}}
</ul>
</nav>
</div>
</header>
{{- /* Mobile header */ -}}
<header class="mobile animate__faster{{ if .Site.Params.header.blur }} is-blur{{ end }}" id="header-mobile">
<div class="header-container">
<div class="header-wrapper">
<div class="header-title">
<a href="{{ $relLangURL }}" title="{{ .Site.Title }}" class="header-title-link">
{{- with .Site.Params.header.title -}}
{{- with .logo -}}
{{- dict "Src" . "Class" "logo" "Alt" $.Site.Title "Width" 26 "Height" 26 | partial "plugin/image.html" -}}
{{- end -}}
{{- with .pre -}}
<span class="header-title-pre">{{ . | safeHTML }}</span>
{{- end -}}
{{- if .typeit -}}
{{- $.Store.Set "hasTyped" true -}}
<span class="typeit" data-group="header-mobile"><template>{{ .name | default $.Site.Title }}</template></span>
{{- else -}}
<span class="header-title-text">{{ .name | default $.Site.Title }}</span>
{{- end -}}
{{- with .post -}}
<span class="header-title-post">{{ . | safeHTML }}</span>
{{- end -}}
{{- else -}}
<span class="header-title-text">{{ .Site.Title }}</span>
{{- end -}}
</a>
{{- with .Site.Params.header.subtitle -}}
{{- if .typeit -}}
{{- $.Store.Set "hasTyped" true -}}
<span class="typeit header-subtitle" data-group="header-mobile"><template>{{ .name }}</template></span>
{{- else -}}
<span class="header-subtitle">{{- .name -}}</span>
{{- end -}}
{{- end -}}
</div>
{{- if .Site.Params.search.enable -}}
<button type="button" class="search-trigger mobile" aria-label="{{ T "assets.search" }}">
{{- dict "Class" "fa-solid fa-search" | partial "plugin/icon.html" -}}
</button>
{{- end -}}
<button type="button" class="theme-switch" aria-label="{{ T "header.switchTheme" }}">
{{- dict "Class" "fa-solid fa-adjust" | partial "plugin/icon.html" -}}
</button>
<button type="button" class="menu-toggle" id="menu-toggle-mobile" aria-controls="menu-mobile" aria-expanded="false" aria-labelledby="menu-mobile">
<span></span><span></span><span></span>
</button>
</div>
<nav>
<ul class="menu" id="menu-mobile">
{{- $currentPage := . -}}
{{- range .Site.Menus.main -}}
{{- $url := .URL -}}
{{- with $url -}}
{{- $url = . | relLangURL -}}
{{- end -}}
{{- with .Page -}}
{{- $url = .RelPermalink -}}
{{- end -}}
{{- if (ne .Params.Draft true) | or $buildDrafts | and (ne .Params.Type "desktop") -}}
<li class="menu-item{{ if $.IsMenuCurrent `main` . | or ($.HasMenuCurrent `main` .) | or (eq $.RelPermalink $url) }} active{{ end }}{{ with .Params.Class }} {{ . }}{{ end }}">
{{- if .HasChildren -}}
<span class="nested-item">
<a class="menu-link"
{{- with $url }} href="{{ $url }}"{{ else }} href="javascript:void(0);"{{ end }}
{{- with .Title }} title="{{ . }}"{{ end }}
{{- if (urls.Parse $url).Host }} rel="noopener noreferrer" target="_blank"{{ end -}}
>
{{- with .Pre -}}{{- . | safeHTML }} {{ end }}
{{- with .Params.Icon -}}{{ dict "Class" (printf "%v fa-sm" .) | partial "plugin/icon.html" }} {{ end }}
{{- .Name }}
{{- with .Post }} {{ . | safeHTML -}}{{- end -}}
</a>
{{ dict "Class" "dropdown-icon fa-solid fa-chevron-right" | partial "plugin/icon.html" }}
</span>
<ul class="sub-menu">
{{- range $k, $v := .Children -}}
{{- $url := $v.URL -}}
{{- with $url -}}
{{- $url = . | relLangURL -}}
{{- end -}}
{{- with $v.Page -}}
{{- $url = .RelPermalink -}}
{{- end -}}
{{- if (ne $v.Params.Draft true) | or $buildDrafts | and (ne $v.Params.Type "desktop") -}}
{{- if $k | and $v.Params.Divided -}}
<li class="menu-item menu-item-divider" aria-hidden="true"></li>
{{- end -}}
<li class="menu-item{{ if $.IsMenuCurrent `main` $v | or ($.HasMenuCurrent `main` $v) | or (eq $.RelPermalink $url) }} active{{ end }}{{ with $v.Params.Class }} {{ . }}{{ end }}">
<a class="menu-link"
{{- with $url }} href="{{ $url }}"{{ else }} href="javascript:void(0);"{{ end }}
{{- with $v.Title }} title="{{ . }}"{{ end }}
{{- if (urls.Parse $url).Host }}rel="noopener noreferrer" target="_blank"{{ end -}}
>
{{- with $v.Pre -}}{{- . | safeHTML }} {{ end }}
{{- with $v.Params.Icon -}}{{ dict "Class" (printf "%v fa-sm" .) | partial "plugin/icon.html" }} {{ end }}
{{- $v.Name }}
{{- with $v.Post }} {{ . | safeHTML -}}{{- end -}}
</a>
</li>
{{- end -}}
{{- end -}}
</ul>
{{- else -}}
<a class="menu-link"
{{- with $url }} href="{{ $url }}"{{ else }} href="javascript:void(0);"{{ end }}
{{- with .Title }} title="{{ . }}"{{ end }}
{{- if (urls.Parse $url).Host }} rel="noopener noreferrer" target="_blank"{{ end -}}
>
{{- with .Pre -}}{{- . | safeHTML }} {{ end }}
{{- with .Params.Icon -}}{{ dict "Class" (printf "%v fa-sm" .) | partial "plugin/icon.html" }} {{ end }}
{{- .Name }}
{{- with .Post }} {{ . | safeHTML -}}{{- end -}}
</a>
{{- end -}}
</li>
{{- end -}}
{{- end -}}
<li class="menu-item menu-system">
{{- if hugo.IsMultilingual -}}
<span class="menu-system-item language-switch">
<button type="button" aria-label="{{ T "header.selectLanguage" }}" title="{{ T "header.selectLanguage" }}">
{{- .Language.LanguageName -}}
{{- dict "Class" "dropdown-icon fa-solid fa-chevron-down" | partial "plugin/icon.html" -}}
</button>
<select id="language-select" class="language-select" onchange="location = this.value;">
{{- if eq .Kind "404" -}}
{{- range hugo.Sites -}}
{{- $link := printf "%v/404.html" .LanguagePrefix -}}
<option value="{{ $link }}"{{ if eq . $.Site }} selected disabled{{ end }}>
{{- .Language.LanguageName -}}
</option>
{{- end -}}
{{- else if .IsTranslated -}}
{{- range .AllTranslations -}}
<option value="{{ .RelPermalink }}"{{ if eq .Lang $.Lang }} selected disabled{{ end }}>
{{- .Language.LanguageName -}}
</option>
{{- end -}}
{{- else -}}
<option disabled>{{- T "header.noMoretTranslations" -}}</option>
{{- end -}}
</select>
</span>
{{- end -}}
{{- /* Custom menu items in the mobile header */ -}}
{{- block "custom-menu:mobile" . }}{{ end -}}
</li>
</ul>
</nav>
</div>
</header>