Skip to content

Commit

Permalink
feat: support TOC in v3 (#290)
Browse files Browse the repository at this point in the history
* feat: support TOC in v3

* Update docs
  • Loading branch information
g1eny0ung committed Jul 25, 2024
1 parent bebd818 commit bfe2299
Show file tree
Hide file tree
Showing 8 changed files with 332 additions and 69 deletions.
1 change: 1 addition & 0 deletions docs/pages/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added

- Add `showPrevNextPost` param to control the display of previous and next post links in the single post page
- Add `showTableOfContents` param to control the display of the table of contents in the single post page

## [3.1.1] - 2024-07-23

Expand Down
5 changes: 5 additions & 0 deletions docs/pages/params-configurations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ customSyntaxHighlighting = true

# options
stickyNav = true
showTableOfContents = true
showSummaryCoverInPost = true
showPrevNextPost = true
# hasTwitterEmbed = true
Expand Down Expand Up @@ -161,6 +162,10 @@ View [Syntax highlighting](syntax-highlighting.md) for more details.

Make navbar sticky when scrolling.

### showTableOfContents = true

Show table of contents in the single post page.

### showSummaryCoverInPost = true

Show summary cover image in the single post page.
Expand Down
1 change: 1 addition & 0 deletions hugo.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ siteStartYear = 2016

# options
# stickyNav = true
# showTableOfContents = true
# showSummaryCoverInPost = true
# showPrevNextPost = true
# hasTwitterEmbed = true
Expand Down
145 changes: 78 additions & 67 deletions layouts/_default/single.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,89 +26,100 @@

{{ define "main" }}
<div class="mt-4 px-4">
<article class="mx-auto prose dark:prose-invert" id="dream-single-page">
<header>
<h1>{{ .Title }}</h1>
<p class="text-sm">
{{ if site.Params.Experimental.jsDate }}
<span data-format="luxon">{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</span>
{{ else }}
{{ if eq site.Language.Lang "zh" }}
{{ index site.Data.zh.Weekday (printf "%d" .Date.Weekday) }},{{ index site.Data.zh.Month (printf "%d" .Date.Month) }} {{ .Date.Day }} 日,{{ .Date.Year }} 年
{{ else if eq site.Language.Lang "es" }}
{{ index site.Data.es.Weekday (printf "%d" .Date.Weekday) }}, {{ .Date.Day }} de {{ index site.Data.es.Month (printf "%d" .Date.Month) }} de {{ .Date.Year }}
{{ else if eq site.Language.Lang "pt" }}
{{ index site.Data.pt.Weekday (printf "%d" .Date.Weekday) }}, {{ .Date.Day }} de {{ index site.Data.pt.Month (printf "%d" .Date.Month) }} de {{ .Date.Year }}
{{ else if eq site.Language.Lang "fr" }}
{{ index site.Data.fr.Weekday (printf "%d" .Date.Weekday) }} {{ .Date.Day }} {{ index site.Data.fr.Month (printf "%d" .Date.Month) }} {{ .Date.Year }}
{{ else }}
{{ .Date.Format "Monday, Jan 2, 2006" }}
{{ end }}
{{ end }}

| <span>{{ .ReadingTime }}{{ T "minuteRead" .ReadingTime }}</span>

{{ if ne .Params.nolastmod true }}
| <span>{{ T "updateAt" }}
{{ if site.Params.showTableOfContents }}
<div class="relative" x-data="{ height: '' }" x-init="height = $el.scrollHeight + 'px'">
{{ else }}
<div>
{{ end }}
{{ if site.Params.showTableOfContents }}
<div class="absolute right-0 lg:w-36 xl:w-48 hidden lg:block" :style="{ height }">
{{ .TableOfContents }}
</div>
{{ end }}
<article class="mx-auto prose dark:prose-invert" id="dream-single-post-main">
<header>
<h1>{{ .Title }}</h1>
<p class="text-sm">
{{ if site.Params.Experimental.jsDate }}
<span data-format="luxon">{{ .Lastmod.Format "2006-01-02T15:04:05Z07:00" }}</span>
<span data-format="luxon">{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</span>
{{ else }}
{{ if eq site.Language.Lang "zh" }}
{{ index site.Data.zh.Weekday (printf "%d" .Lastmod.Weekday) }},{{ index site.Data.zh.Month (printf "%d" .Lastmod.Month) }} {{ .Lastmod.Day }} 日,{{ .Lastmod.Year }} 年
{{ index site.Data.zh.Weekday (printf "%d" .Date.Weekday) }},{{ index site.Data.zh.Month (printf "%d" .Date.Month) }} {{ .Date.Day }} 日,{{ .Date.Year }} 年
{{ else if eq site.Language.Lang "es" }}
{{ index site.Data.es.Weekday (printf "%d" .Lastmod.Weekday) }}, {{ .Lastmod.Day }} de {{ index site.Data.es.Month (printf "%d" .Lastmod.Month) }} de {{ .Lastmod.Year }}
{{ index site.Data.es.Weekday (printf "%d" .Date.Weekday) }}, {{ .Date.Day }} de {{ index site.Data.es.Month (printf "%d" .Date.Month) }} de {{ .Date.Year }}
{{ else if eq site.Language.Lang "pt" }}
{{ index site.Data.pt.Weekday (printf "%d" .Lastmod.Weekday) }}, {{ .Lastmod.Day }} de {{ index site.Data.pt.Month (printf "%d" .Lastmod.Month) }} de {{ .Lastmod.Year }}
{{ index site.Data.pt.Weekday (printf "%d" .Date.Weekday) }}, {{ .Date.Day }} de {{ index site.Data.pt.Month (printf "%d" .Date.Month) }} de {{ .Date.Year }}
{{ else if eq site.Language.Lang "fr" }}
{{ index site.Data.fr.Weekday (printf "%d" .Date.Weekday) }} {{ .Date.Day }} {{ index site.Data.fr.Month (printf "%d" .Date.Month) }} {{ .Date.Year }}
{{ else }}
{{ .Lastmod.Format "Monday, Jan 2, 2006" }}
{{ .Date.Format "Monday, Jan 2, 2006" }}
{{ end }}
{{ end }}</span>
{{ end }}
</p>
<div class="flex justify-between">
{{ partial "author.html" (dict "Params" .Params "template" "single") }}
{{ end }}

{{ partial "share.html" . }}
</div>
</header>
| <span>{{ .ReadingTime }}{{ T "minuteRead" .ReadingTime }}</span>

{{ if and .Params.Cover site.Params.showSummaryCoverInPost }}
<img src="{{ .Params.Cover }}" />
{{ end }}
{{ if ne .Params.nolastmod true }}
| <span>{{ T "updateAt" }}
{{ if site.Params.Experimental.jsDate }}
<span data-format="luxon">{{ .Lastmod.Format "2006-01-02T15:04:05Z07:00" }}</span>
{{ else }}
{{ if eq site.Language.Lang "zh" }}
{{ index site.Data.zh.Weekday (printf "%d" .Lastmod.Weekday) }},{{ index site.Data.zh.Month (printf "%d" .Lastmod.Month) }} {{ .Lastmod.Day }} 日,{{ .Lastmod.Year }} 年
{{ else if eq site.Language.Lang "es" }}
{{ index site.Data.es.Weekday (printf "%d" .Lastmod.Weekday) }}, {{ .Lastmod.Day }} de {{ index site.Data.es.Month (printf "%d" .Lastmod.Month) }} de {{ .Lastmod.Year }}
{{ else if eq site.Language.Lang "pt" }}
{{ index site.Data.pt.Weekday (printf "%d" .Lastmod.Weekday) }}, {{ .Lastmod.Day }} de {{ index site.Data.pt.Month (printf "%d" .Lastmod.Month) }} de {{ .Lastmod.Year }}
{{ else if eq site.Language.Lang "fr" }}
{{ index site.Data.fr.Weekday (printf "%d" .Date.Weekday) }} {{ .Date.Day }} {{ index site.Data.fr.Month (printf "%d" .Date.Month) }} {{ .Date.Year }}
{{ else }}
{{ .Lastmod.Format "Monday, Jan 2, 2006" }}
{{ end }}
{{ end }}</span>
{{ end }}
</p>
<div class="flex justify-between">
{{ partial "author.html" (dict "Params" .Params "template" "single") }}

{{ .Content | emojify }}

{{ if site.Params.showPrevNextPost }}
<div class="divider"></div>
<div class="flex flex-col md:flex-row justify-between gap-4 py-4">
{{ with .NextInSection }}
<a class="group btn btn-outline" href="{{ .RelPermalink }}" title="{{ .Title }}">
<ion-icon name="chevron-back"></ion-icon>
<div class="inline-flex flex-col items-start">
<span class="text-base-content/60 group-hover:text-neutral-content/60 text-xs font-normal">{{ T "prevPage" }}</span>
<span class="max-w-48 truncate">{{ .LinkTitle }}</span>
{{ partial "share.html" . }}
</div>
</a>
{{ else }}
<div></div>
</header>

{{ if and .Params.Cover site.Params.showSummaryCoverInPost }}
<img src="{{ .Params.Cover }}" />
{{ end }}

{{ with .PrevInSection }}
<a class="group btn btn-outline" href="{{ .RelPermalink }}" title="{{ .Title }}">
<div class="inline-flex flex-col items-end">
<span class="text-base-content/60 group-hover:text-neutral-content/60 text-xs font-normal">{{ T "nextPage" }}</span>
<span class="max-w-48 truncate">{{ .LinkTitle }}</span>
</div>
<ion-icon name="chevron-forward"></ion-icon>
</a>
{{ else }}
<div></div>
{{ .Content | emojify }}

{{ if site.Params.showPrevNextPost }}
<div class="divider"></div>
<div class="flex flex-col md:flex-row justify-between gap-4 py-4">
{{ with .NextInSection }}
<a class="group btn btn-outline" href="{{ .RelPermalink }}" title="{{ .Title }}">
<ion-icon name="chevron-back"></ion-icon>
<div class="inline-flex flex-col items-start">
<span class="text-base-content/60 group-hover:text-neutral-content/60 text-xs font-normal">{{ T "prevPage" }}</span>
<span class="max-w-48 truncate">{{ .LinkTitle }}</span>
</div>
</a>
{{ else }}
<div></div>
{{ end }}

{{ with .PrevInSection }}
<a class="group btn btn-outline" href="{{ .RelPermalink }}" title="{{ .Title }}">
<div class="inline-flex flex-col items-end">
<span class="text-base-content/60 group-hover:text-neutral-content/60 text-xs font-normal">{{ T "nextPage" }}</span>
<span class="max-w-48 truncate">{{ .LinkTitle }}</span>
</div>
<ion-icon name="chevron-forward"></ion-icon>
</a>
{{ else }}
<div></div>
{{ end }}
</div>
{{ end }}
</div>
{{ end }}
</article>
</article>
</div>

{{ $disqusShortname := (or site.Config.Services.Disqus.Shortname site.DisqusShortname) }}

Expand Down
8 changes: 8 additions & 0 deletions src/input.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,11 @@
transform: rotateY(180deg);
}
}

#TableOfContents {
@apply sticky top-24;
}

#TableOfContents ul {
@apply menu menu-sm;
}
2 changes: 1 addition & 1 deletion src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ document.addEventListener('alpine:init', () => {
},

changeSyntaxHighlightingTheme() {
if (document.querySelector('#dream-single-page')) {
if (document.querySelector('#dream-single-post-main')) {
const customSyntaxHighlightingUrl = this.isDark()
? window.customSyntaxHighlighting.dark
: window.customSyntaxHighlighting.light
Expand Down
Loading

0 comments on commit bfe2299

Please sign in to comment.