{"id":6219,"date":"2026-06-18T21:28:46","date_gmt":"2026-06-18T21:28:46","guid":{"rendered":"https:\/\/developer.wordpress.org\/news\/?p=6219"},"modified":"2026-06-18T21:28:46","modified_gmt":"2026-06-18T21:28:46","slug":"dynamically-loading-template-parts-in-block-themes","status":"publish","type":"post","link":"https:\/\/developer.wordpress.org\/news\/2026\/06\/dynamically-loading-template-parts-in-block-themes\/","title":{"rendered":"Dynamically loading template parts in block themes"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">My team and I have been working on a music-related WordPress project. For the project, I needed a way to display a different sidebar depending on what page the site visitor was viewing. It\u2019s a question that comes up from time to time from block theme authors.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In classic themes, this always felt straightforward: you just dropped your logic for loading a different template part right in the template itself. While there are architectural design issues with putting logic code in templates\u2014which are largely irrelevant for this post\u2014it simply worked. You could call <code>get_sidebar()<\/code>, <code>get_header()<\/code>, <code>get_footer()<\/code>, or <code>get_template_part()<\/code> and pass any variable to the functions\u2019 parameters to get what you needed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For block themes, you cannot do that in HTML-based templates. Even in PHP-registered patterns, you don\u2019t have access to most data before they are processed (patterns are registered on <code>init<\/code>), so contextually loading <a href=\"https:\/\/developer.wordpress.org\/themes\/templates\/template-parts\/\">template parts<\/a> won\u2019t work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The answer for block themes has been to use multiple top-level templates. Create a template for this category, another one for that tag, a third for something else entirely. It works, but it also means maintaining a growing pile of nearly identical templates that differ only in which template part they load.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There&#8217;s a better way. WordPress lets you intercept block data before it renders and swap out a template part&#8217;s slug on the fly\u2014replacing a default template part with a context-specific one. And while my use case is sidebars, the same technique works for any template part: headers, footers, banners, comments sections, whatever your theme needs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This tutorial will walk you through how to build this system, starting with the core filter and expanding into broader use cases.<\/p>\n\n\n\n<div class=\"wp-block-group has-light-grey-2-background-color has-background is-layout-flow wp-block-group-is-layout-flow\" style=\"border-radius:2px;margin-top:var(--wp--preset--spacing--30);margin-bottom:var(--wp--preset--spacing--30);padding-top:var(--wp--preset--spacing--30);padding-right:var(--wp--preset--spacing--30);padding-bottom:var(--wp--preset--spacing--30);padding-left:var(--wp--preset--spacing--30)\">\n<p class=\"has-large-font-size wp-block-paragraph\" style=\"font-style:normal;font-weight:600;line-height:1\">Table of Contents<\/p>\n\n\n\n<nav aria-label=\"Table of Contents\" class=\"wp-block-table-of-contents\"><ol><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/06\/dynamically-loading-template-parts-in-block-themes\/#the-render-block-data-filter-hook\">The render_block_data filter hook<\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/06\/dynamically-loading-template-parts-in-block-themes\/#building-the-category-based-sidebar\">Building the category-based sidebar<\/a><\/li><li><a class=\"wp-block-table-of-contents__entry\" href=\"https:\/\/developer.wordpress.org\/news\/2026\/06\/dynamically-loading-template-parts-in-block-themes\/#setting-up-the-template-parts\">Setting up the template parts<\/a><\/li><\/ol><\/nav>\n<\/div>\n\n\n\n<h2 id=\"the-render-block-data-filter-hook\" class=\"wp-block-heading\">The <code>render_block_data<\/code> filter hook<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/developer.wordpress.org\/reference\/hooks\/render_block_data\/\"><code>render_block_data<\/code><\/a> filter hook fires just before any block is rendered. It gives you the parsed block data as an array\u2014including the block name and its attributes\u2014and lets you modify that data before WordPress does anything with it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the Template Part block (<a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/core-blocks\/core-blocks-theme\/core-block-template-part\/\"><code>core\/template-part<\/code><\/a>), the most useful attribute is <code>slug<\/code>, which tells WordPress which template part file to load. Change that slug, and WordPress loads a completely different template part.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the filter signature:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">add_filter( 'render_block_data', 'themeslug_render_template_part_data' );\n\nfunction themeslug_render_template_part_data( array $parsed_block ): array \n{\n\t\/\/ Your logic here.\n\treturn $parsed_block;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The key rule: always return <code>$parsed_block<\/code>, whether you&#8217;ve modified it or not. This filter runs for every block on the page, so the first thing you&#8217;ll want to do in any implementation is bail early for blocks you don&#8217;t care about.<\/p>\n\n\n\n<h2 id=\"building-the-category-based-sidebar\" class=\"wp-block-heading\">Building the category-based sidebar<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s walk through a concrete example. For the music project, it only needed a sidebar on single post views, named <code>sidebar-post.html<\/code> (located in the\u00a0 theme\u2019s <code>\/parts<\/code> folder), so this is a narrow use case that we can look at.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In my theme\u2019s <code>templates\/single-post.html<\/code> file, the sidebar template is called via this markup:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"markup\" class=\"language-markup\">&lt;!-- wp:template-part {\"slug\":\"sidebar-post\"} \/--&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s what the normal template part looks like when viewing the site:<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6a39ece5a2c7e&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6a39ece5a2c7e\" class=\"wp-block-image alignwide size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"2048\" height=\"2271\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part.webp\" alt=\"Single blog post view from a music article. It has a title and image that spans in a wide width across the screen, sitting above two columns. Content on the left and a sidebar on the right (showing the latest posts and a subscription form).\" class=\"wp-image-6221\" srcset=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part.webp 2048w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-271x300.webp 271w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-767x851.webp 767w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-923x1024.webp 923w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-1385x1536.webp 1385w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-1847x2048.webp 1847w\" sizes=\"auto, (max-width: 2048px) 100vw, 2048px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">As shown above, it displays the latest posts and a subscription button. But for this project, I needed single post sidebars to display different data for two additional scenarios:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>sidebar-post-artist-spotlight.html<\/code>: Artist Spotlight category<\/li>\n\n\n\n<li><code>sidebar-post-album-reviews.html<\/code>: Album Reviews category<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s the full filter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">add_filter( 'render_block_data', 'themeslug_render_template_part_data' );\n\nfunction themeslug_render_template_part_data( array $parsed_block ): array \n{\n\t\/\/ Only target the Template Part block with a `sidebar-post` slug and\n\t\/\/ when viewing a single post.\n\tif (\n\t\t( $parsed_block['blockName'] ?? '' ) !== 'core\/template-part'\n\t\t|| ( $parsed_block['attrs']['slug'] ?? '' ) !== 'sidebar-post'\n\t\t|| ! is_singular( 'post' )\n\t) {\n\t\treturn $parsed_block;\n\t}\n\n\t$post = get_queried_object();\n\n\tif ( ! $post instanceof WP_Post ) {\n\t\treturn $parsed_block;\n\t}\n\n\t\/\/ Get the directory where template parts live.\n\t$parts_dir = get_block_theme_folders()['wp_template_part'];\n\n\t\/\/ Loop through the post's categories and look for a matching template part.\n\tforeach ( get_the_category( $post-&gt;ID ) as $category ) {\n\t\t$slug = \"sidebar-post-{$category-&gt;slug}\";\n\n\t\tif ( locate_template( \"{$parts_dir}\/{$slug}.html\" ) ) {\n\t\t\t$parsed_block['attrs']['slug'] = $slug;\n\t\t\treturn $parsed_block;\n\t\t}\n\t}\n\n\t\/\/ No category-specific part found; return the original unchanged.\n\treturn $parsed_block;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There are a few things worth calling out in this code.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The early return checks at the top are important. This filter fires for every block on every page, so you want to exit as fast as possible for anything that doesn&#8217;t match your criteria:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The block name is <code>core\/template-part<\/code>.<\/li>\n\n\n\n<li>The slug name is <code>sidebar-post<\/code>.<\/li>\n\n\n\n<li>The user is currently viewing a singular post.<\/li>\n\n\n\n<li>The current queried object is a <code>WP_Post<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The call to <code>get_block_theme_folders()['wp_template_part']<\/code> returns the directory your theme uses for template parts\u2014by default <code>parts<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Notice that if no category-specific template part is found, the function returns <code>$parsed_block<\/code> without modifying it. That means WordPress loads the original <code>sidebar-post.html<\/code>\u2014the one defined in the template itself. You get the fallback behavior for free, without any extra logic.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The loop through <code>get_the_category()<\/code> also handles priority automatically. If a post belongs to multiple categories, the categories are returned in term order. The first matching template part file wins. If you need a different priority order, you can sort the categories however you like before iterating.<\/p>\n\n\n\n<h2 id=\"setting-up-the-template-parts\" class=\"wp-block-heading\">Setting up the template parts<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For this system to work, you need the template part files in place. At minimum, you need the default <code>parts\/sidebar-post.html<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then add category-specific versions as needed:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>parts\/sidebar-post-author-spotlight.html<\/code><\/li>\n\n\n\n<li><code>parts\/sidebar-post-album-reviews.html<\/code><\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Only create the ones you actually need. If <code>sidebar-post-author-spotlight.html<\/code> doesn&#8217;t exist, the loop skips it and keeps checking. This is what makes the system resilient: you don&#8217;t have to create a template part for every possible category, only the ones where you want something different.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My block markup for <code>sidebar-post.html<\/code> looks like the following, but yours should fit your theme:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"markup\" class=\"language-markup\">&lt;!-- wp:group {\"style\":{\"layout\":{\"selfStretch\":\"fit\",\"flexSize\":null}},\"layout\":{\"type\":\"flex\",\"orientation\":\"vertical\",\"justifyContent\":\"stretch\"}} --&gt;\n&lt;div class=\"wp-block-group\"&gt;\n\n\t&lt;!-- wp:group {\"className\":\"is-style-section-3\",\"style\":{\"spacing\":{\"blockGap\":\"var:preset|spacing|40\"}},\"layout\":{\"type\":\"flex\",\"orientation\":\"vertical\"}} --&gt;\n\t&lt;div class=\"wp-block-group is-style-section-3\"&gt;\n\n\t\t&lt;!-- wp:heading {\"level\":3,\"className\":\"is-style-text-widget-heading\"} --&gt;\n\t\t&lt;h3 class=\"wp-block-heading is-style-text-widget-heading\"&gt;Latest Posts&lt;\/h3&gt;\n\t\t&lt;!-- \/wp:heading --&gt;\n\n\t\t&lt;!-- wp:query {\"queryId\":3,\"query\":{\"perPage\":3,\"pages\":0,\"offset\":0,\"postType\":\"post\",\"order\":\"desc\",\"orderBy\":\"date\",\"author\":\"\",\"search\":\"\",\"exclude\":[],\"sticky\":\"ignore\",\"inherit\":false,\"taxQuery\":null,\"parents\":[],\"format\":[]},\"className\":\"is-style-query-numbered\"} --&gt;\n\t\t&lt;div class=\"wp-block-query is-style-query-numbered\"&gt;\n\n\t\t\t&lt;!-- wp:post-template {\"style\":{\"spacing\":{\"blockGap\":\"var:preset|spacing|40\"}},\"layout\":{\"type\":\"default\"}} --&gt;\n\t\t\t\t\n\t\t\t\t&lt;!-- wp:group {\"style\":{\"spacing\":{\"blockGap\":\"var:preset|spacing|20\"}},\"layout\":{\"type\":\"constrained\"}} --&gt;\n\t\t\t\t&lt;div class=\"wp-block-group\"&gt;\n\t\t\t\t\t\n\t\t\t\t\t&lt;!-- wp:post-title {\"level\":3,\"isLink\":true} \/--&gt;\n\n\t\t\t\t\t&lt;!-- wp:group {\"className\":\"is-style-meta\",\"style\":{\"spacing\":{\"blockGap\":\"var:preset|spacing|10\"}},\"fontSize\":\"3-xs\",\"layout\":{\"type\":\"flex\",\"flexWrap\":\"nowrap\"}} --&gt;\n\t\t\t\t\t&lt;div class=\"wp-block-group is-style-meta has-3-xs-font-size\"&gt;\n\t\t\t\t\t\t&lt;!-- wp:post-date {\"format\":\"human-diff\",\"metadata\":{\"bindings\":{\"datetime\":{\"source\":\"core\/post-data\",\"args\":{\"field\":\"date\"}}}}} \/--&gt;\n\t\t\t\t\t&lt;\/div&gt;\n\t\t\t\t\t&lt;!-- \/wp:group --&gt;\n\t\t\t\t\n\t\t\t\t&lt;\/div&gt;\n\t\t\t\t&lt;!-- \/wp:group --&gt;\n\t\t\t\n\t\t\t&lt;!-- \/wp:post-template --&gt;\n\t\t\n\t\t&lt;\/div&gt;\n\t\t&lt;!-- \/wp:query --&gt;\n\t\n\t&lt;\/div&gt;\n\t&lt;!-- \/wp:group --&gt;\n\n\t&lt;!-- wp:group {\"style\":{\"spacing\":{\"blockGap\":\"var:preset|spacing|30\"}},\"layout\":{\"type\":\"flex\",\"orientation\":\"vertical\",\"justifyContent\":\"stretch\"}} --&gt;\n\t&lt;div class=\"wp-block-group\"&gt;\n\t\t\n\t\t&lt;!-- wp:paragraph {\"className\":\"is-style-default\",\"style\":{\"typography\":{\"textAlign\":\"center\"}},\"fontSize\":\"3-xs\",\"fontFamily\":\"mono\"} --&gt;\n\t\t&lt;p class=\"has-text-align-center is-style-default has-mono-font-family has-3-xs-font-size\"&gt;Join 12K Subscribers&lt;\/p&gt;\n\t\t&lt;!-- \/wp:paragraph --&gt;\n\n\t\t&lt;!-- wp:buttons --&gt;\n\t\t&lt;div class=\"wp-block-buttons\"&gt;\n\t\t\t&lt;!-- wp:button {\"width\":100} --&gt;\n\t\t\t&lt;div class=\"wp-block-button has-custom-width wp-block-button__width-100\"&gt;&lt;a class=\"wp-block-button__link wp-element-button\"&gt;Subscribe&lt;\/a&gt;&lt;\/div&gt;\n\t\t\t&lt;!-- \/wp:button --&gt;\n\t\t&lt;\/div&gt;\n\t\t&lt;!-- \/wp:buttons --&gt;\n\t\n\t&lt;\/div&gt;\n\t&lt;!-- \/wp:group --&gt;\n\t\n&lt;\/div&gt;\n&lt;!-- \/wp:group --&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>sidebar-post-artist-spotlight.html<\/code> and <code>sidebar-post-album-reviews.html<\/code> could be entirely different, showcasing whatever content you wanted.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here\u2019s a screenshot of the Album Reviews sidebar in action:<\/p>\n\n\n\n<figure data-wp-context=\"{&quot;imageId&quot;:&quot;6a39ece5a410b&quot;}\" data-wp-interactive=\"core\/image\" data-wp-key=\"6a39ece5a410b\" class=\"wp-block-image alignwide size-full wp-lightbox-container\"><img loading=\"lazy\" decoding=\"async\" width=\"2048\" height=\"2772\" data-wp-class--hide=\"state.isContentHidden\" data-wp-class--show=\"state.isContentVisible\" data-wp-init=\"callbacks.setButtonStyles\" data-wp-on--click=\"actions.showLightbox\" data-wp-on--load=\"callbacks.setButtonStyles\" data-wp-on--pointerdown=\"actions.preloadImage\" data-wp-on--pointerenter=\"actions.preloadImageWithDelay\" data-wp-on--pointerleave=\"actions.cancelPreload\" data-wp-on-window--resize=\"callbacks.setButtonStyles\" src=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-album-review.webp\" alt=\"Single blog post view from a music article about an album. It has a title and image that spans in a wide width across the screen, sitting above two columns. Content on the left and a sidebar on the right (showing an album spotlight and a subscription form).\" class=\"wp-image-6223\" srcset=\"https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-album-review.webp 2048w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-album-review-222x300.webp 222w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-album-review-768x1039.webp 768w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-album-review-757x1024.webp 757w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-album-review-1135x1536.webp 1135w, https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/sidebar-template-part-album-review-1513x2048.webp 1513w\" sizes=\"auto, (max-width: 2048px) 100vw, 2048px\" \/><button\n\t\t\tclass=\"lightbox-trigger\"\n\t\t\ttype=\"button\"\n\t\t\taria-haspopup=\"dialog\"\n\t\t\tdata-wp-bind--aria-label=\"state.thisImage.triggerButtonAriaLabel\"\n\t\t\tdata-wp-init=\"callbacks.initTriggerButton\"\n\t\t\tdata-wp-on--click=\"actions.showLightbox\"\n\t\t\tdata-wp-style--right=\"state.thisImage.buttonRight\"\n\t\t\tdata-wp-style--top=\"state.thisImage.buttonTop\"\n\t\t>\n\t\t\t<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"12\" height=\"12\" fill=\"none\" viewBox=\"0 0 12 12\">\n\t\t\t\t<path fill=\"#fff\" d=\"M2 0a2 2 0 0 0-2 2v2h1.5V2a.5.5 0 0 1 .5-.5h2V0H2Zm2 10.5H2a.5.5 0 0 1-.5-.5V8H0v2a2 2 0 0 0 2 2h2v-1.5ZM8 12v-1.5h2a.5.5 0 0 0 .5-.5V8H12v2a2 2 0 0 1-2 2H8Zm2-12a2 2 0 0 1 2 2v2h-1.5V2a.5.5 0 0 0-.5-.5H8V0h2Z\" \/>\n\t\t\t<\/svg>\n\t\t<\/button><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For this case, the <code>sidebar-post-album-reviews.html<\/code> part is connected to a music album that\u2019s being reviewed. This is handled via a custom Query block variation and post meta. To learn more about that technique, read <a href=\"https:\/\/developer.wordpress.org\/news\/2022\/12\/building-a-book-review-grid-with-a-query-loop-block-variation\/\">Building a book review grid with a Query Loop block variation<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The important piece is that this didn\u2019t require a custom single post template for each category. I only needed to add a template part for the section of the page that needed to change. This reduces code duplication.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>render_block_data<\/code> filter doesn&#8217;t get nearly enough attention in the block theme space. It&#8217;s a clean, low-footprint way to make your theme layouts genuinely dynamic without duplicating templates. Once you have the pattern down, you&#8217;ll find yourself reaching for it for all sorts of things\u2014not just sidebars.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Give it a try and see what you come up with.<\/p>\n\n\n\n<p class=\"has-text-align-right wp-block-paragraph\"><em>Props to <a href='https:\/\/profiles.wordpress.org\/bph\/' class='mention'><span class='mentions-prefix'>@<\/span>bph<\/a>, <a href='https:\/\/profiles.wordpress.org\/areziaal\/' class='mention'><span class='mentions-prefix'>@<\/span>areziaal<\/a>, <a href='https:\/\/profiles.wordpress.org\/welcher\/' class='mention'><span class='mentions-prefix'>@<\/span>welcher<\/a>, and <a href='https:\/\/profiles.wordpress.org\/juanmaguitar\/' class='mention'><span class='mentions-prefix'>@<\/span>juanmaguitar<\/a> for feedback on this article.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Stop duplicating WordPress block theme templates just to load different sidebar content. Learn how to use the render_block_data filter to dynamically swap template parts based on post category, page context, or any conditional logic \u2014 no extra templates required.<\/p>\n","protected":false},"author":20482,"featured_media":6226,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"edge","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"jetpack_post_was_ever_published":false},"categories":[38],"tags":[],"class_list":["post-6219","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-themes","mentions-areziaal","mentions-bph","mentions-juanmaguitar","mentions-welcher"],"revision_note":"","jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/developer.wordpress.org\/news\/files\/2026\/06\/dynamic-template-parts.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts\/6219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/users\/20482"}],"replies":[{"embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/comments?post=6219"}],"version-history":[{"count":4,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts\/6219\/revisions"}],"predecessor-version":[{"id":6229,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/posts\/6219\/revisions\/6229"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/media\/6226"}],"wp:attachment":[{"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/media?parent=6219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/categories?post=6219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/developer.wordpress.org\/news\/wp-json\/wp\/v2\/tags?post=6219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}