diff --git a/data/structures/section-title.yml b/data/structures/section-title.yml index 6d1ef5e6..2140613a 100644 --- a/data/structures/section-title.yml +++ b/data/structures/section-title.yml @@ -12,6 +12,24 @@ arguments: class: size: use-title: + heading-level: + type: int + optional: true + release: v3.19.0 + comment: >- + Heading level of the title, from 1 (h1) to 6 (h6). Defaults to 0, which + renders a div instead of a heading. Content blocks receive a level from + the page that renders them, so the first titled block of a page without a + page header becomes its h1. + heading-class: + type: string + optional: true + release: v3.19.0 + comment: >- + Classes for the heading element, applied only when a heading level renders + one. Replaces the margin reset that otherwise keeps a title raised by + heading-level aligned with the div it succeeds; pass an empty string to + leave the element on its own styling. justify: link-type: use-section: diff --git a/layouts/_partials/assets/section-title.html b/layouts/_partials/assets/section-title.html index 6af5f2ec..a331d199 100644 --- a/layouts/_partials/assets/section-title.html +++ b/layouts/_partials/assets/section-title.html @@ -43,32 +43,67 @@ {{- if and (not $preheading) $args.useSection }}{{ $preheading = $page.CurrentSection.Name }}{{ end -}} {{- $justify := cond (eq $args.justify "start") "" (cond (eq $args.justify "end") "me-0" "mx-auto") -}} +{{/* Read the heading level. An explicit heading-level wins, the legacy use-title boolean maps onto + level 1, and a caller that asks for neither keeps the div this partial has always rendered. */}} +{{- $level := $args.headingLevel -}} +{{- $levelled := ne $level nil -}} +{{- if not $levelled }}{{ $level = cond $args.useTitle 1 0 }}{{ end -}} +{{- if or (lt $level 0) (gt $level 6) -}} + {{- partial "utilities/LogWarn.html" (dict + "partial" "assets/section-title.html" + "warnid" "warn-invalid-heading-level" + "msg" (printf "Heading level %d is out of range, falling back to a div" $level) + "details" (slice "Use a level between 1 and 6, or 0 to render a div") + "file" $page.File + ) -}} + {{- $level = 0 -}} +{{- end -}} + +{{/* Classes for the heading element. A caller-supplied heading-class always wins, including an + empty string, which leaves the element on its own styling. Without one, a heading-level title + resets the margins that a heading carries and the div it replaces does not, plus the weight + and line height that the "fs" heading style leaves to Bootstrap; a use-title title keeps the + styling the h1 has always had. */}} +{{- $headingClass := "" -}} +{{- if isset $args "headingClass" -}} + {{- $headingClass = $args.headingClass -}} +{{- else if $levelled -}} + {{- $headingClass = "mt-0 mb-0" -}} + {{- if eq $headingStyle "fs" }}{{ $headingClass = printf "%s fw-normal lh-base" $headingClass }}{{ end -}} +{{- end -}} + {{ $preheading = partial "utilities/TitleCase.html" (dict "page" $page "text" $preheading) }} {{ $title = partial "utilities/TitleCase.html" (dict "page" $page "text" $title) }} +{{/* Composes the title element. The tag varies with the heading level, and Go's template engine + rejects a dynamic element name, so the markup is assembled as a string and marked safe. */}} {{ define "_partials/assets/section-title-header.html" }} - {{- $page := .page }} - {{ $headingStyle := .headingStyle }} - - {{ if (index . "use-title") }} - {{ $title := .title | $page.RenderString }} - {{ $label := trim (replaceRE "\r\n?|\n" " " ($title | plainify)) " " }} -