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:
2026-06-06 19:26:33 +00:00
Unverified
parent d329fe9dfb
commit 835b118d1a
443 changed files with 33405 additions and 1220 deletions

View File

@@ -0,0 +1,165 @@
{{- $role := .Get "role" -}}
{{- $collection := .Get "collection" -}}
{{- $apiURL := "" -}}
{{- $repoLink := "" -}}
{{- $type := "" -}}
{{- $namespace := "" -}}
{{- $name := "" -}}
{{- if $role -}}
{{- $parts := split $role "." -}}
{{- $namespace = index $parts 0 -}}
{{- $name = index $parts 1 -}}
{{- $apiURL = print "https://galaxy.ansible.com/api/v1/roles/?owner__username=" $namespace "&name=" $name -}}
{{- $repoLink = print "https://galaxy.ansible.com/ui/standalone/roles/" $namespace "/" $name "/" -}}
{{- $type = "role" -}}
{{- else if $collection -}}
{{- $parts := split $collection "." -}}
{{- $namespace = index $parts 0 -}}
{{- $name = index $parts 1 -}}
{{- $apiURL = print "https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/index/" $namespace "/" $name "/" -}}
{{- $repoLink = print "https://galaxy.ansible.com/ui/repo/published/" $namespace "/" $name "/" -}}
{{- $type = "collection" -}}
{{- end -}}
{{ $id := delimit (slice "ansible" (partial "functions/uid.html" .)) "-" }}
{{- $title := "" -}}
{{- $description := "" -}}
{{- $downloads := 0 -}}
{{- $version := "" -}}
{{- $tags := slice -}}
{{- $license := "" -}}
{{- $dataAvailable := false -}}
{{- /* Formats an integer with comma thousand separators (lang.NumFmt is unavailable in this template context). */ -}}
{{- define "_format-int" -}}
{{- $n := printf "%d" (int .) -}}
{{- $out := "" -}}
{{- $len := len $n -}}
{{- range $i := seq $len -}}
{{- $idx := sub $i 1 -}}
{{- $c := substr $n $idx 1 -}}
{{- if and (gt $idx 0) (eq (mod (sub $len $idx) 3) 0) -}}
{{- $out = print $out "," $c -}}
{{- else -}}
{{- $out = print $out $c -}}
{{- end -}}
{{- end -}}
{{- $out -}}
{{- end -}}
{{- with try (resources.GetRemote $apiURL) -}}
{{- with .Err -}}
{{- warnf "ansible shortcode: failed to fetch remote resource from %q: %s" $apiURL $.Position -}}
{{- else with .Value -}}
{{- $resp := . | transform.Unmarshal -}}
{{- if eq $type "role" -}}
{{- with index ($resp.results | default slice) 0 -}}
{{- $title = print $namespace "." .name -}}
{{- $description = .description -}}
{{- $downloads = .download_count -}}
{{- with .summary_fields -}}
{{- with index (.versions | default slice) 0 -}}
{{- $version = .name -}}
{{- end -}}
{{- $tags = .tags -}}
{{- end -}}
{{- $dataAvailable = true -}}
{{- end -}}
{{- else if eq $type "collection" -}}
{{- $title = print $namespace "." $name -}}
{{- $downloads = $resp.download_count -}}
{{- with $resp.highest_version -}}
{{- $version = .version -}}
{{- end -}}
{{- if $version -}}
{{- $versionURL := print $apiURL "versions/" $version "/" -}}
{{- with try (resources.GetRemote $versionURL) -}}
{{- with .Value -}}
{{- $verResp := . | transform.Unmarshal -}}
{{- with $verResp.metadata -}}
{{- $description = .description -}}
{{- $tags = .tags -}}
{{- with .license -}}
{{- $license = index . 0 -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- $dataAvailable = true -}}
{{- end -}}
{{- else -}}
{{- warnf "ansible shortcode: unable to get remote resource from %q: %s" $apiURL $.Position -}}
{{- end -}}
{{- end -}}
{{- if $dataAvailable -}}
<div class="ansible-card-wrapper">
<a id="{{ $id }}" target="_blank" href="{{ $repoLink }}" class="cursor-pointer">
<div
class="w-full md:w-auto pt-3 p-5 border border-neutral-200 dark:border-neutral-700 border rounded-md shadow-2xl">
<div class="flex items-center">
<span class="text-2xl text-neutral-800 dark:text-neutral mr-2">
{{ partial "icon.html" "ansible" }}
</span>
<div
class="m-0 font-bold text-xl text-neutral-800 decoration-primary-500 hover:underline hover:underline-offset-2 dark:text-neutral">
{{ $title }}
</div>
</div>
{{- if $description }}
<p class="m-0 mt-2 text-md text-neutral-800 dark:text-neutral">
{{ $description | markdownify }}
</p>
{{- end }}
<div class="m-0 mt-2 flex items-center flex-wrap">
<span class="rounded-md border border-primary-400 px-1 py-[1px] mr-3 text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">
{{ $type }}
</span>
<span class="text-md mr-2 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "download" }}
</span>
<div class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ template "_format-int" $downloads }}
</div>
{{- if $version }}
<span class="text-md mr-2 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "tag" }}
</span>
<div class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ $version }}
</div>
{{- end }}
{{- if $license }}
<span class="text-md mr-2 text-neutral-800 dark:text-neutral">
{{ partial "icon.html" "scale-balanced" }}
</span>
<div class="m-0 mr-5 text-md text-neutral-800 dark:text-neutral">
{{ $license }}
</div>
{{- end }}
</div>
{{- if $tags }}
<div class="m-0 mt-2 flex flex-wrap gap-1">
{{- range first 5 $tags }}
<span
class="rounded-md border border-neutral-300 px-1 py-[1px] text-xs font-normal text-neutral-700 dark:border-neutral-600 dark:text-neutral-300">
{{ . }}
</span>
{{- end }}
</div>
{{- end }}
</div>
</a>
</div>
{{- else if $apiURL -}}
{{ warnf "ansible shortcode: unable to fetch %q: %s" $apiURL .Position }}
{{- end -}}