migrate to decoupled Blowfish layout, fix TOC scrollspy, and update docs
- Theme Decoupling & Cleanup:
- Fully decoupled and vendored the Blowfish theme directly into root directories (layouts/,
assets/, static/, data/, i18n/).
- De-registered and cleaned up legacy Git submodules (themes/blowfish, themes/hugo-admonitions)
from the Git index to protect the build from upstream breakages.
- Configured .gitignore to ignore development preview symlinks (content, static,
config/_default/menus.en.toml), build folders (public/, resources/), and locks.
- TOC & Layout Fixes:
- Replaced the custom layouts/_default/single.html template with the Blowfish default to restore
native container widths and the side-by-side flex layout.
- Restored TOC to float on the right sidebar on desktop viewports and render inline on mobile
viewports.
- Fixed a parameter resolution bug in layouts/partials/toc.html by checking both .Site.Params.
smartTOC and .Site.Params.article.smartTOC (where it is defined in params.toml).
- Upgraded the TOC scrollspy JavaScript to target all '#TableOfContents' containers on the page,
enabling highlight tracking on both desktop and mobile layouts.
- Documentation Updates (README.md):
- Restored YAML front matter metadata block at the top.
- Added detailed notes on the CI/CD build process and Gitea runner deployment targets
(/srv/www/docs-public and /srv/www/docs-private).
- Added a categorized and sorted "Shortcodes Quick Reference" table at the top of the shortcodes
section (ordered by Custom, Hugo Default, and Blowfish).
- Documented custom shortcodes (Include, Screenshot, Raw HTML) and missing Hugo default
shortcodes (Highlight, Instagram, Param, Ref, Relref, Twitter, Vimeo, Youtube).
- Restructured headings to ensure all sub-shortcodes are H3, removed block break tags (<br/>),
and appended horizontal separators (---) after H2 sections.
This commit is contained in:
@@ -1,86 +1,140 @@
|
||||
{{ define "main" }}
|
||||
{{ .Scratch.Set "scope" "single" }}
|
||||
|
||||
<article class="w-full py-8">
|
||||
<article>
|
||||
{{/* Hero */}}
|
||||
{{ if .Params.showHero | default (site.Params.article.showHero | default false) }}
|
||||
{{ partial (printf "hero/%s.html" (.Params.heroStyle | default site.Params.article.heroStyle)) . }}
|
||||
{{ $heroStyle := .Params.heroStyle }}
|
||||
{{ if not $heroStyle }}{{ $heroStyle = site.Params.article.heroStyle }}{{ end }}
|
||||
{{ $heroStyle := print "hero/" $heroStyle ".html" }}
|
||||
{{ if templates.Exists ( printf "partials/%s" $heroStyle ) }}
|
||||
{{ partial $heroStyle . }}
|
||||
{{ else }}
|
||||
{{ partial "hero/basic.html" . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<header id="single_header" class="mt-5 max-w-prose mx-auto px-4">
|
||||
<h1 class="mt-0 text-4xl font-extrabold text-neutral-900 dark:text-neutral">{{ .Title | emojify }}</h1>
|
||||
{{/* Header */}}
|
||||
<header id="single_header" class="mt-5 max-w-prose">
|
||||
{{ if .Params.showBreadcrumbs | default (site.Params.article.showBreadcrumbs | default false) }}
|
||||
{{ partial "breadcrumbs.html" . }}
|
||||
{{ end }}
|
||||
<h1 class="mt-0 text-4xl font-extrabold text-neutral-900 dark:text-neutral">
|
||||
{{ .Title | emojify }}
|
||||
</h1>
|
||||
<div class="mt-1 mb-6 text-base text-neutral-500 dark:text-neutral-400 print:hidden">
|
||||
{{ partial "article-meta/basic.html" (dict "context" . "scope" "single") }}
|
||||
|
||||
<!-- Added Dates Section
|
||||
<div class="mt-2 flex flex-wrap gap-x-4 italic opacity-80 text-sm">
|
||||
<span>Published: {{ .Date.Format "Jan 2, 2006" }}</span>
|
||||
{{ if ne (.Lastmod.Format "2006-01-02") (.Date.Format "2006-01-02") }}
|
||||
<span class="before:content-['•'] before:mr-4">
|
||||
Last updated: {{ .Lastmod.Format "Jan 2, 2006" }}
|
||||
</span>
|
||||
{{ end }}
|
||||
</div> -->
|
||||
</div>
|
||||
{{ if not (.Params.showAuthorBottom | default (site.Params.article.showAuthorBottom | default false)) }}
|
||||
{{ template "SingleAuthor" . }}
|
||||
{{ end }}
|
||||
</header>
|
||||
|
||||
{{/* The Content Wrapper: Standard Blowfish structure */}}
|
||||
<div class="mt-8 px-4">
|
||||
<div class="container mx-auto prose dark:prose-invert">
|
||||
{{ if .Params.showTableOfContents | default site.Params.article.showTableOfContents }}
|
||||
<div class="toc-container mb-8">
|
||||
{{/* Body */}}
|
||||
<section class="flex flex-col max-w-full mt-0 prose dark:prose-invert lg:flex-row">
|
||||
{{ $enableToc := site.Params.article.showTableOfContents | default false }}
|
||||
{{ $enableToc = .Params.showTableOfContents | default $enableToc }}
|
||||
{{ $showToc := and $enableToc (in .TableOfContents "<ul") }}
|
||||
{{ $topClass := cond (hasPrefix site.Params.header.layout "fixed") "lg:top-[140px]" "lg:top-10" }}
|
||||
{{ if $showToc }}
|
||||
<div class="order-first lg:ms-auto px-0 lg:order-last lg:ps-8 lg:max-w-2xs">
|
||||
<div class="toc ps-5 print:hidden lg:sticky {{ $topClass }}">
|
||||
{{ partial "toc.html" . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
<article class="article-content">
|
||||
{{ partial "series/series.html" . }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
||||
<div class="min-w-0 min-h-0 max-w-fit">
|
||||
{{ partial "series/series.html" . }}
|
||||
<div class="article-content max-w-prose mb-20">
|
||||
{{ .Content }}
|
||||
|
||||
{{ if .Params.replyByEmail | default site.Params.replyByEmail }}
|
||||
{{ $defaultReplyByEmail := site.Params.replyByEmail }}
|
||||
{{ $replyByEmail := default $defaultReplyByEmail .Params.replyByEmail }}
|
||||
{{ if $replyByEmail }}
|
||||
{{ $replySubject := i18n "article.reply_to" (dict "Title" .Title) | default (printf "Reply to %s" .Title) }}
|
||||
<strong class="block mt-8">
|
||||
<a target="_blank" href="mailto:{{ site.Params.Author.email }}">Reply by Email</a>
|
||||
<a
|
||||
class="email-link m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 hover:bg-primary-500 hover:text-neutral dark:bg-neutral-700 dark:text-neutral-300 dark:hover:bg-primary-400 dark:hover:text-neutral-800"
|
||||
href="#"
|
||||
data-email="{{ site.Params.Author.email | base64Encode }}"
|
||||
data-subject="{{ replace $replySubject "\"" "'" }}">
|
||||
{{ i18n "article.reply_by_email" | default "Reply by Email" }}
|
||||
</a>
|
||||
<noscript>
|
||||
<span
|
||||
class="m-1 rounded bg-neutral-300 p-1.5 text-neutral-700 dark:bg-neutral-700 dark:text-neutral-300">
|
||||
{{ i18n "article.reply_by_email" | default "Reply by Email" }} (require JavaScript)
|
||||
</span>
|
||||
</noscript>
|
||||
</strong>
|
||||
{{ end }}
|
||||
|
||||
<div class="mt-10">
|
||||
{{ if (.Params.showAuthorBottom | default (site.Params.article.showAuthorBottom | default false)) }}
|
||||
{{ template "SingleAuthor" . }}
|
||||
{{ end }}
|
||||
{{ partial "series/series-closed.html" . }}
|
||||
{{ partial "sharing-links.html" . }}
|
||||
{{ partial "related.html" . }}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
{{ if (.Params.showAuthorBottom | default (site.Params.article.showAuthorBottom | default false)) }}
|
||||
{{ template "SingleAuthor" . }}
|
||||
{{ end }}
|
||||
{{ partial "series/series-closed.html" . }}
|
||||
{{ partial "sharing-links.html" . }}
|
||||
{{ partial "related.html" . }}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="pt-8 mt-12 border-t border-neutral-200 dark:border-neutral-800 max-w-prose mx-auto px-4">
|
||||
{{/* Footer */}}
|
||||
<footer class="pt-8 max-w-prose print:hidden">
|
||||
{{ partial "article-pagination.html" . }}
|
||||
{{ if .Params.showComments | default (site.Params.article.showComments | default false) }}
|
||||
{{ if templates.Exists "partials/comments.html" }}
|
||||
<div class="pt-3">
|
||||
<hr class="border-dotted border-neutral-300 dark:border-neutral-600" />
|
||||
<div class="pt-3">
|
||||
{{ partial "comments.html" . }}
|
||||
</div>
|
||||
</div>
|
||||
{{ else }}
|
||||
{{ warnf "[BLOWFISH] Comments are enabled for %s but no comments partial exists." .File.Path }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</footer>
|
||||
</article>
|
||||
{{ end }}
|
||||
|
||||
{{ define "SingleAuthor" }}
|
||||
<div class="max-w-prose">
|
||||
{{ $authorsData := site.Data.authors }}
|
||||
{{ $baseURL := site.BaseURL }}
|
||||
{{ $isAuthorBottom := (.Params.showAuthorBottom | default ( site.Params.article.showAuthorBottom | default false)) }}
|
||||
{{ if not (strings.HasSuffix $baseURL "/") }}{{ $baseURL = delimit (slice $baseURL "/") "" }}{{ end }}
|
||||
{{ $authorsData := hugo.Data.authors }}
|
||||
{{ $taxonomies := site.Taxonomies.authors }}
|
||||
{{ $baseURL := site.BaseURL }}
|
||||
{{ $taxonomyLink := 0 }}
|
||||
{{ $showAuthor := 0 }}
|
||||
{{ $isAuthorBottom := (.Params.showAuthorBottom | default ( site.Params.article.showAuthorBottom | default false)) }}
|
||||
|
||||
{{ if .Params.showAuthor | default (site.Params.article.showAuthor | default true) }}
|
||||
{{ partial "author.html" . }}
|
||||
{{ end }}
|
||||
{{ if not (strings.HasSuffix $baseURL "/") }}
|
||||
{{ $baseURL = delimit (slice $baseURL "/") "" }}
|
||||
{{ end }}
|
||||
|
||||
{{ range $author := .Page.Params.authors }}
|
||||
{{ $authorData := index $authorsData $author }}
|
||||
{{ if $authorData }}
|
||||
{{ $link := printf "%sauthors/%s/" $baseURL $author }}
|
||||
{{ partial "author-extra.html" (dict "context" . "data" $authorData "link" $link) }}
|
||||
{{ if .Params.showAuthor | default (site.Params.article.showAuthor | default true) }}
|
||||
{{ $showAuthor = 1 }}
|
||||
{{ partial "author.html" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ range $author := .Page.Params.authors }}
|
||||
{{ $authorData := index $authorsData $author }}
|
||||
{{- if $authorData -}}
|
||||
{{ range $taxonomyname, $taxonomy := $taxonomies }}
|
||||
{{ if (eq $taxonomyname $author) }}
|
||||
{{ $taxonomyLink = delimit (slice $baseURL "authors/" $author "/") "" }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ $finalLink := $taxonomyLink }}
|
||||
{{ $currentLang := site.Language.Name }}
|
||||
{{ if eq site.LanguagePrefix "" }}
|
||||
{{ $finalLink = printf "%sauthors/%s/" $baseURL $author }}
|
||||
{{ else }}
|
||||
{{ $finalLink = printf "%s%s/authors/%s/" $baseURL $currentLang $author }}
|
||||
{{ end }}
|
||||
{{ partial "author-extra.html" (dict "context" . "data" $authorData "link" $finalLink) }}
|
||||
{{- end -}}
|
||||
{{ end }}
|
||||
|
||||
{{ if or $taxonomyLink $showAuthor }}
|
||||
<div class="{{ cond $isAuthorBottom "mb-10" "mb-5" }}"></div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
Reference in New Issue
Block a user