Adding Page Creation Patterns to Custom Block Patterns Admin UI

Dev note as of 8/21/23:
With the addition of “synced patterns” in WordPress 6.3, this method is no longer needed.

In this post I show how I create an admin UI for creating and managing block patterns directly within the WordPress dashboard (ie. no code). This post will build directly off of that code to add the ability to set specific block patterns as page creation patterns.

Nick Diego gives a great overview of page creation patterns in his post on WPEngine’s blog. I’ll use the register_block_pattern method mentioned in his post (and in my original post) to conditionally add page creation patterns using my own custom Block Pattern UI.

Add “Enable Pattern Creation” Boolean

The first thing we need to do is extend on the ACF field group to add a boolean (true/false) field to enable the page creation pattern. Below is the full local field group registration code. Note that lines 137-155 have been added to create the new boolean. I’ve also editing the title of the field group to “Block Pattern Options” instead of the original “Block Pattern Categories”.

<?php
// register the ACF field group
acf_add_local_field_group(
     [
          'key'    => 'group_61a8f5eb8dc40',
          'title'  => 'Block Pattern Options',
          'fields' => [
               [
                    'key'               => 'field_61a8f608a61fa',
                    'label'             => 'Block Pattern Categories',
                    'name'              => 'wd_block_pattern_categories',
                    'type'              => 'checkbox',
                    'instructions'      => '',
                    'required'          => 0,
                    'conditional_logic' => 0,
                    'choices'           => $block_pattern_categories,
                    'allow_custom'      => 0,
                    'default_value'     => [],
                    'layout'            => 'vertical',
                    'toggle'            => 0,
                    'return_format'     => 'value',
                    'save_custom'       => 0,
                    'wrapper' => [
                         'width' => '',
                         'class' => '',
                         'id'    => '',
                    ],
               ],
               [
                    'key'               => 'field_631b432effe37',
                    'label'             => 'Enable Creation Pattern',
                    'name'              => 'wd_block_patterns_enable_starter_pattern',
                    'type'              => 'true_false',
                    'instructions'      => 'Set this pattern as a creation pattern for pages.',
                    'required'          => 0,
                    'conditional_logic' => 0,
                    'message'           => '',
                    'default_value'     => 0,
                    'ui_on_text'        => '',
                    'ui_off_text'       => '',
                    'ui'                => 1,
                    'wrapper' => [
                         'width' => '',
                         'class' => '',
                         'id'    => '',
                    ],
               ],
          ],
          'location' => [
               [
                    [
                         'param'    => 'post_type',
                         'operator' => '==',
                         'value'    => 'block_pattern',
                    ]
               ]
          ],
          'menu_order'            => 0,
          'position'              => 'side',
          'style'                 => 'default',
          'label_placement'       => 'top',
          'instruction_placement' => 'label',
          'hide_on_screen'        => '',
          'active'                => true,
          'description'           => '',
          'show_in_rest'          => 0,
     ]
);

Conditionally set block pattern at page creation patterns

Next, we’ll edit the block registration function to check the status of the enable pattern boolean and enable the page creation pattern.

<?php
/*
 * Register Block Patterns
 */
add_action( 'admin_init', 'wd_register_block_patterns' );
function wd_register_block_patterns() {

     if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {

          $loop = new WP_Query(
               [
                    'post_type'      => 'block_pattern',
                    'post_status'    => 'publish',
                    'posts_per_page' => -1,
               ]
          );

          if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();

               $post_title = get_the_title();
               $post_slug = str_replace( ' ', '-', strtolower( $post_title ) );
               $post_content = get_the_content();
               $enable_starter_pattern = get_field( 'wd_block_patterns_enable_starter_pattern', get_the_ID() );
               $blockTypes = $enable_starter_pattern == 1 ? 'core/post-content' : '';
               $block_pattern_categories = get_field( 'wd_block_pattern_categories', get_the_ID() );

               register_block_pattern(
                    'wd/' . $post_slug,
                    [
                         'title'      => $post_title,
                         'blockTypes' => [ $blockTypes ],
                         'content'    => trim( $post_content ),
                         'categories' => $block_pattern_categories,
                         'keywords'   => [
                              $post_title,
                              'pattern',
                              'block pattern',
                         ]
                    ]
               );

          endwhile; endif; wp_reset_postdata();
     }
}

Let’s take a look at the changes to this function:

  • Line 214 – Pull in the value of the new enable patterns creation boolean (wd_block_patterns_enable_starter_pattern)
  • Set blockTypes variable to ‘core/post-content’ if the enable patterns boolean is true (this sets the pattern as a page creation pattern)
  • add blockTypes attribute to register_block_pattern function

Wrapping it Up

That’s all there is to it! You can now set any block pattern as a page creation pattern with the click of a toggle. Check it out below:

