From 03b489faffdbec177bfa757577c02abed0e085d5 Mon Sep 17 00:00:00 2001 From: James Petty Date: Tue, 11 Aug 2026 13:58:47 -0400 Subject: [PATCH] Make article headings linkable (#52) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a Goldmark heading render hook that renders each Markdown heading with its auto-generated id plus a hover-revealed anchor link, so any article section can be linked to and shared. IDs still come from .Anchor, so existing in-page `#section` links keep working, and author `{.class}` attributes (e.g. .wp-block-heading) are preserved. - themes/.../_markup/render-heading.html — the render hook - themes/.../static/css/heading-anchors.css — hover styling + scroll-margin to clear the sticky header; loaded async alongside the other theme CSS - single.html — the in-article smooth-scroll handler now also updates the URL hash, so clicking a section link makes it copyable from the address bar fa-link is already in the icon subset, so generated assets are unchanged. Closes #52 Co-Authored-By: Claude Opus 4.8 --- .../layouts/_default/baseof.html | 3 +- .../layouts/_default/single.html | 9 +++-- .../layouts/_markup/render-heading.html | 14 ++++++++ .../static/css/heading-anchors.css | 35 +++++++++++++++++++ 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 themes/powershell-community/layouts/_markup/render-heading.html create mode 100644 themes/powershell-community/static/css/heading-anchors.css diff --git a/themes/powershell-community/layouts/_default/baseof.html b/themes/powershell-community/layouts/_default/baseof.html index 1a2bb90aa..9e5211d20 100644 --- a/themes/powershell-community/layouts/_default/baseof.html +++ b/themes/powershell-community/layouts/_default/baseof.html @@ -111,7 +111,8 @@ {{- $asyncCSS := slice "https://cdnjs.cloudflare.com/ajax/libs/prism/1.24.1/themes/prism-tomorrow.min.css" "/css/alerts.css" - "/css/code-copy.css" -}} + "/css/code-copy.css" + "/css/heading-anchors.css" -}} {{- with .Site.Params.algolia }}{{ $asyncCSS = $asyncCSS | append "https://cdn.jsdelivr.net/npm/@algolia/algoliasearch-netlify-frontend@1/dist/algoliasearchNetlify.css" }}{{ end -}} {{ range $asyncCSS }} diff --git a/themes/powershell-community/layouts/_default/single.html b/themes/powershell-community/layouts/_default/single.html index 0a0b22c5b..70075db00 100644 --- a/themes/powershell-community/layouts/_default/single.html +++ b/themes/powershell-community/layouts/_default/single.html @@ -207,13 +207,16 @@

}); } - // Smooth scrolling for anchor links within the article + // Smooth scrolling for anchor links within the article. Also update the + // URL hash so a linked section is shareable/copyable from the address bar. document.querySelectorAll('.prose a[href^="#"]').forEach(anchor => { anchor.addEventListener('click', function (e) { - e.preventDefault(); - const target = document.querySelector(this.getAttribute('href')); + const hash = this.getAttribute('href'); + const target = document.querySelector(hash); if (target) { + e.preventDefault(); target.scrollIntoView({ behavior: 'smooth', block: 'start' }); + history.pushState(null, '', hash); } }); }); diff --git a/themes/powershell-community/layouts/_markup/render-heading.html b/themes/powershell-community/layouts/_markup/render-heading.html new file mode 100644 index 000000000..852cf2df4 --- /dev/null +++ b/themes/powershell-community/layouts/_markup/render-heading.html @@ -0,0 +1,14 @@ +{{- /* Heading render hook: makes article headings directly linkable. + Renders the heading with its auto-generated id (from .Anchor, i.e. + Goldmark's autoHeadingID) plus a hover-revealed anchor link, so any + section can be linked to and shared. Because the id still comes from + .Anchor, pre-existing `#section` links keep resolving unchanged. + The `{.class}` attribute authors add (e.g. .wp-block-heading) is + preserved. Styling lives in static/css/heading-anchors.css. */ -}} +{{- $id := .Anchor -}} +{{- $class := "ps-heading" -}} +{{- with .Attributes.class }}{{ $class = printf "%s %s" $class . }}{{ end -}} + + {{- .Text | safeHTML -}} + + diff --git a/themes/powershell-community/static/css/heading-anchors.css b/themes/powershell-community/static/css/heading-anchors.css new file mode 100644 index 000000000..dfb7fa5e7 --- /dev/null +++ b/themes/powershell-community/static/css/heading-anchors.css @@ -0,0 +1,35 @@ +/* Linkable article headings — a hover-revealed anchor link next to each + heading. Rendered by layouts/_markup/render-heading.html. */ + +.ps-heading { + position: relative; + /* Clear the sticky site header (bg-white shadow-lg sticky top-0) when + jumping to an anchor so the heading isn't hidden underneath it. */ + scroll-margin-top: 5.5rem; +} + +.ps-heading-anchor { + opacity: 0; + margin-left: 0.4em; + font-size: 0.7em; + color: #9ca3af; + text-decoration: none; + vertical-align: middle; + transition: opacity 0.15s ease, color 0.15s ease; +} + +.ps-heading:hover .ps-heading-anchor, +.ps-heading-anchor:focus-visible { + opacity: 1; +} + +.ps-heading-anchor:hover { + color: #2563eb; +} + +/* Touch devices can't hover — keep the anchor discoverable but subtle. */ +@media (hover: none) { + .ps-heading-anchor { + opacity: 0.5; + } +}