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

Use core version of template and template part post types and REST endpoints for WP 5.9, with back compat for 5.8 #36898

Merged
merged 9 commits into from
Dec 2, 2021
38 changes: 15 additions & 23 deletions lib/compat/wordpress-5.9/block-template-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
define( 'WP_TEMPLATE_PART_AREA_UNCATEGORIZED', 'uncategorized' );
}


if ( ! function_exists( 'get_block_theme_folders' ) ) {
/**
* For backward compatibility reasons,
Expand Down Expand Up @@ -197,7 +196,7 @@ function get_default_block_template_types() {
*/
function _filter_block_template_part_area( $type ) {
$allowed_areas = array_map(
function ( $item ) {
static function ( $item ) {
return $item['area'];
},
get_allowed_block_template_part_areas()
Expand Down Expand Up @@ -463,7 +462,6 @@ function _inject_theme_attribute_in_block_template_content( $template_content )
*/
function _remove_theme_attribute_in_block_template_content( $template_content ) {
$has_updated_content = false;
$new_content = '';
$template_blocks = parse_blocks( $template_content );

$blocks = _flatten_blocks( $template_blocks );
Expand All @@ -474,12 +472,8 @@ function _remove_theme_attribute_in_block_template_content( $template_content )
}
}

if ( $has_updated_content ) {
foreach ( $template_blocks as $block ) {
$new_content .= serialize_block( $block );
}

return $new_content;
if ( ! $has_updated_content ) {
return $template_content;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There were some minor changes to this function in WordPress core, so I've replicated them for Gutenberg.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this branch there is no foreach ( $template_blocks as $block ) which is something I see in the Core version. Is that right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, oops. I obviously wasn't thorough enough. Fixed in #37137.

}

return $template_content;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if is now unnecessary. In both cases we return $template_content;. Is that right?

Expand All @@ -493,26 +487,24 @@ function _remove_theme_attribute_in_block_template_content( $template_content )
* @param array $template_file Theme file.
* @param array $template_type wp_template or wp_template_part.
*
* @return WP_Block_Template Template.
* @return Gutenberg_Block_Template Template.
*/
function _build_block_template_result_from_file( $template_file, $template_type ) {
$default_template_types = get_default_block_template_types();
$template_content = file_get_contents( $template_file['path'] );
$theme = wp_get_theme()->get_stylesheet();

$template = new WP_Block_Template();
$template = new Gutenberg_Block_Template();
$template->id = $theme . '//' . $template_file['slug'];
$template->theme = $theme;
$template->content = _inject_theme_attribute_in_block_template_content( $template_content );
$template->slug = $template_file['slug'];
$template->source = 'theme';
$template->origin = null;
$template->type = $template_type;
$template->title = ! empty( $template_file['title'] ) ? $template_file['title'] : $template_file['slug'];
$template->status = 'publish';
$template->has_theme_file = true;
$template->is_custom = true;
$template->author = 0;

if ( 'wp_template' === $template_type && isset( $default_template_types[ $template_file['slug'] ] ) ) {
$template->description = $default_template_types[ $template_file['slug'] ]['description'];
Expand All @@ -538,7 +530,7 @@ function _build_block_template_result_from_file( $template_file, $template_type
*
* @param WP_Post $post Template post.
*
* @return WP_Block_Template|WP_Error Template.
* @return Gutenberg_Block_Template|WP_Error Template.
*/
function _build_block_template_result_from_post( $post ) {
$default_template_types = get_default_block_template_types();
Expand All @@ -558,7 +550,7 @@ function _build_block_template_result_from_post( $post ) {
$has_theme_file = wp_get_theme()->get_stylesheet() === $theme &&
null !== _get_block_template_file( $post->post_type, $post->post_name );

$template = new WP_Block_Template();
$template = new Gutenberg_Block_Template();
$template->wp_id = $post->ID;
$template->id = $theme . '//' . $post->post_name;
$template->theme = $theme;
Expand Down Expand Up @@ -613,7 +605,7 @@ function gutenberg_get_block_templates( $query = array(), $template_type = 'wp_t
*
* @since 10.8
*
* @param WP_Block_Template[]|null $block_templates Return an array of block templates to short-circuit the default query,
* @param Gutenberg_Block_Template[]|null $block_templates Return an array of block templates to short-circuit the default query,
* or null to allow WP to run it's normal queries.
* @param array $query {
* Optional. Arguments to retrieve templates.
Expand Down Expand Up @@ -716,7 +708,7 @@ function gutenberg_get_block_templates( $query = array(), $template_type = 'wp_t
*
* @since 10.8
*
* @param WP_Block_Template[] $query_result Array of found block templates.
* @param Gutenberg_Block_Template[] $query_result Array of found block templates.
* @param array $query {
* Optional. Arguments to retrieve templates.
*
Expand All @@ -734,7 +726,7 @@ function gutenberg_get_block_templates( $query = array(), $template_type = 'wp_t
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param array $template_type wp_template or wp_template_part.
*
* @return WP_Block_Template|null Template.
* @return Gutenberg_Block_Template|null Template.
*/
function gutenberg_get_block_template( $id, $template_type = 'wp_template' ) {
/**
Expand All @@ -744,7 +736,7 @@ function gutenberg_get_block_template( $id, $template_type = 'wp_template' ) {
*
* @since 10.8
*
* @param WP_Block_Template|null $block_template Return block template object to short-circuit the default query,
* @param Gutenberg_Block_Template|null $block_template Return block template object to short-circuit the default query,
* or null to allow WP to run it's normal queries.
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param array $template_type wp_template or wp_template_part.
Expand Down Expand Up @@ -791,7 +783,7 @@ function gutenberg_get_block_template( $id, $template_type = 'wp_template' ) {
*
* @since 10.8
*
* @param WP_Block_Template|null $block_template The found block template, or null if there isn't one.
* @param Gutenberg_Block_Template|null $block_template The found block template, or null if there isn't one.
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param array $template_type wp_template or wp_template_part.
*/
Expand All @@ -806,7 +798,7 @@ function gutenberg_get_block_template( $id, $template_type = 'wp_template' ) {
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param array $template_type wp_template or wp_template_part.
*
* @return WP_Block_Template|null File template.
* @return Gutenberg_Block_Template|null File template.
*/
function get_block_file_template( $id, $template_type = 'wp_template' ) {
/**
Expand All @@ -816,7 +808,7 @@ function get_block_file_template( $id, $template_type = 'wp_template' ) {
*
* @since 10.8
*
* @param WP_Block_Template|null $block_template Return block template object to short-circuit the default query,
* @param Gutenberg_Block_Template|null $block_template Return block template object to short-circuit the default query,
* or null to allow WP to run it's normal queries.
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param array $template_type wp_template or wp_template_part.
Expand Down Expand Up @@ -851,7 +843,7 @@ function get_block_file_template( $id, $template_type = 'wp_template' ) {
*
* @since 10.8
*
* @param null|WP_Block_Template $block_template The found block template.
* @param null|Gutenberg_Block_Template $block_template The found block template.
* @param string $id Template unique identifier (example: theme_slug//template_slug).
* @param array $template_type wp_template or wp_template_part.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* Blocks API: WP_Block_Template class
* Blocks API: Gutenberg_Block_Template class
*
* @package WordPress
* @since 5.5.0
Expand All @@ -9,7 +9,7 @@
/**
* Class representing a block template.
*/
class WP_Block_Template {
class Gutenberg_Block_Template {
Copy link
Contributor Author

@talldan talldan Dec 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed this and the situation should be:

  • If Gutenberg is running on WordPress 5.8, Gutenberg_Block_Template is used instead of WP_Block_Template`, since the latter is outdated in 5.8.
  • If Gutenberg is running on WordPress 5.9, WP_Block_Template is used.

This should resolve any issues where author or origin might not be defined on 5.8.


/**
* Type: wp_template or wp_template_part
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,8 +452,8 @@ protected function prepare_item_for_database( $request ) {
/**
* Prepare a single template output for response
*
* @param WP_Block_Template $template Template instance.
* @param WP_REST_Request $request Request object.
* @param Gutenberg_Block_Template $template Template instance.
* @param WP_REST_Request $request Request object.
*
* @return WP_REST_Response $data
*/
Expand Down
167 changes: 167 additions & 0 deletions lib/compat/wordpress-5.9/template-parts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php
/**
* Block template part functions.
*
* This is a temporary compatibility fix for WordPress 5.8.x, which is missing
* some features for template parts that are present in 5.9.
*
* Once 5.9 is the minimum supported WordPress version for the Gutenberg
* plugin, this shim can be removed.
*
* @package gutenberg
*/

// Only run any of the code in this file if the version is less than 5.9.
// wp_is_block_template_theme was introduced in 5.9.
if ( ! function_exists( 'wp_is_block_template_theme' ) ) {
/**
* Registers block editor 'wp_template_part' post type.
*/
function gutenberg_register_template_part_post_type() {
if ( ! gutenberg_supports_block_templates() ) {
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' ),
'view_items' => __( 'View Template Parts', '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' => false,
'show_in_admin_bar' => false,
'show_in_rest' => true,
'rest_base' => 'template-parts',
'rest_controller_class' => 'Gutenberg_REST_Templates_Controller',
'map_meta_cap' => true,
'supports' => array(
'title',
'slug',
'excerpt',
'editor',
'revisions',
'author',
),
);

register_post_type( 'wp_template_part', $args );
}
add_action( 'init', 'gutenberg_register_template_part_post_type' );

/**
* Registers the 'wp_template_part_area' taxonomy.
*/
function gutenberg_register_wp_template_part_area_taxonomy() {
if ( ! gutenberg_supports_block_templates() ) {
return;
}

register_taxonomy(
'wp_template_part_area',
array( 'wp_template_part' ),
array(
'public' => false,
'hierarchical' => false,
'labels' => array(
'name' => __( 'Template Part Areas', 'gutenberg' ),
'singular_name' => __( 'Template Part Area', 'gutenberg' ),
),
'query_var' => false,
'rewrite' => false,
'show_ui' => false,
'_builtin' => true,
'show_in_nav_menus' => false,
'show_in_rest' => false,
)
);
}
add_action( 'init', 'gutenberg_register_wp_template_part_area_taxonomy' );

/**
* Fixes the label of the 'wp_template_part' admin menu entry.
*/
function gutenberg_fix_template_part_admin_menu_entry() {
if ( ! gutenberg_supports_block_templates() ) {
return;
}

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' );

// Customize the `wp_template` admin list.
add_filter( 'manage_wp_template_part_posts_columns', 'gutenberg_templates_lists_custom_columns' );
add_action( 'manage_wp_template_part_posts_custom_column', 'gutenberg_render_templates_lists_custom_column', 10, 2 );
add_filter( 'views_edit-wp_template_part', 'gutenberg_filter_templates_edit_views' );

/**
* Sets a custom slug when creating auto-draft template parts.
* This is only needed for auto-drafts created by the regular WP editor.
* If this page is to be removed, this won't be necessary.
*
* @param int $post_id Post ID.
*/
function gutenberg_set_unique_slug_on_create_template_part( $post_id ) {
// This is the core function with the same functionality.
if ( function_exists( 'wp_set_unique_slug_on_create_template_part' ) ) {
return;
}

$post = get_post( $post_id );
if ( 'auto-draft' !== $post->post_status ) {
return;
}

if ( ! $post->post_name ) {
wp_update_post(
array(
'ID' => $post_id,
'post_name' => 'custom_slug_' . uniqid(),
)
);
}

$terms = get_the_terms( $post_id, 'wp_theme' );
if ( ! $terms || ! count( $terms ) ) {
wp_set_post_terms( $post_id, wp_get_theme()->get_stylesheet(), 'wp_theme' );
}
}

add_action( 'save_post_wp_template_part', 'gutenberg_set_unique_slug_on_create_template_part' );
}
Loading