refactor: use "sidebar-tree" for entire rendering

chore: update example site content

chore: add configuration for footer

chore: allow disable footer completely

chore: navbar highlights if contains current page

chore: styling update for partial templates

chore: update steps to use markdown delimiter
This commit is contained in:
Xin 2023-08-14 21:56:26 +01:00
parent 7a2cca9181
commit ed14432f77
15 changed files with 178 additions and 140 deletions

View File

@ -1,5 +0,0 @@
---
title: Test very long title to see how it looks
---
Hello world!

View File

@ -0,0 +1,9 @@
---
linkTitle: "ドキュメンテーション"
title: Hextraへようこそ
---
**Hextra**は、[Tailwind CSS](https://tailwindcss.com/)で構築された、モダンでレスポンシブでパワフルな[Hugo](https://gohugo.io/)テーマです。
[Next.js](https://nextjs.org/)テーマの[Nextra](https://github.com/shuding/nextra)にインスパイアされています。
## クイックスタート

View File

@ -1,4 +1,9 @@
--- ---
linkTitle: "Documentation" linkTitle: "Documentation"
title: Welcome to Hextra title: Introduction
--- ---
**Hextra** is a modern, responsive, and powerful [Hugo](https://gohugo.io/) theme built with [Tailwind CSS](https://tailwindcss.com/).
It is inspired by Next.js theme [Nextra](https://github.com/shuding/nextra).
Hextra is designed for building websites for documentation, blogs, and landing pages. It is elegant and easy to use out of the box, but also highly customizable to fit your needs.

View File

@ -0,0 +1,13 @@
---
title: コンポーネント
weight: 2
---
Hextraは、[Hugo Shortcodes](https://gohugo.io/content-management/shortcodes/)に基づいたさまざまな組み込みコンポーネントを提供しています。
{{< cards >}}
{{< card link="callouts" title="Callouts" icon="warning" >}}
{{< card link="cards" title="Cards" icon="cards" >}}
{{< card link="steps" title="Steps" icon="one" >}}
{{< /cards >}}

View File

@ -6,7 +6,7 @@ A built-in component to display a series of steps.
## Example ## Example
{{< steps >}} {{% steps %}}
### Step 1 ### Step 1
@ -20,15 +20,15 @@ This is the second step.
This is the third step. This is the third step.
{{< /steps >}} {{% /steps %}}
## Usage ## Usage
Put Markdown h3 header within `steps` shortcode. Put Markdown h3 header within `steps` shortcode.
```markdown ```
{{</* steps */>}} {{%/* steps */%}}
### Step 1 ### Step 1
This is the first step. This is the first step.
@ -36,5 +36,5 @@ This is the first step.
### Step 2 ### Step 2
This is the second step. This is the second step.
{{</* /steps */>}} {{%/* /steps */%}}
``` ```

View File

@ -1,5 +1,6 @@
--- ---
title: はじめに title: はじめに
weight: 1
--- ---
プロジェクトの紹介。 プロジェクトの紹介。

View File

@ -70,6 +70,11 @@ menu:
weight: 2 weight: 2
params: params:
footer:
disabled: false
displayCopyright: true
displayPoweredBy: true
displayUpdatedDate: true displayUpdatedDate: true
dateFormat: "January 2, 2006" dateFormat: "January 2, 2006"

View File

@ -4,7 +4,7 @@
<body dir="ltr"> <body dir="ltr">
{{- partial "navbar.html" . -}} {{- partial "navbar.html" . -}}
{{- block "main" . }}{{ end -}} {{- block "main" . }}{{ end -}}
{{- partial "footer.html" . -}} {{- if not .Site.Params.footer.disabled }}{{ partial "footer.html" . }}{{ end }}
</body> </body>
{{ partial "scripts.html" . }} {{ partial "scripts.html" . }}
</html> </html>

View File

@ -4,20 +4,22 @@
<footer class="hextra-footer bg-gray-100 pb-[env(safe-area-inset-bottom)] dark:bg-neutral-900 print:bg-transparent"> <footer class="hextra-footer bg-gray-100 pb-[env(safe-area-inset-bottom)] dark:bg-neutral-900 print:bg-transparent">
{{- if $enableFooterSwitches }} {{- if $enableFooterSwitches }}
<div class="mx-auto flex max-w-[90rem] gap-2 py-2 px-4"> <div class="mx-auto flex max-w-[90rem] gap-2 py-2 px-4">
{{ partial "language-switch.html" (dict "context" .) }} {{- partial "language-switch.html" (dict "context" .) -}}
{{ partial "theme-toggle.html" }} {{- partial "theme-toggle.html" -}}
</div> </div>
{{ end -}} {{ end -}}
<hr class="dark:border-neutral-800" /> <hr class="dark:border-neutral-800" />
<div class="mx-auto flex max-w-[90rem] justify-center py-12 pl-[max(env(safe-area-inset-left),1.5rem)] pr-[max(env(safe-area-inset-right),1.5rem)] text-gray-600 dark:text-gray-400 md:justify-start"> <div class="mx-auto flex max-w-[90rem] justify-center py-12 pl-[max(env(safe-area-inset-left),1.5rem)] pr-[max(env(safe-area-inset-right),1.5rem)] text-gray-600 dark:text-gray-400 md:justify-start">
<div class="flex w-full flex-col items-center sm:items-start"> <div class="flex w-full flex-col items-center sm:items-start">
<div> {{- if .Site.Params.footer.displayPoweredBy }}<div class="font-semibold">{{ template "theme-credit" . }}</div>{{ end -}}
<a class="flex items-center gap-1 text-current" target="_blank" rel="noopener noreferrer" title="Hugo homepage" href="https://gohugo.io/"> {{- if .Site.Params.footer.displayCopyright }}<p class="mt-6 text-xs">{{ i18n "footer.copyright" }}</p>{{ end -}}
<span>Powered by</span>
{{ partial "utils/icon.html" (dict "name" "hugo-full" "attributes" "height=20") }}
</a>
</div>
<p class="mt-6 text-xs">© 2023 Hextra Project.</p>
</div> </div>
</div> </div>
</footer> </footer>
{{- define "theme-credit" -}}
<a class="flex items-center gap-1 text-current" target="_blank" rel="noopener noreferrer" title="Hextra homepage" href="https://github.com/imfing/hextra">
<span class="mr-1">Powered by Hextra</span>
{{- partial "utils/icon.html" (dict "name" "hextra" "attributes" "height=1em") -}}
</a>
{{- end -}}

View File

@ -15,7 +15,7 @@
{{ range site.Languages }} {{ range site.Languages }}
{{ $link := partial "utils/lang-link" (dict "lang" .Lang "context" $page) }} {{ $link := partial "utils/lang-link" (dict "lang" .Lang "context" $page) }}
<li class="flex flex-col"> <li class="flex flex-col">
<a href="{{ $link }}" class="text-gray-800 dark:text-gray-100 hover:bg-primary-50 hover:text-primary-600 relative cursor-pointer whitespace-nowrap py-1.5 transition-colors ltr:pl-3 ltr:pr-9 rtl:pr-3 rtl:pl-9"> <a href="{{ $link }}" class="text-gray-800 dark:text-gray-100 hover:bg-primary-50 hover:text-primary-600 hover:dark:bg-primary-500/10 hover:dark:text-primary-600 relative cursor-pointer whitespace-nowrap py-1.5 transition-colors ltr:pl-3 ltr:pr-9 rtl:pr-3 rtl:pl-9">
{{- .LanguageName -}} {{- .LanguageName -}}
{{- if eq .LanguageName site.Language.LanguageName -}} {{- if eq .LanguageName site.Language.LanguageName -}}
<span class="absolute inset-y-0 flex items-center ltr:right-3 rtl:left-3"> <span class="absolute inset-y-0 flex items-center ltr:right-3 rtl:left-3">

View File

@ -5,36 +5,39 @@
<a class="flex items-center hover:opacity-75 ltr:mr-auto rtl:ml-auto" href="{{ .Site.Home.RelPermalink }}"> <a class="flex items-center hover:opacity-75 ltr:mr-auto rtl:ml-auto" href="{{ .Site.Home.RelPermalink }}">
{{ partial "utils/icon.html" (dict "name" "hextra" "attributes" "height=20") }} {{ partial "utils/icon.html" (dict "name" "hextra" "attributes" "height=20") }}
<span class="mx-2 font-extrabold hidden md:inline select-none" title="{{ .Site.Title }}"> <span class="mx-2 font-extrabold hidden md:inline select-none" title="{{ .Site.Title }}">
{{ .Site.Title }} {{- .Site.Title -}}
</span> </span>
</a> </a>
{{- $currentPage := . -}} {{- $currentPage := . -}}
{{- range .Site.Menus.main -}} {{- range .Site.Menus.main -}}
{{- if eq .Params.type "search" -}} {{- if eq .Params.type "search" -}}
{{ partial "search.html" (dict "params" .Params) }} {{- partial "search.html" (dict "params" .Params) -}}
{{- else -}} {{- else -}}
{{ $external := strings.HasPrefix .URL "http" }} {{- $external := strings.HasPrefix .URL "http" -}}
{{/* Display icon menu item */}}
{{- if .Params.icon -}} {{- if .Params.icon -}}
<a class="p-2 text-current" {{ if $external }}target="_blank" rel="noreferer"{{ end }} href="{{ .URL | safeURL }}"> <a class="p-2 text-current" {{ if $external }}target="_blank" rel="noreferer"{{ end }} href="{{ .URL | safeURL }}">
{{ partial "utils/icon.html" (dict "name" .Params.icon "attributes" "height=24") }} {{- partial "utils/icon.html" (dict "name" .Params.icon "attributes" "height=24") -}}
<span class="sr-only">{{ .Name }}</span> <span class="sr-only">{{ .Name }}</span>
</a> </a>
{{- else -}} {{- else -}}
{{- $active := or ($currentPage.HasMenuCurrent "main" .) ($currentPage.IsMenuCurrent "main" .) -}}
{{- $activeClass := cond $active "font-medium" "text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200" -}}
<a <a
href="{{ .URL | safeURL }}" href="{{ .URL | safeURL }}"
{{ if $external }}target="_blank" rel="noreferer"{{ end }} {{ if $external }}target="_blank" rel="noreferer"{{ end }}
class="text-sm contrast-more:text-gray-700 contrast-more:dark:text-gray-100 relative -ml-2 hidden whitespace-nowrap p-2 md:inline-block text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200" class="text-sm contrast-more:text-gray-700 contrast-more:dark:text-gray-100 relative -ml-2 hidden whitespace-nowrap p-2 md:inline-block {{ $activeClass }}"
> >
<span class="text-center">{{ .Name }}</span> <span class="text-center">{{ .Name }}</span>
</a> </a>
{{- end -}} {{- end -}}
{{ end }} {{- end -}}
{{ end }} {{- end -}}
<button type="button" aria-label="Menu" class="hamburger-menu -mr-2 rounded p-2 active:bg-gray-400/20 md:hidden"> <button type="button" aria-label="Menu" class="hamburger-menu -mr-2 rounded p-2 active:bg-gray-400/20 md:hidden">
{{ partial "utils/icon.html" (dict "name" "menu" "attributes" "height=24") }} {{- partial "utils/icon.html" (dict "name" "menu" "attributes" "height=24") -}}
</button> </button>
</nav> </nav>
</div> </div>

View File

@ -1,30 +1,30 @@
{{ $jsTheme := resources.Get "js/theme.js" }} {{- $jsTheme := resources.Get "js/theme.js" -}}
{{ $jsMenu := resources.Get "js/menu.js" }} {{- $jsMenu := resources.Get "js/menu.js" -}}
{{ $jsCodeCopy := resources.Get "js/code-copy.js" }} {{- $jsCodeCopy := resources.Get "js/code-copy.js" -}}
{{ $jsTabs := resources.Get "js/tabs.js" }} {{- $jsTabs := resources.Get "js/tabs.js" -}}
{{ $jsLang := resources.Get "js/lang.js" }} {{- $jsLang := resources.Get "js/lang.js" -}}
{{ $scripts := slice $jsTheme $jsMenu $jsCodeCopy $jsTabs $jsLang | resources.Concat "js/main.js" }} {{- $scripts := slice $jsTheme $jsMenu $jsCodeCopy $jsTabs $jsLang | resources.Concat "js/main.js" -}}
{{ if hugo.IsProduction }} {{- if hugo.IsProduction -}}
{{ $scripts = $scripts | minify | fingerprint }} {{- $scripts = $scripts | minify | fingerprint -}}
{{ end }} {{- end -}}
<script defer src="{{ $scripts.RelPermalink }}" integrity="{{ $scripts.Data.Integrity }}"></script> <script defer src="{{ $scripts.RelPermalink }}" integrity="{{ $scripts.Data.Integrity }}"></script>
{{/* FlexSearch */}} {{/* FlexSearch */}}
{{- if not site.Params.search.disabled -}} {{- if not site.Params.search.disabled -}}
{{ $jsSearchScript := printf "%s.search.js" .Language.Lang }} {{- $jsSearchScript := printf "%s.search.js" .Language.Lang -}}
{{ $jsSearch := resources.Get "js/flexsearch.js" | resources.ExecuteAsTemplate $jsSearchScript . }} {{- $jsSearch := resources.Get "js/flexsearch.js" | resources.ExecuteAsTemplate $jsSearchScript . -}}
{{ if hugo.IsProduction }} {{- if hugo.IsProduction -}}
{{ $jsSearch = $jsSearch | minify | fingerprint }} {{- $jsSearch = $jsSearch | minify | fingerprint -}}
{{ end }} {{- end -}}
{{ $flexSearchJS := resources.Get "vendor/flexsearch/flexsearch.bundle.min.js" | fingerprint }} {{- $flexSearchJS := resources.Get "vendor/flexsearch/flexsearch.bundle.min.js" | fingerprint -}}
<script defer src="{{ $flexSearchJS.RelPermalink }}" integrity="{{ $flexSearchJS.Data.Integrity }}"></script> <script defer src="{{ $flexSearchJS.RelPermalink }}" integrity="{{ $flexSearchJS.Data.Integrity }}"></script>
<script defer src="{{ $jsSearch.RelPermalink }}" integrity="{{ $jsSearch.Data.Integrity }}"></script> <script defer src="{{ $jsSearch.RelPermalink }}" integrity="{{ $jsSearch.Data.Integrity }}"></script>
{{- end -}} {{- end -}}
{{/* Mermaid */}} {{/* Mermaid */}}
{{ if .Page.Store.Get "hasMermaid" -}} {{- if .Page.Store.Get "hasMermaid" -}}
{{ $mermaidJS := resources.Get "vendor/mermaid/mermaid.min.js" | fingerprint }} {{- $mermaidJS := resources.Get "vendor/mermaid/mermaid.min.js" | fingerprint -}}
<script defer src="{{ $mermaidJS.RelPermalink }}" integrity="{{ $mermaidJS.Data.Integrity }}"></script> <script defer src="{{ $mermaidJS.RelPermalink }}" integrity="{{ $mermaidJS.Data.Integrity }}"></script>
<script> <script>
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
@ -32,20 +32,20 @@
mermaid.initialize({ startOnLoad: true, theme: theme }); mermaid.initialize({ startOnLoad: true, theme: theme });
}); });
</script> </script>
{{ end }} {{- end -}}
{{/* KaTex */}} {{/* KaTex */}}
{{ if and (not site.Params.math.disabled) .Page.Params.math }} {{- if and (not site.Params.math.disabled) .Page.Params.math -}}
{{ $katexCSS := resources.Get "vendor/katex/katex.min.css" | fingerprint }} {{- $katexCSS := resources.Get "vendor/katex/katex.min.css" | fingerprint -}}
{{ $katexJS := resources.Get "vendor/katex/katex.min.js" | fingerprint }} {{- $katexJS := resources.Get "vendor/katex/katex.min.js" | fingerprint -}}
{{ $katexAutoRenderJS := resources.Get "vendor/katex/auto-render.min.js" | fingerprint }} {{- $katexAutoRenderJS := resources.Get "vendor/katex/auto-render.min.js" | fingerprint -}}
<link type="text/css" rel="stylesheet" href="{{ $katexCSS.RelPermalink }}" integrity="{{ $katexCSS.Data.Integrity }}" /> <link type="text/css" rel="stylesheet" href="{{ $katexCSS.RelPermalink }}" integrity="{{ $katexCSS.Data.Integrity }}" />
<script defer src="{{ $katexJS.RelPermalink }}" integrity="{{ $katexJS.Data.Integrity }}"></script> <script defer src="{{ $katexJS.RelPermalink }}" integrity="{{ $katexJS.Data.Integrity }}"></script>
<script defer src="{{ $katexAutoRenderJS.RelPermalink }}" integrity="{{ $katexAutoRenderJS.Data.Integrity }}"></script> <script defer src="{{ $katexAutoRenderJS.RelPermalink }}" integrity="{{ $katexAutoRenderJS.Data.Integrity }}"></script>
{{ $katexFonts := resources.Match "vendor/katex/fonts/*" }} {{ $katexFonts := resources.Match "vendor/katex/fonts/*" }}
{{ range $katexFonts }} {{- range $katexFonts -}}
{{ .Publish }} {{ .Publish }}
{{ end }} {{- end -}}
<script> <script>
// TODO: make render options configurable // TODO: make render options configurable
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {

View File

@ -1,10 +1,10 @@
{{ $context := .context }} {{- $context := .context -}}
{{ $disableSidebar := .disableSidebar | default false }} {{- $disableSidebar := .disableSidebar | default false -}}
{{ $sidebarClass := cond $disableSidebar "md:hidden xl:block" "md:sticky" }} {{- $sidebarClass := cond $disableSidebar "md:hidden xl:block" "md:sticky" -}}
{{ $navRoot := cond (eq site.Home.Type "docs") site.Home $context.FirstSection }} {{- $navRoot := cond (eq site.Home.Type "docs") site.Home $context.FirstSection -}}
{{ $navPages := union $navRoot.RegularPages $navRoot.Sections }} {{- $navPages := union $navRoot.RegularPages $navRoot.Sections -}}
{{ $pageURL := $context.RelPermalink }} {{- $pageURL := $context.RelPermalink -}}
<aside class="sidebar-container flex flex-col print:hidden md:top-16 md:shrink-0 md:w-64 md:self-start max-md:[transform:translate3d(0,-100%,0)] {{ $sidebarClass }}"> <aside class="sidebar-container flex flex-col print:hidden md:top-16 md:shrink-0 md:w-64 md:self-start max-md:[transform:translate3d(0,-100%,0)] {{ $sidebarClass }}">
@ -15,13 +15,13 @@
<div class="overflow-y-auto overflow-x-hidden p-4 grow md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]"> <div class="overflow-y-auto overflow-x-hidden p-4 grow md:h-[calc(100vh-var(--navbar-height)-var(--menu-height))]">
<ul class="flex flex-col gap-1 md:hidden"> <ul class="flex flex-col gap-1 md:hidden">
<!-- Nav --> <!-- Nav -->
{{- range site.Menus.main -}} {{- range site.Menus.main }}
{{- if and .URL (and (ne .Params.type "search") (not .Params.icon)) -}} {{- if and .URL (and (ne .Params.type "search") (not .Params.icon)) -}}
<li>{{ template "sidebar-item-link" dict "active" false "title" .Name "link" .URL }}</li> <li>{{ template "sidebar-item-link" dict "active" false "title" .Name "link" .URL }}</li>
{{- end -}} {{- end -}}
{{- end -}} {{- end -}}
{{ template "sidebar-separator" }} {{ template "sidebar-separator" -}}
{{ template "sidebar-main" (dict "pages" $navPages "pageURL" $pageURL "toc" true) }} {{ template "sidebar-main" (dict "context" $navRoot "pageURL" $pageURL "toc" true) -}}
<!-- Sidebar footer --> <!-- Sidebar footer -->
@ -32,15 +32,15 @@
</ul> </ul>
<!-- Sidebar on large screen --> <!-- Sidebar on large screen -->
{{ if $disableSidebar -}} {{- if $disableSidebar }}
<div class="max-xl:hidden h-0 w-64 shrink-0"></div> <div class="max-xl:hidden h-0 w-64 shrink-0"></div>
{{ .context.Scratch.Set "enableFooterSwitches" true }} {{ .context.Scratch.Set "enableFooterSwitches" true }}
{{ else }} {{- else -}}
<ul class="flex flex-col gap-1 max-md:hidden"> <ul class="flex flex-col gap-1 max-md:hidden">
{{ template "sidebar-main" (dict "pages" $navPages "pageURL" $pageURL) }} {{ template "sidebar-main" (dict "context" $navRoot "pageURL" $pageURL) }}
{{ template "sidebar-footer" }} {{ template "sidebar-footer" }}
</ul> </ul>
{{ end }} {{ end -}}
</div> </div>
{{/* Hide theme switch when sidebar is disabled */}} {{/* Hide theme switch when sidebar is disabled */}}
{{ $switchesClass := cond $disableSidebar "md:hidden" "" }} {{ $switchesClass := cond $disableSidebar "md:hidden" "" }}
@ -51,57 +51,54 @@
</aside> </aside>
{{- define "sidebar-main" -}} {{- define "sidebar-main" -}}
{{ $pages := .pages }} {{ $context := .context }}
{{ $toc := .toc | default false }} {{ $toc := .toc | default false }}
{{ $pageURL := .pageURL }} {{ $pageURL := .pageURL }}
{{- with $pages -}} {{ template "sidebar-tree" (dict "context" $context "level" 0 "pageURL" $pageURL "toc" $toc) }}
{{- range .ByWeight -}}
{{ template "sidebar-item" (dict "item" . "pageURL" $pageURL "toc" $toc) }}
{{ template "sidebar-tree" (dict "context" . "level" 1 "pageURL" $pageURL "toc" $toc) }}
{{- end -}}
{{ end }}
{{- end -}}
{{- define "sidebar-footer" -}}
{{- range site.Menus.sidebar -}}
{{ if eq .Params.type "separator" }}
<li class="[word-break:break-word] mt-5 mb-2 px-2 py-1.5 text-sm font-semibold text-gray-900 first:mt-0 dark:text-gray-100">
<span class="cursor-default">{{ .Name }}</span>
</li>
{{ else }}
<li>{{ template "sidebar-item-link" dict "active" false "title" .Name "link" .URL }}</li>
{{ end }}
{{- end -}}
{{- end -}} {{- end -}}
{{- define "sidebar-tree" -}} {{- define "sidebar-tree" -}}
{{ $pageURL := .pageURL }} {{- if ge .level 4 -}}
{{ $level := .level }} {{- return -}}
{{ $toc := .toc | default false }} {{- end -}}
{{ if ge $level 4 }} {{- $context := .context -}}
{{ return }} {{- $pageURL := .pageURL -}}
{{ end }} {{- $level := .level -}}
{{- $toc := .toc | default false -}}
{{ $items := union .context.RegularPages .context.Sections }} {{- $items := union .context.RegularPages .context.Sections -}}
{{ with $items }} {{- with $items -}}
<div class="pt-1 ltr:pr-0"> {{- if eq $level 0 -}}
<ul class='relative flex flex-col gap-1 before:absolute before:inset-y-1 before:w-px before:bg-gray-200 before:content-[""] ltr:ml-3 ltr:pl-3 ltr:before:left-0 rtl:mr-3 rtl:pr-3 rtl:before:right-0 dark:before:bg-neutral-800'> {{- range $items.ByWeight }}
{{ range $items.ByWeight }} {{- $active := eq $pageURL .RelPermalink -}}
{{ $active := eq $pageURL .RelPermalink }} <li class="open">
{{ $title := .LinkTitle | default .File.BaseFileName }} {{- template "sidebar-item-link" dict "context" . "active" $active "title" .LinkTitle "link" .RelPermalink -}}
<li class="flex flex-col gap-1"> {{- if and $toc $active -}}
{{ template "sidebar-item-link" dict "active" $active "title" $title "link" .RelPermalink }} {{- template "sidebar-toc" dict "page" . -}}
{{ if and $toc $active }} {{- end -}}
{{ template "sidebar-toc" dict "page" . }} {{- template "sidebar-tree" dict "context" . "pageURL" $pageURL "level" (add $level 1) -}}
{{ end }} </li>
</li> {{- end -}}
{{ template "sidebar-tree" dict "context" . "pageURL" $pageURL "level" (add $level 1) }} {{- else -}}
{{ end }} <div class="pt-1 ltr:pr-0">
</ul> <ul class='relative flex flex-col gap-1 before:absolute before:inset-y-1 before:w-px before:bg-gray-200 before:content-[""] ltr:ml-3 ltr:pl-3 ltr:before:left-0 rtl:mr-3 rtl:pr-3 rtl:before:right-0 dark:before:bg-neutral-800'>
</div> {{- range $items.ByWeight }}
{{ end }} {{- $active := eq $pageURL .RelPermalink -}}
{{- $title := .LinkTitle | default .File.BaseFileName -}}
<li class="flex flex-col gap-1">
{{- template "sidebar-item-link" dict "context" . "active" $active "title" $title "link" .RelPermalink -}}
{{- if and $toc $active -}}
{{ template "sidebar-toc" dict "page" . }}
{{- end }}
{{ template "sidebar-tree" dict "context" . "pageURL" $pageURL "level" (add $level 1) }}
</li>
{{- end -}}
</ul>
</div>
{{- end -}}
{{- end }}
{{- end -}} {{- end -}}
{{- define "sidebar-toc" -}} {{- define "sidebar-toc" -}}
@ -126,13 +123,23 @@
{{ end }} {{ end }}
{{- end -}} {{- end -}}
{{- define "sidebar-footer" -}}
{{- range site.Menus.sidebar -}}
{{ if eq .Params.type "separator" }}
<li class="[word-break:break-word] mt-5 mb-2 px-2 py-1.5 text-sm font-semibold text-gray-900 first:mt-0 dark:text-gray-100">
<span class="cursor-default">{{ .Name }}</span>
</li>
{{ else }}
<li>{{ template "sidebar-item-link" dict "active" false "title" .Name "link" .URL }}</li>
{{ end }}
{{- end -}}
{{- end -}}
{{- define "sidebar-item" }} {{- define "sidebar-item" }}
{{- $active := eq .pageURL .item.RelPermalink -}} {{- $active := eq .pageURL .item.RelPermalink -}}
{{- $title := .item.LinkTitle | default .item.File.BaseFileName -}} {{- $title := .item.LinkTitle | default .item.File.BaseFileName -}}
{{- $link := .item.RelPermalink -}} {{- $link := .item.RelPermalink -}}
{{- $toc := .toc | default false -}} {{- $toc := .toc | default false -}}
<li class="open"> <li class="open">
{{ template "sidebar-item-link" dict "active" $active "title" $title "link" $link }} {{ template "sidebar-item-link" dict "active" $active "title" $title "link" $link }}
{{ if and $toc $active }} {{ if and $toc $active }}
@ -144,7 +151,7 @@
{{- define "sidebar-item-link" -}} {{- define "sidebar-item-link" -}}
{{ $external := strings.HasPrefix .link "http" }} {{ $external := strings.HasPrefix .link "http" }}
<a <a
class="flex cursor-pointer rounded px-2 py-1.5 text-sm transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word] class="flex items-center justify-between gap-2 cursor-pointer rounded px-2 py-1.5 text-sm transition-colors [-webkit-tap-highlight-color:transparent] [-webkit-touch-callout:none] [word-break:break-word]
{{- if .active }} {{- if .active }}
bg-primary-100 font-semibold text-primary-800 contrast-more:border contrast-more:border-primary-500 dark:bg-primary-400/10 dark:text-primary-600 contrast-more:dark:border-primary-500 bg-primary-100 font-semibold text-primary-800 contrast-more:border contrast-more:border-primary-500 dark:bg-primary-400/10 dark:text-primary-600 contrast-more:dark:border-primary-500
{{- else }} {{- else }}

View File

@ -5,23 +5,21 @@
<nav class="hextra-toc order-last hidden w-64 shrink-0 xl:block print:hidden px-4" aria-label="table of contents"> <nav class="hextra-toc order-last hidden w-64 shrink-0 xl:block print:hidden px-4" aria-label="table of contents">
{{ if $toc }} {{- if $toc }}
<div class="sticky top-16 overflow-y-auto pr-4 pt-6 text-sm [hyphens:auto] max-h-[calc(100vh-4rem-env(safe-area-inset-bottom))] ltr:-mr-4 rtl:-ml-4"> <div class="sticky top-16 overflow-y-auto pr-4 pt-6 text-sm [hyphens:auto] max-h-[calc(100vh-4rem-env(safe-area-inset-bottom))] ltr:-mr-4 rtl:-ml-4">
{{ with .Fragments.Headings }} {{- with .Fragments.Headings -}}
<p class="mb-4 font-semibold tracking-tight">{{ i18n "article.on_this_page" }}</p> <p class="mb-4 font-semibold tracking-tight">{{ i18n "article.on_this_page" }}</p>
{{ range . }} {{- range . -}}
<ul> <ul>
{{ with .Headings }} {{- with .Headings -}}{{ template "toc-subheading" (dict "headings" . "level" 0) }}{{- end -}}
{{ template "toc-subheading" (dict "headings" . "level" 0) }}
{{ end }}
</ul> </ul>
{{ end }} {{- end -}}
{{ end }} {{- end -}}
{{ $borderClass := "mt-8 border-t bg-white pt-8 shadow-[0_-12px_16px_white] dark:bg-dark dark:shadow-[0_-12px_16px_#111]" }} {{- $borderClass := "mt-8 border-t bg-white pt-8 shadow-[0_-12px_16px_white] dark:bg-dark dark:shadow-[0_-12px_16px_#111]" -}}
{{ if not .Fragments.Headings }} {{- if not .Fragments.Headings -}}
{{ $borderClass = "" }} {{- $borderClass = "" -}}
{{ end }} {{- end -}}
{{/* TOC bottom part */}} {{/* TOC bottom part */}}
<div class="{{ $borderClass }} sticky bottom-0 flex flex-col items-start gap-2 pb-8 dark:border-neutral-800 contrast-more:border-t contrast-more:border-neutral-400 contrast-more:shadow-none contrast-more:dark:border-neutral-400"> <div class="{{ $borderClass }} sticky bottom-0 flex flex-col items-start gap-2 pb-8 dark:border-neutral-800 contrast-more:border-t contrast-more:border-neutral-400 contrast-more:shadow-none contrast-more:dark:border-neutral-400">
@ -33,31 +31,31 @@
{{- end -}} {{- end -}}
</div> </div>
</div> </div>
{{ end }} {{ end -}}
</nav> </nav>
{{/* TOC subheadings component. This is a recursive component that renders a list of headings. */}} {{/* TOC subheadings component. This is a recursive component that renders a list of headings. */}}
{{- define "toc-subheading" -}} {{- define "toc-subheading" -}}
{{ $headings := .headings }} {{- $headings := .headings -}}
{{ $level := .level }} {{- $level := .level -}}
{{ if ge $level 6 }} {{- if ge $level 6 -}}
{{ return }} {{ return }}
{{ end }} {{- end -}}
{{ $padding := (mul $level 4) }} {{- $padding := (mul $level 4) -}}
{{ $class := cond (eq $level 0) "font-semibold" (printf "ltr:pl-%d rtl:pr-%d" $padding $padding) }} {{- $class := cond (eq $level 0) "font-semibold" (printf "ltr:pl-%d rtl:pr-%d" $padding $padding) -}}
{{ range $headings }} {{- range $headings }}
{{ if .Title }} {{- if .Title }}
<li class="my-2 scroll-my-6 scroll-py-6"> <li class="my-2 scroll-my-6 scroll-py-6">
<a class="{{ $class }} inline-block text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-300 contrast-more:text-gray-900 contrast-more:underline contrast-more:dark:text-gray-50 w-full break-words" href="#{{ anchorize .ID }}"> <a class="{{ $class }} inline-block text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-300 contrast-more:text-gray-900 contrast-more:underline contrast-more:dark:text-gray-50 w-full break-words" href="#{{ anchorize .ID }}">
{{ .Title }} {{- .Title -}}
</a> </a>
</li> </li>
{{ end }} {{- end -}}
{{ with .Headings }} {{- with .Headings -}}
{{ template "toc-subheading" (dict "headings" . "level" (add $level 1)) }} {{ template "toc-subheading" (dict "headings" . "level" (add $level 1)) }}
{{ end }} {{- end -}}
{{ end }} {{- end -}}
{{- end -}} {{- end -}}

View File

@ -1,3 +1,3 @@
<div class="steps ml-4 mb-12 border-l border-gray-200 pl-6 dark:border-neutral-800 [counter-reset:step]"> <div class="steps ml-4 mb-12 border-l border-gray-200 pl-6 dark:border-neutral-800 [counter-reset:step]">
{{ .Inner | markdownify }} {{- .Inner -}}
</div> </div>