Let’s be honest: most clients don’t want a blank canvas when they click “Add New.” They want a magic button that gently hands them a perfectly styled, semi-filled-out page that doesn’t make them think too hard. And you know what? That’s our job. We’re not just developers anymore—we’re cognitive load reducers.

Years ago before Gutenberg the answer would have been to create a .php template for each page layout, which the client would have utilized by filling out custom fields, which gave them no idea of what the final product would look like. This guaranteed more work for developers when the marketing team wanted to tweak the design, but it also created frustration with the limits of using WordPress as a CMS.

In this post, I’m going to show you how to give your clients a better starting point when creating a new post in a custom post type (CPT). The trick? Leveraging patterns and Synced Patterns created right inside WordPress and loading them automatically as the initial content for your CPTs. Maximum flexibility for the editors, minimum setup every time they start a new entry.

Sidenote: this is for classic and hybrid themes, rather than “block themes” using full site editing. If you’re doing that, I recommend reading this article on creating templates for custom post types.


The Goal

We want to:

  • Set up a block template for a CPT (like customer_story) that gives the user a full layout as a starting point.
  • Allow this layout to be editable by site admins through the WordPress UI (no theme redeploys required).
  • Retain design consistency by combining this with nested Synced Patterns and Synced Pattern Overrides.

What Doesn’t Work (and Why)

You might be tempted to reference your UI-created pattern using the core/pattern block and its slug:

array( 'core/pattern', array( 'slug' => 'customer-story-content-template' ) )

Seems logical. But this only works if your pattern was registered in code using register_block_pattern() or added to your theme’s /patterns directory. Patterns created in the admin UI? No registered slug. So WordPress just shrugs and shows a “Pattern Placeholder” block. Useless.

The Real Fix: Use core/block with a Ref ID

When you create a pattern through the admin, it gets saved as a wp_block post. To insert that into your post template, use the core/block block type with a ref that points to the pattern’s post ID. Like this:

array( 'core/block', array( 'ref' => 4939 ) )

Boom. That pulls the full pattern content into the post editor.

To make this dynamic, because hardcoding IDs is for cowboys, and also the ID will change if you import the json into a different file, you can fetch the block post by title:

function get_pattern_id_by_title( $title ) {
    $patterns = get_posts( array(
        'post_type'   => 'wp_block',
        'post_status' => 'publish',
        'title'       => $title,
        'numberposts' => 1,
    ) );

    return ! empty( $patterns ) ? $patterns[0]->ID : false;
}

Now in your CPT registration:

$pattern_id = get_pattern_id_by_title( 'Customer Story Content Template' );

$template = $pattern_id ? [
    [ 'core/block', [ 'ref' => $pattern_id ] ]
] : [];

register_post_type( 'customer_story', [
    'label' => 'Customer Stories',
    'public' => true,
    'show_in_rest' => true,
    'supports' => [ 'title', 'editor', 'thumbnail' ],
    'template' => $template,
    'template_lock' => false,
] );

This works well when you’re developing across multiple environments, and instead of doing database syncing, you’re importing the pattern jsons. The only disadvantage to this method is that it’ll break if anyone changes the title. So if you want a backup, you can replace line 3 through 5 above with the following.

if ( false === $pattern_id ) {
	// Default to production pattern ID if not found.
	$template = array(
		array(
			'core/block',
			array(
				'ref' => 5028,
			),
		),
	);
} else {
	$template = array(
		array(
			'core/block',
			array(
				'ref' => $pattern_id,
			),
		),
	);
}

Why This Is Good for Clients

Your clients now get:

  • A consistent, helpful starting layout
  • Editable patterns via the admin
  • The ability to change the pattern for future posts without a dev

And you? You reduce repetitive questions and emergency layout tweaks. Plus, you’re making it much harder for some shiny new CMS (cough Webflow cough) to poach your client with a fancier interface.

Bonus: Combine With Synced Pattern Overrides

Want to make this even tighter? Use Synced Pattern Overrides to inject editable fields into a reusable layout. Editors keep flexibility, designers keep consistency.

Here’s an example of what I’ve implemented recently, with 2 nested synced patterns within a larger unsynced pattern, which is used a starting point template for the Customer Story CPT.

In the sidebar, in the section labeled “Customer Story Sidebar Top” it’s important to use symantec H3 elements, which have special styling for this section. I don’t want the editors to be able to change the H level, or mess with the styling. So by designating this heading element as a synced pattern override element, the editor can change the text value, and that’s about it. Freedom within constraints.

But Wait: My Pattern Was Unsynced… Why Can’t I Edit It?

Here’s a curveball: even if your parent pattern is not synced (confirmed in Appearance > Patterns, or via the post meta), when you inject it via core/block, WordPress treats it as a reusable block. That means you still have to manually detach it before editing.

Why? Because that’s how core/block works: it references a saved pattern post by ID, and the editor treats the whole thing as a reusable block until you say otherwise.

Even worse? If you’re nesting synced patterns (e.g., CTA buttons or feature layouts) inside your unsynced layout, those inner patterns remain synced, meaning users can’t just start typing.

UX Strategy: Educate and Override

Until WordPress gives us a detach_on_insert flag (hint hint), here are your best options:

  • Add an instructional block at the top of the pattern that tells editors: “Click the three dots and choose Detach from Pattern before editing.”
  • Name the pattern clearly, like: “Customer Story Layout (Detach to edit).”
  • Use Synced Pattern Overrides for your inner blocks, so users can customize individual fields (like text and images) without breaking the layout.

This lets you build a layered system:

  • Unsynced top-level pattern (for CPT starter template)
  • Synced nested patterns (for layout + style)
  • Overrides for editable fields

Result: clients get structure, consistency, and flexibility.

For clarity, here’s the final result of one of these patterns implemented on a production site:

Final Thoughts

Curating the editing experience is about more than just aesthetics—it’s about creating an interface your clients actually enjoy using. The more friction you remove, the more loyalty you gain.

Injecting backend-created patterns into CPT templates gives you the best of both worlds: reliable starting layouts and the freedom for site admins to evolve them over time. Just remember: don’t fight the block editor. Make it work for you.

And yes, all of this is subject to change as WordPress evolves—so keep an eye on the Block Editor Handbook and maybe check back here once detach_on_insert is a thing (🙏).


Need a deeper dive into custom block templates, pattern registration, or block locking strategies? The Block Editor Handbook is your new best friend.

Or hit me up—I live for this stuff

Leave a Reply

Your email address will not be published. Required fields are marked *

Post comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.