How Block Theme Templates Load
Block themes follow the same initial bootstrap process as classic themes, but diverge at the template resolution stage to support block-based templates.
Core Loading Flow
wp-blog-header.phpis the entry point for every front-end request.It loads
wp-includes/template-loader.php, which determines which template should render the current request.Based on the query type, a corresponding function is called:
get_single_template()for single posts or CPTsget_page_template()for pagesget_archive_template()for archives
These functions internally call
get_query_template()to resolve the correct template file.
Template Resolution Logic
get_query_template() attempts to locate the appropriate template using:
$template = locate_template( $templates );
For block themes, it also calls:
$template = locate_block_template( $template, $type, $templates );
Block Template Resolution
Inside locate_block_template():
if ( ! current_theme_supports( 'block-templates' ) ) {
return $template;
}
- Block themes automatically support
block-templatesvia:
add_action( 'setup_theme', 'wp_enable_block_templates' );
- The function
resolve_block_template()is used to fetch the appropriate template.
$block_template = resolve_block_template( $type, $templates, $template );
If a block template is found:
- It returns an instance of
WP_Block_Template - The global variable
$_wp_current_template_contentis populated
- It returns an instance of
global $_wp_current_template_content;
$_wp_current_template_content = $block_template->content;
- Instead of returning a theme file, it returns:
return ABSPATH . WPINC . '/template-canvas.php';
Rendering via Template Canvas
The file wp-includes/template-canvas.php is responsible for rendering block templates.
<?php
/**
* Template canvas loader
*/
get_header();
echo get_the_block_template_html();
get_footer();
Block Template Rendering
The function get_the_block_template_html():
- Parses block markup from
$_wp_current_template_content - Renders dynamic blocks
- Outputs final HTML
It ensures standard WordPress hooks are executed:
wp_head();
body_class();
wp_body_open();
wp_footer();
Fallback Behavior
- If a block template is found → it is used
- If not → falls back to classic PHP templates via
locate_template()
Templates and Template Parts
Block themes use HTML-based templates and reusable template parts to define layout and structure.
Templates
Templates define the full structure of a page and are stored in:
/templates/
Examples:
templates/index.html
templates/single.html
templates/archive.html
templates/page.html
Template Parts
Reusable sections like headers and footers are stored in:
/parts/
Examples:
parts/header.html
parts/footer.html
parts/sidebar.html
Including Template Parts
Template parts are included using block markup:
<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
Replacing Default Blocks in Templates
To customize prebuilt templates, override them in your theme.
Example: Replace a Query Loop block in index.html
<!-- wp:query {"query":{"perPage":5}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-excerpt /-->
<!-- /wp:post-template -->
</div>
<!-- /wp:query -->
You can modify block attributes or replace blocks entirely.
Creating Templates for Custom Post Types
To create a template for a custom post type (e.g., movie):
File:
templates/single-movie.html
Example:
<!-- wp:template-part {"slug":"header"} /-->
<!-- wp:group -->
<div class="wp-block-group">
<!-- wp:post-title /-->
<!-- wp:post-featured-image /-->
<!-- wp:post-content /-->
</div>
<!-- /wp:group -->
<!-- wp:template-part {"slug":"footer"} /-->
Registering Custom Post Type (for context)
function register_movie_cpt() {
register_post_type( 'movie', [
'label' => 'Movies',
'public' => true,
'show_in_rest' => true,
'has_archive' => true,
] );
}
add_action( 'init', 'register_movie_cpt' );
Template Hierarchy in Block Themes
Block themes follow a similar hierarchy to classic themes, but use .html files:
single-{post-type}.htmlsingle.htmlindex.html