Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lib: Add template part CPTs and their theme resolution logic. #18339

Merged
merged 1 commit into from
Nov 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function gutenberg_is_experiment_enabled( $name ) {

require dirname( __FILE__ ) . '/blocks.php';
require dirname( __FILE__ ) . '/templates.php';
require dirname( __FILE__ ) . '/template-parts.php';
require dirname( __FILE__ ) . '/template-loader.php';
require dirname( __FILE__ ) . '/client-assets.php';
require dirname( __FILE__ ) . '/block-directory.php';
Expand Down
38 changes: 38 additions & 0 deletions lib/template-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,40 @@ function gutenberg_override_query_template( $template, $type, array $templates =
return '';
}

/**
* Recursively traverses a block tree, creating auto drafts
* for any encountered template parts without a fixed post.
*
* @access private
*
* @param array $block The root block to start traversing from.
*/
function create_auto_draft_for_template_part_block( $block ) {
if ( 'core/template-part' === $block['blockName'] && ! isset( $block['attrs']['id'] ) ) {
$template_part_file_path =
get_stylesheet_directory() . '/block-template-parts/' . $block['attrs']['slug'] . '.html';
if ( ! file_exists( $template_part_file_path ) ) {
return;
}
wp_insert_post(
array(
'post_content' => file_get_contents( $template_part_file_path ),
'post_title' => ucfirst( $block['attrs']['slug'] ),
'post_status' => 'auto-draft',
'post_type' => 'wp_template_part',
'post_name' => $block['attrs']['slug'],
'meta_input' => array(
'theme' => $block['attrs']['theme'],
),
)
);
}

foreach ( $block['innerBlocks'] as $inner_block ) {
create_auto_draft_for_template_part_block( $inner_block );
}
}

/**
* Find the correct 'wp_template' post for the current hierarchy and return the path
* to the canvas file that will render it.
Expand Down Expand Up @@ -147,6 +181,10 @@ function gutenberg_find_template( $template_file ) {
$current_template_post = get_post(
wp_insert_post( $current_template_post )
);

foreach ( parse_blocks( $current_template_post->post_content ) as $block ) {
create_auto_draft_for_template_part_block( $block );
}
} else {
$current_template_post = new WP_Post(
(object) $current_template_post
Expand Down
118 changes: 118 additions & 0 deletions lib/template-parts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
/**
* Block template part functions.
*
* @package gutenberg
*/

/**
* Registers block editor 'wp_template_part' post type.
*/
function gutenberg_register_template_part_post_type() {
if ( ! gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing' ) ) {
return;
}

$labels = array(
'name' => __( 'Template Parts', 'gutenberg' ),
'singular_name' => __( 'Template Part', 'gutenberg' ),
'menu_name' => _x( 'Template Parts', 'Admin Menu text', 'gutenberg' ),
'add_new' => _x( 'Add New', 'Template Part', 'gutenberg' ),
'add_new_item' => __( 'Add New Template Part', 'gutenberg' ),
'new_item' => __( 'New Template Part', 'gutenberg' ),
'edit_item' => __( 'Edit Template Part', 'gutenberg' ),
'view_item' => __( 'View Template Part', 'gutenberg' ),
'all_items' => __( 'All Template Parts', 'gutenberg' ),
'search_items' => __( 'Search Template Parts', 'gutenberg' ),
'parent_item_colon' => __( 'Parent Template Part:', 'gutenberg' ),
'not_found' => __( 'No template parts found.', 'gutenberg' ),
'not_found_in_trash' => __( 'No template parts found in Trash.', 'gutenberg' ),
'archives' => __( 'Template part archives', 'gutenberg' ),
'insert_into_item' => __( 'Insert into template part', 'gutenberg' ),
'uploaded_to_this_item' => __( 'Uploaded to this template part', 'gutenberg' ),
'filter_items_list' => __( 'Filter template parts list', 'gutenberg' ),
'items_list_navigation' => __( 'Template parts list navigation', 'gutenberg' ),
'items_list' => __( 'Template parts list', 'gutenberg' ),
);

$args = array(
'labels' => $labels,
'description' => __( 'Template parts to include in your templates.', 'gutenberg' ),
'public' => false,
'has_archive' => false,
'show_ui' => true,
'show_in_menu' => 'themes.php',
'show_in_admin_bar' => false,
'show_in_rest' => true,
'map_meta_cap' => true,
'supports' => array(
'title',
'slug',
'editor',
'revisions',
),
);

$meta_args = array(
'object_subtype' => 'wp_template_part',
'type' => 'string',
'description' => 'The theme that provided the template part, if any.',
'single' => true,
'show_in_rest' => true,
);

register_post_type( 'wp_template_part', $args );
register_meta( 'post', 'theme', $meta_args );
}
add_action( 'init', 'gutenberg_register_template_part_post_type' );

/**
* Fixes the label of the 'wp_template_part' admin menu entry.
*/
function gutenberg_fix_template_part_admin_menu_entry() {
global $submenu;
if ( ! isset( $submenu['themes.php'] ) ) {
return;
}
$post_type = get_post_type_object( 'wp_template_part' );
if ( ! $post_type ) {
return;
}
foreach ( $submenu['themes.php'] as $key => $submenu_entry ) {
if ( $post_type->labels->all_items === $submenu['themes.php'][ $key ][0] ) {
$submenu['themes.php'][ $key ][0] = $post_type->labels->menu_name; // phpcs:ignore WordPress.WP.GlobalVariablesOverride
break;
}
}
}
add_action( 'admin_menu', 'gutenberg_fix_template_part_admin_menu_entry' );

/**
* Filters the 'wp_template_part' post type columns in the admin list table.
*
* @param array $columns Columns to display.
* @return array Filtered $columns.
*/
function gutenberg_filter_template_part_list_table_columns( array $columns ) {
$columns['slug'] = __( 'Slug', 'gutenberg' );
if ( isset( $columns['date'] ) ) {
unset( $columns['date'] );
}
return $columns;
}
add_filter( 'manage_wp_template_part_posts_columns', 'gutenberg_filter_template_part_list_table_columns' );

/**
* Renders column content for the 'wp_template_part' post type list table.
*
* @param string $column_name Column name to render.
* @param int $post_id Post ID.
*/
function gutenberg_render_template_part_list_table_column( $column_name, $post_id ) {
if ( 'slug' !== $column_name ) {
return;
}
$post = get_post( $post_id );
echo esc_html( $post->post_name );
}
add_action( 'manage_wp_template_part_posts_custom_column', 'gutenberg_render_template_part_list_table_column', 10, 2 );