Blocks API
Framework for registering, parsing, and rendering block-based content in WordPress.
Since: 5.0.0
Source: wp-includes/blocks.php, wp-includes/block-editor.php, wp-includes/class-wp-block*.php
Components
| Component | Description |
|---|---|
| functions.md | Core block registration, parsing, and rendering functions |
| class-wp-block.md | Parsed block instance for rendering |
| class-wp-block-type.md | Block type definition with metadata |
| class-wp-block-type-registry.md | Block type registry singleton |
| class-wp-block-parser.md | Block content parser |
| class-wp-block-list.md | Iterable block collection |
| class-wp-block-supports.md | Block feature support system |
| class-wp-block-styles-registry.md | Block style variations registry |
| class-wp-block-template.md | Block template instance |
| class-wp-block-templates-registry.md | Block templates registry |
| hooks.md | Actions and filters |
Architecture Overview
The Blocks API is the foundation of the WordPress Block Editor (Gutenberg). It provides:
- Block Type Registration – Define block types with attributes, supports, and render callbacks
- Block Parsing – Parse HTML content containing block comment delimiters
- Block Rendering – Convert parsed blocks to final HTML output
- Block Supports – Common features like colors, spacing, typography
- Block Styles – Alternative visual styles for blocks
- Block Templates – Full-page templates built with blocks
Block Content Format
Blocks are stored as HTML with special comment delimiters:
<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">Hello World</p>
<!-- /wp:paragraph -->
<!-- wp:image {"id":123} /-->
Void blocks use self-closing syntax: <!-- wp:block-name {"attrs"} /-->
Container blocks wrap inner content or other blocks.
Registration Flow
register_block_type()
├── File path detected? → register_block_type_from_metadata()
│ ├── Load block.json
│ ├── Apply 'block_type_metadata' filter
│ ├── register_block_script_handle()
│ ├── register_block_style_handle()
│ ├── Apply 'block_type_metadata_settings' filter
│ └── WP_Block_Type_Registry::register()
│
└── Block name/type provided → WP_Block_Type_Registry::register()
└── new WP_Block_Type()
├── Apply 'register_block_type_args' filter
└── Store in registry
Parsing Flow
parse_blocks( $content )
└── WP_Block_Parser::parse()
├── Tokenize block delimiters (RegExp)
├── Build stack of WP_Block_Parser_Frame
├── Handle void-block / block-opener / block-closer
└── Return array of WP_Block_Parser_Block
└── { blockName, attrs, innerBlocks, innerHTML, innerContent }
Rendering Flow
do_blocks( $content )
├── parse_blocks()
└── For each top-level block:
render_block()
├── Apply 'pre_render_block' filter (short-circuit)
├── Apply 'render_block_data' filter
├── Apply 'render_block_context' filter
├── new WP_Block( $parsed_block, $context )
└── WP_Block::render()
├── process_block_bindings()
├── Render inner blocks (recursive)
├── Call render_callback if dynamic
├── Enqueue scripts/styles
├── Apply 'render_block' filter
├── Apply 'render_block_{$name}' filter
└── Return HTML string
Block Hooks Flow (Since 6.4.0)
Blocks can hook into other blocks at specific positions:
apply_block_hooks_to_content()
├── get_hooked_blocks()
│ └── Collect blocks with block_hooks property
│
├── make_before_block_visitor()
│ └── Insert 'before' and 'first_child' hooked blocks
│
├── make_after_block_visitor()
│ └── Insert 'after' and 'last_child' hooked blocks
│
└── traverse_and_serialize_blocks()
└── Apply visitors during serialization
Context System
Blocks can share data with descendants:
Parent Block (provides_context)
│
├── context['postId'] = 123
│
└── Child Block (uses_context: ['postId'])
└── $this->context['postId'] === 123
Block Supports
Common features are defined in block.json under supports:
{
"supports": {
"color": { "background": true, "text": true },
"spacing": { "margin": true, "padding": true },
"typography": { "fontSize": true, "lineHeight": true },
"align": ["wide", "full"],
"html": false
}
}
Supports are processed by files in wp-includes/block-supports/:
align.php– Alignmentbackground.php– Background imagesborder.php– Border stylescolors.php– Text/background colorsdimensions.php– Min/max heightduotone.php– Duotone filterselements.php– Link/button stylinglayout.php– Layout/flexposition.php– Sticky/fixed positionshadow.php– Box shadowsspacing.php– Margin/paddingtypography.php– Font settings
Key Concepts
Dynamic Blocks
Blocks with a render_callback that generates HTML at runtime:
register_block_type('my/block', [
'render_callback' => function($attributes, $content, $block) {
return '<div>' . esc_html($attributes['title']) . '</div>';
}
]);
Static Blocks
Blocks without render_callback that save their HTML directly in post content.
Block Bindings (Since 6.5.0)
Connect block attributes to external data sources:
{
"metadata": {
"bindings": {
"content": {
"source": "core/post-meta",
"args": { "key": "custom_field" }
}
}
}
}
Block Patterns
Reusable block layouts registered with register_block_pattern().
Block Variations
Alternative configurations of a block type registered via variations in block.json.