As noted in Nick’s post, this is only available for Pages currently. Once WordPress core adds support for posts and custom post types I’ll update this post to add options to add block patterns as page creation patterns for not only pages, but posts and custom post type as well.

Here is the fully updated code:

<?php
/**
 * Setup front end UI for Block Patterns
 *
 * @author       WhiteleyDesigns
 * @since        1.0.0
 * @license      GPL-2.0+
 **/

/*
 * Register Block Patterns Custom Post Type
 */
add_action( 'init', 'wd_register_cpt_block_pattern' );
function wd_register_cpt_block_pattern() {

     $labels = [
          'name'               => _x( 'Block Pattern', 'post type general name', WD_PLUGIN_THEME_SLUG ),
          'singular_name'      => _x( 'Block Pattern', 'post type singular name', WD_PLUGIN_THEME_SLUG ),
          'menu_name'          => _x( 'Block Patterns', 'admin menu', WD_PLUGIN_THEME_SLUG ),
          'name_admin_bar'     => _x( 'Block Pattern', 'add new on admin bar', WD_PLUGIN_THEME_SLUG ),
          'add_new'            => _x( 'Add New', 'Block Pattern', WD_PLUGIN_THEME_SLUG ),
          'add_new_item'       => __( 'Add New Block Pattern', WD_PLUGIN_THEME_SLUG ),
          'new_item'           => __( 'New Block Pattern', WD_PLUGIN_THEME_SLUG ),
          'edit_item'          => __( 'Edit Block Pattern', WD_PLUGIN_THEME_SLUG ),
          'view_item'          => __( 'View Block Pattern', WD_PLUGIN_THEME_SLUG ),
          'all_items'          => __( 'All Block Patterns', WD_PLUGIN_THEME_SLUG ),
          'search_items'       => __( 'Search Block Patterns', WD_PLUGIN_THEME_SLUG ),
          'parent_item_colon'  => __( 'Parent Block Patterns:', WD_PLUGIN_THEME_SLUG ),
          'not_found'          => __( 'No Block Patterns found.', WD_PLUGIN_THEME_SLUG ),
          'not_found_in_trash' => __( 'No Block Patterns found in Trash.', WD_PLUGIN_THEME_SLUG )
     ];

     $args = [
          'labels'              => $labels,
          'description'         => __( 'Block Patterns.', WD_PLUGIN_THEME_SLUG ),
          'public'              => false,
          'exclude_from_search' => true,
          'publicly_queryable'  => true,
          'show_ui'             => true,
          'show_in_menu'        => true,
          'query_var'           => true,
          'capability_type'     => 'post',
          'has_archive'         => false,
          'hierarchical'        => false,
          'menu_position'       => 290,
          'menu_icon'           => 'dashicons-screenoptions',
          'show_in_rest'        => true,
          'supports'            => [
               'title',
               'editor',
               'revisions',
          ],
          'rewrite' => [
               'slug'       => 'block-pattern',
               'with_front' => false,
          ],
     ];

     register_post_type(
          'block_pattern',
          $args
     );
}


/**
 * Add custom block pattern categories
 */
function wd_register_block_pattern_categories() {

     if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {

          register_block_pattern_category(
               'whiteley-designs',
               [
                    'label' => _x( 'Whiteley Designs', 'Block pattern category', WD_PLUGIN_THEME_SLUG ),
               ]
          );

     }
}
add_action( 'init', 'wd_register_block_pattern_categories' );


/**
 * Remove core block patterns
 */
remove_theme_support( 'core-block-patterns' );


/**
 * Create categories metabox
 *
 * @link https://www.advancedcustomfields.com/resources/register-fields-via-php/
 */
add_action( 'acf/init', 'wd_add_block_patterns_acf_metabox' );
function wd_add_block_patterns_acf_metabox() {

     // set array of categories to offer
     $block_pattern_categories = [
          'buttons'          => 'Buttons', // core
          'columns'          => 'Columns', // core
          'gallery'          => 'Gallery', // core
          'header'           => 'Headers', // core
          'text'             => 'Text', // core
          // 'query'            => 'Query', // core
          'whiteley-designs' => 'Whiteley Designs', // custom
     ];

     // register the ACF field group
     acf_add_local_field_group(
          [
               'key'    => 'group_61a8f5eb8dc40',
               'title'  => 'Block Pattern Options',
               'fields' => [
                    [
                         'key'               => 'field_61a8f608a61fa',
                         'label'             => 'Block Pattern Categories',
                         'name'              => 'wd_block_pattern_categories',
                         'type'              => 'checkbox',
                         'instructions'      => '',
                         'required'          => 0,
                         'conditional_logic' => 0,
                         'choices'           => $block_pattern_categories,
                         'allow_custom'      => 0,
                         'default_value'     => [],
                         'layout'            => 'vertical',
                         'toggle'            => 0,
                         'return_format'     => 'value',
                         'save_custom'       => 0,
                         'wrapper' => [
                              'width' => '',
                              'class' => '',
                              'id'    => '',
                         ],
                    ],
                    [
                         'key'               => 'field_631b432effe37',
                         'label'             => 'Enable Creation Pattern',
                         'name'              => 'wd_block_patterns_enable_starter_pattern',
                         'type'              => 'true_false',
                         'instructions'      => 'Set this pattern as a creation pattern for pages.',
                         'required'          => 0,
                         'conditional_logic' => 0,
                         'message'           => '',
                         'default_value'     => 0,
                         'ui_on_text'        => '',
                         'ui_off_text'       => '',
                         'ui'                => 1,
                         'wrapper' => [
                              'width' => '',
                              'class' => '',
                              'id'    => '',
                         ],
                    ],
               ],
               'location' => [
                    [
                         [
                              'param'    => 'post_type',
                              'operator' => '==',
                              'value'    => 'block_pattern',
                         ]
                    ]
               ],
               'menu_order'            => 0,
               'position'              => 'side',
               'style'                 => 'default',
               'label_placement'       => 'top',
               'instruction_placement' => 'label',
               'hide_on_screen'        => '',
               'active'                => true,
               'description'           => '',
               'show_in_rest'          => 0,
          ]
     );
}


/*
 * Redirect single posts to home page
 */
add_action( 'template_redirect', 'wd_block_patterns_cpt_redirect_single' );
function wd_block_patterns_cpt_redirect_single() {

     if ( is_singular( 'block_pattern' ) ) {
          wp_redirect( get_home_url() );
          exit;
     }
}


/*
 * Register Block Patterns
 */
add_action( 'admin_init', 'wd_register_block_patterns' );
function wd_register_block_patterns() {

     if ( class_exists( 'WP_Block_Patterns_Registry' ) ) {

          $loop = new WP_Query(
               [
                    'post_type'      => 'block_pattern',
                    'post_status'    => 'publish',
                    'posts_per_page' => -1,
               ]
          );

          if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();

               $post_title = get_the_title();
               $post_slug = str_replace( ' ', '-', strtolower( $post_title ) );
               $post_content = get_the_content();
               $enable_starter_pattern = get_field( 'wd_block_patterns_enable_starter_pattern', get_the_ID() );
               $blockTypes = $enable_starter_pattern == 1 ? 'core/post-content' : '';
               $block_pattern_categories = get_field( 'wd_block_pattern_categories', get_the_ID() );

               register_block_pattern(
                    'wd/' . $post_slug,
                    [
                         'title'      => $post_title,
                         'blockTypes' => [ $blockTypes ],
                         'content'    => trim( $post_content ),
                         'categories' => $block_pattern_categories,
                         'keywords'   => [
                              $post_title,
                              'pattern',
                              'block pattern',
                         ]
                    ]
               );

          endwhile; endif; wp_reset_postdata();
     }
}

Comments

  1. RS says:

    Thank you! This is a great tutorial and very useful!
    The page creation patterns are working for only Pages, how can we make it work in other Custom Post Types?

    1. Matt Whiteley says:

      Hey RS,

      I mentioned this in the post – “As noted in Nick’s post, this is only available for Pages currently. Once WordPress core adds support for posts and custom post types I’ll update this post to add options to add block patterns as page creation patterns for not only pages, but posts and custom post type as well.”

      As soon as it is added to WordPress core and not just the Gutenberg plugin, I’ll update this post showing how to do it with post and custom post types.

      Cheers!

      Matt

      1. RS says:

        Thank you! Hopefully, this can be added to WordPress core and not just the Gutenberg plugin, it’s a great feature!

        1. Matt Whiteley says:

          Hey! FYI – this is now available and I wrote an update post for it – https://whiteleydesigns.com/extended-page-creation-patterns-to-posts-and-custom-post-types/.

          Cheers!

          Matt

          1. RS says:

            Thank you so much!

  2. RS says:

    Hello,

    I can see that we can now create block patterns from the Admin UI with “synced patterns”, but those block patterns are not appearing the page creation pattern modal. Is there something that we need to enable for those block patterns (created with “synced patterns”) to appear in the modal?

    thanks!

    1. Matt Whiteley says:

      Hey!

      As of now, I don’t know of a way to allow patterns to show as “page creation patterns” since the updates. I haven’t delved into it deeply, so it may be doable, but I don’t have an answer for that yet. If I do figure it out and dig into it I will update this article and reply to your comment here.

      Cheers!

      Matt

      1. RS says:

        Thank you so much!

Leave a Reply

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