PRC's override/extension of the WordPress core/heading block.
prc-block/core-heading
Target Block: core/heading
- Changes the default heading level from H2 to H4
- Adds "chapter/section" functionality for table of contents integration
- Adds an alternate TOC text attribute for overriding what appears in the table of contents
- Registers "Heading" (default, H4), "Section" (chapter heading), and "Layout Heading" variations
- Registers "Layout Heading", "Hidden", and Sub-title block styles
- Registers a Sub-title block binding that reads/writes the
sub_titlepost meta field (replaces the deprecatedprc-block/sub-titleblock) - Cleans up auto-generated heading IDs (removes
h-prefix, converts leading numbers to words) - Generates reproducible IDs for headings without anchors
- Integrates chapter headings with
prc-block/table-of-contentsInteractivity API state - Handles legacy chapter detection for posts published before March 2023
- Provides transforms from legacy
[chapter]shortcode andprc-block/chapterblock
None directly via supports. However, the default heading level is changed to 4 via block_type_metadata_settings.
| Attribute | Type | Default | Description |
|---|---|---|---|
isChapter |
boolean |
false |
Marks the heading as a section/chapter heading for TOC inclusion |
altTocText |
string |
'' |
Alternate text to display in the table of contents instead of the heading content |
Registered both server-side (block_type_metadata) and client-side (blocks.registerBlockType).
Additional context consumed:
| Context Key | Description |
|---|---|
postId |
Used for legacy chapter heading detection |
prcLegacyChapter |
Set to true for posts before March 2023 |
| Style Name | Label | Description |
|---|---|---|
layout-heading |
Layout Heading | Black bottom border with 4px padding and 24px margin |
hidden |
Hidden | Visually hidden (0px font, 0 opacity, 0 height) on frontend; 50% opacity in editor |
sub-title |
Sub-title | Smaller, secondary heading style for post subtitles |
The deprecated prc-block/sub-title block was migrated to a bound core/heading with the Sub-title style. Producers insert a heading, apply the Sub-title style, and bind its content to the sub_title post meta field via the block bindings UI.
Binding source: prc-block/core-heading/sub-title (registered in block-bindings.js and class-core-heading.php).
Post meta: sub_title — registered with show_in_rest and single => true so the binding is editable in the block editor and persists through REST saves (including RTC).
Rendering rules (render_sub_title_heading):
- Bound headings outside
core/post-content(e.g. in single templates) render the livesub_titlemeta value. - Bound headings inside
core/post-contentare suppressed to avoid duplicating the template subtitle. - Empty or whitespace-only meta renders nothing.
Migration: Legacy prc-block/sub-title blocks remain in deprecated/src/sub-title/ for backward compatibility. New content should use the bound heading pattern above.
From style.scss:
Hidden style: On the frontend, headings with is-style-hidden (excluding editor context) get zero font size, zero opacity, zero height. In the editor, they display at 50% opacity.
Layout heading: is-style-layout-heading gets a 1px solid black bottom border, 4px bottom padding, 24px bottom margin.
Sub-title style: is-style-sub-title applies the secondary heading typography defined in style.scss (used by the sub-title block binding).
Legacy section-header: Same visual treatment as layout-heading (backward compatibility).
Sub-header alt: Black background with white text, display block.
From index.js and controls.jsx:
- Wraps block edit with custom controls via
createHigherOrderComponent - Toolbar: Adds a book-alt icon toggle with labels Make Chapter / Remove Chapter to set
isChapter. When turning a heading into a chapter, ifgetAnchorFromContent(content)yields a slug, the block also sets theanchorattribute so the fragment ID matches the heading text. - Inspector Advanced Controls: When
isChapteris true, shows an Alternate TOC Text text field (placeholder shows current headingcontent). - Anchor sync (H3 and H4): For heading levels 3 and 4, a
useEffectkeeps theanchorattribute aligned withgetAnchorFromContent(content)when the heading text changes or when the level switches into H3/H4 (same slug rules as below). Other levels do not receive automatic anchor updates from content. getAnchorFromContent(src/core-heading/utils.js): derives a URL slug from the raw RichTextcontent— decode HTML entities, strip tags (inserting a space at tag boundaries so words do not run together), collapse whitespace, thencleanForSlug. Covered bysrc/core-heading/test/utils.test.js.- Registers transforms from legacy blocks
- Registers three block variations
No dedicated view.js. Interactivity is handled server-side by injecting attributes on chapter headings that integrate with the prc-block/table-of-contents store.
Class: Core_Heading
Key behaviors:
-
ID cleanup: Removes
h-prefix from auto-generated IDs. Converts leading numbers to words (e.g.,h-5-thingsbecomesfive-things). Falls back to an MD5 hash of block content for reproducible IDs. -
Legacy chapter detection: For the first heading in
core/post-content, checks if the post date is before March 2023. If so, setsprcLegacyChaptercontext totrue, which auto-marks H3 headings as chapters. -
Table of contents integration: When
isChapteris true:- Registers the heading in
wp_interactivity_state('prc-block/table-of-contents')undersectionsFound - Uses
altTocTextas the TOC label if provided, otherwise strips tags from heading content - Adds
data-is-section="true"attribute - Adds
data-wp-interactiveanddata-wp-contextfor TOC interactivity
- Registers the heading in
-
Context filter:
check_if_legacy_chapter_headingruns once per post to determine legacy status, avoiding repeated database lookups.
<!-- Standard heading (H4 default) -->
<h4 class="wp-block-heading" id="survey-methodology">Survey Methodology</h4>
<!-- Chapter/section heading with TOC integration -->
<h3
class="wp-block-heading"
id="key-findings"
data-is-section="true"
data-wp-interactive='{"namespace":"prc-block/table-of-contents"}'
data-wp-context='{"id":"key-findings"}'
>
Key Findings
</h3>
<!-- Layout heading -->
<h3 class="wp-block-heading is-style-layout-heading">Related Reports</h3>
<!-- Hidden heading (accessibility only) -->
<h4 class="wp-block-heading is-style-hidden">Screen reader only text</h4>| Variation Name | Title | Description | Default Level |
|---|---|---|---|
heading |
Heading | Default heading variation | H4 |
section |
Section | Chapter/section heading included in TOC | H3 |
layout-heading |
Layout Heading | Heading with bottom border styling | H3 |
| Source | Type | Description |
|---|---|---|
[chapter] shortcode |
Shortcode | Converts [chapter title="..."] to H2 chapter heading |
prc-block/chapter |
Block | Converts legacy chapter block to heading with isChapter: true |
core/shortcode containing [chapter] |
Block | Extracts title and creates H2 chapter heading |