Skip to content

fix(layouts): preserve inline HTML in title-cased body headings#1931

Merged
markdumay merged 2 commits into
mainfrom
fix/title-case-html-mangle
May 24, 2026
Merged

fix(layouts): preserve inline HTML in title-cased body headings#1931
markdumay merged 2 commits into
mainfrom
fix/title-case-html-mangle

Conversation

@markdumay
Copy link
Copy Markdown
Collaborator

_markup/render-heading.html ran (title ($text | htmlUnescape)) | htmlEscape on the heading text. Markdown-generated inline HTML such as , , , and entered that pipeline as ordinary text from Go's perspective, so the title filter capitalized the first letter inside each tag name ( -> ). The subsequent htmlEscape turned the mangled markup into entity-encoded text, leaving readers with literal "_c" in the rendered page.

Switch to a CSS-driven approach: emit a title-case class on the heading element and let the browser apply text-transform: capitalize. The underlying HTML stays intact, inline markup keeps working, and capitalization is locale-aware via the lang attribute — useful for multilingual sites where different languages prefer different casing conventions. The existing site.Params.main.titleCase toggle and the per-page exact: true opt-out are preserved.

The class-list building was unified across the two heading branches so the title-case and pre-existing heading classes (plus any IAL .Attributes.class) compose cleanly.

Only _markup/render-heading.html carried this bug. Other title-casing sites in the theme (header.html, docs/header.html, minimal/header.html, tags/list.html, _partials/head/seo.html, _partials/footer/social.html, _partials/page/taxonomy-*.html) operate on frontmatter title: strings which are plain text and unaffected.

`_markup/render-heading.html` ran `(title ($text | htmlUnescape)) | htmlEscape`
on the heading text. Markdown-generated inline HTML such as <code>,
<strong>, <em>, and <a> entered that pipeline as ordinary text from Go's
perspective, so the `title` filter capitalized the first letter inside
each tag name (<code> -> <Code>). The subsequent `htmlEscape` turned the
mangled markup into entity-encoded text, leaving readers with literal
"<Code>_c</Code>" in the rendered page.

Switch to a CSS-driven approach: emit a `title-case` class on the heading
element and let the browser apply `text-transform: capitalize`. The
underlying HTML stays intact, inline markup keeps working, and
capitalization is locale-aware via the `lang` attribute — useful for
multilingual sites where different languages prefer different casing
conventions. The existing `site.Params.main.titleCase` toggle and the
per-page `exact: true` opt-out are preserved.

The class-list building was unified across the two heading branches so
the `title-case` and pre-existing `heading` classes (plus any IAL
`.Attributes.class`) compose cleanly.

Only `_markup/render-heading.html` carried this bug. Other title-casing
sites in the theme (`header.html`, `docs/header.html`, `minimal/header.html`,
`tags/list.html`, `_partials/head/seo.html`, `_partials/footer/social.html`,
`_partials/page/taxonomy-*.html`) operate on frontmatter `title:` strings
which are plain text and unaffected.
@netlify
Copy link
Copy Markdown

netlify Bot commented May 24, 2026

Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit 0ac385c
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6a1308ed0dc1e700088dd368
😎 Deploy Preview https://deploy-preview-1931--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@markdumay markdumay merged commit d50c8c7 into main May 24, 2026
15 checks passed
@markdumay markdumay deleted the fix/title-case-html-mangle branch May 24, 2026 14:27
@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 2.10.2 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant