Editor: Add plugin template registration API and improve theme overrides for plugin-registered templates
This commit introduces a new API to allow plugins to easily register block templates with `wp_register_block_template()` and the `WP_Block_Templates_Registry` class, addressing the complexity of hooking into multiple filters. It also ensures plugin-registered templates overridden by themes fall back to the plugin-provided title and description when the theme doesn't define them. See https://github.com/WordPress/gutenberg/pull/61577. See https://github.com/WordPress/gutenberg/pull/64610. Fixes #61804. Props aljullu, peterwilsoncc, antonvlasenko, azaozz, youknowriad, noisysocks. Built from https://develop.svn.wordpress.org/trunk@59073 git-svn-id: http://core.svn.wordpress.org/trunk@58469 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
f6df3fba16
commit
ef2b22c001
|
@ -592,6 +592,15 @@ function _build_block_template_result_from_file( $template_file, $template_type
|
||||||
$template->is_custom = true;
|
$template->is_custom = true;
|
||||||
$template->modified = null;
|
$template->modified = null;
|
||||||
|
|
||||||
|
if ( 'wp_template' === $template_type ) {
|
||||||
|
$registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template_file['slug'] );
|
||||||
|
if ( $registered_template ) {
|
||||||
|
$template->plugin = $registered_template->plugin;
|
||||||
|
$template->title = empty( $template->title ) || $template->title === $template->slug ? $registered_template->title : $template->title;
|
||||||
|
$template->description = empty( $template->description ) ? $registered_template->description : $template->description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( 'wp_template' === $template_type && isset( $default_template_types[ $template_file['slug'] ] ) ) {
|
if ( 'wp_template' === $template_type && isset( $default_template_types[ $template_file['slug'] ] ) ) {
|
||||||
$template->description = $default_template_types[ $template_file['slug'] ]['description'];
|
$template->description = $default_template_types[ $template_file['slug'] ]['description'];
|
||||||
$template->title = $default_template_types[ $template_file['slug'] ]['title'];
|
$template->title = $default_template_types[ $template_file['slug'] ]['title'];
|
||||||
|
@ -1014,6 +1023,19 @@ function _build_block_template_result_from_post( $post ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( 'wp_template' === $post->post_type ) {
|
||||||
|
$registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template->slug );
|
||||||
|
if ( $registered_template ) {
|
||||||
|
$template->plugin = $registered_template->plugin;
|
||||||
|
$template->origin =
|
||||||
|
'theme' !== $template->origin && 'theme' !== $template->source ?
|
||||||
|
'plugin' :
|
||||||
|
$template->origin;
|
||||||
|
$template->title = empty( $template->title ) || $template->title === $template->slug ? $registered_template->title : $template->title;
|
||||||
|
$template->description = empty( $template->description ) ? $registered_template->description : $template->description;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$hooked_blocks = get_hooked_blocks();
|
$hooked_blocks = get_hooked_blocks();
|
||||||
if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
|
if ( ! empty( $hooked_blocks ) || has_filter( 'hooked_block_types' ) ) {
|
||||||
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' );
|
$before_block_visitor = make_before_block_visitor( $hooked_blocks, $template, 'insert_hooked_blocks_and_set_ignored_hooked_blocks_metadata' );
|
||||||
|
@ -1157,6 +1179,23 @@ function get_block_templates( $query = array(), $template_type = 'wp_template' )
|
||||||
foreach ( $template_files as $template_file ) {
|
foreach ( $template_files as $template_file ) {
|
||||||
$query_result[] = _build_block_template_result_from_file( $template_file, $template_type );
|
$query_result[] = _build_block_template_result_from_file( $template_file, $template_type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( 'wp_template' === $template_type ) {
|
||||||
|
// Add templates registered in the template registry. Filtering out the ones which have a theme file.
|
||||||
|
$registered_templates = WP_Block_Templates_Registry::get_instance()->get_by_query( $query );
|
||||||
|
$matching_registered_templates = array_filter(
|
||||||
|
$registered_templates,
|
||||||
|
function ( $registered_template ) use ( $template_files ) {
|
||||||
|
foreach ( $template_files as $template_file ) {
|
||||||
|
if ( $template_file['slug'] === $registered_template->slug ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$query_result = array_merge( $query_result, $matching_registered_templates );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1287,18 +1326,17 @@ function get_block_file_template( $id, $template_type = 'wp_template' ) {
|
||||||
}
|
}
|
||||||
list( $theme, $slug ) = $parts;
|
list( $theme, $slug ) = $parts;
|
||||||
|
|
||||||
if ( get_stylesheet() !== $theme ) {
|
if ( get_stylesheet() === $theme ) {
|
||||||
/** This filter is documented in wp-includes/block-template-utils.php */
|
|
||||||
return apply_filters( 'get_block_file_template', null, $id, $template_type );
|
|
||||||
}
|
|
||||||
|
|
||||||
$template_file = _get_block_template_file( $template_type, $slug );
|
$template_file = _get_block_template_file( $template_type, $slug );
|
||||||
if ( null === $template_file ) {
|
if ( null !== $template_file ) {
|
||||||
|
$block_template = _build_block_template_result_from_file( $template_file, $template_type );
|
||||||
|
|
||||||
/** This filter is documented in wp-includes/block-template-utils.php */
|
/** This filter is documented in wp-includes/block-template-utils.php */
|
||||||
return apply_filters( 'get_block_file_template', null, $id, $template_type );
|
return apply_filters( 'get_block_file_template', $block_template, $id, $template_type );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$block_template = _build_block_template_result_from_file( $template_file, $template_type );
|
$block_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $slug );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters the block template object after it has been (potentially) fetched from the theme file.
|
* Filters the block template object after it has been (potentially) fetched from the theme file.
|
||||||
|
|
|
@ -358,3 +358,38 @@ function _resolve_template_for_new_post( $wp_query ) {
|
||||||
$wp_query->set( 'post_status', 'auto-draft' );
|
$wp_query->set( 'post_status', 'auto-draft' );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a block template.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param string $template_name Template name in the form of `plugin_uri//template_name`.
|
||||||
|
* @param array|string $args {
|
||||||
|
* @type string $title Optional. Title of the template as it will be shown in the Site Editor
|
||||||
|
* and other UI elements.
|
||||||
|
* @type string $description Optional. Description of the template as it will be shown in the Site
|
||||||
|
* Editor.
|
||||||
|
* @type string $content Optional. Default content of the template that will be used when the
|
||||||
|
* template is rendered or edited in the editor.
|
||||||
|
* @type string[] $post_types Optional. Array of post types to which the template should be available.
|
||||||
|
* @type string $plugin Optional. Slug of the plugin that registers the template.
|
||||||
|
* }
|
||||||
|
* @return WP_Block_Template|WP_Error The registered template object on success, WP_Error object on failure.
|
||||||
|
*/
|
||||||
|
function wp_register_block_template( $template_name, $args = array() ) {
|
||||||
|
return WP_Block_Templates_Registry::get_instance()->register( $template_name, $args );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister a block template.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param string $template_name Template name in the form of `plugin_uri//template_name`.
|
||||||
|
* @return WP_Block_Template|WP_Error The unregistered template object on success, WP_Error object on failure or if the
|
||||||
|
* template doesn't exist.
|
||||||
|
*/
|
||||||
|
function wp_unregister_block_template( $template_name ) {
|
||||||
|
return WP_Block_Templates_Registry::get_instance()->unregister( $template_name );
|
||||||
|
}
|
||||||
|
|
|
@ -29,15 +29,32 @@ function render_block_core_media_text( $attributes, $content ) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$has_media_on_right = isset( $attributes['mediaPosition'] ) && 'right' === $attributes['mediaPosition'];
|
||||||
|
$image_fill = isset( $attributes['imageFill'] ) && $attributes['imageFill'];
|
||||||
|
$focal_point = isset( $attributes['focalPoint'] ) ? round( $attributes['focalPoint']['x'] * 100 ) . '% ' . round( $attributes['focalPoint']['y'] * 100 ) . '%' : '50% 50%';
|
||||||
|
$unique_id = 'wp-block-media-text__media-' . wp_unique_id();
|
||||||
|
|
||||||
|
$block_tag_processor = new WP_HTML_Tag_Processor( $content );
|
||||||
|
$block_query = array(
|
||||||
|
'tag_name' => 'div',
|
||||||
|
'class_name' => 'wp-block-media-text',
|
||||||
|
);
|
||||||
|
|
||||||
|
while ( $block_tag_processor->next_tag( $block_query ) ) {
|
||||||
|
if ( $image_fill ) {
|
||||||
|
// The markup below does not work with the deprecated `is-image-fill` class.
|
||||||
|
$block_tag_processor->remove_class( 'is-image-fill' );
|
||||||
|
$block_tag_processor->add_class( 'is-image-fill-element' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = $block_tag_processor->get_updated_html();
|
||||||
|
|
||||||
$media_tag_processor = new WP_HTML_Tag_Processor( $content );
|
$media_tag_processor = new WP_HTML_Tag_Processor( $content );
|
||||||
$wrapping_figure_query = array(
|
$wrapping_figure_query = array(
|
||||||
'tag_name' => 'figure',
|
'tag_name' => 'figure',
|
||||||
'class_name' => 'wp-block-media-text__media',
|
'class_name' => 'wp-block-media-text__media',
|
||||||
);
|
);
|
||||||
$has_media_on_right = isset( $attributes['mediaPosition'] ) && 'right' === $attributes['mediaPosition'];
|
|
||||||
$image_fill = isset( $attributes['imageFill'] ) && $attributes['imageFill'];
|
|
||||||
$focal_point = isset( $attributes['focalPoint'] ) ? round( $attributes['focalPoint']['x'] * 100 ) . '% ' . round( $attributes['focalPoint']['y'] * 100 ) . '%' : '50% 50%';
|
|
||||||
$unique_id = 'wp-block-media-text__media-' . wp_unique_id();
|
|
||||||
|
|
||||||
if ( $has_media_on_right ) {
|
if ( $has_media_on_right ) {
|
||||||
// Loop through all the figure tags and set a bookmark on the last figure tag.
|
// Loop through all the figure tags and set a bookmark on the last figure tag.
|
||||||
|
@ -46,29 +63,20 @@ function render_block_core_media_text( $attributes, $content ) {
|
||||||
}
|
}
|
||||||
if ( $media_tag_processor->has_bookmark( 'last_figure' ) ) {
|
if ( $media_tag_processor->has_bookmark( 'last_figure' ) ) {
|
||||||
$media_tag_processor->seek( 'last_figure' );
|
$media_tag_processor->seek( 'last_figure' );
|
||||||
if ( $image_fill ) {
|
|
||||||
$media_tag_processor->set_attribute( 'style', 'background-image:url(' . esc_url( $current_featured_image ) . ');background-position:' . $focal_point . ';' );
|
|
||||||
} else {
|
|
||||||
// Insert a unique ID to identify the figure tag.
|
// Insert a unique ID to identify the figure tag.
|
||||||
$media_tag_processor->set_attribute( 'id', $unique_id );
|
$media_tag_processor->set_attribute( 'id', $unique_id );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if ( $media_tag_processor->next_tag( $wrapping_figure_query ) ) {
|
if ( $media_tag_processor->next_tag( $wrapping_figure_query ) ) {
|
||||||
if ( $image_fill ) {
|
|
||||||
$media_tag_processor->set_attribute( 'style', 'background-image:url(' . esc_url( $current_featured_image ) . ');background-position:' . $focal_point . ';' );
|
|
||||||
} else {
|
|
||||||
// Insert a unique ID to identify the figure tag.
|
// Insert a unique ID to identify the figure tag.
|
||||||
$media_tag_processor->set_attribute( 'id', $unique_id );
|
$media_tag_processor->set_attribute( 'id', $unique_id );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$content = $media_tag_processor->get_updated_html();
|
$content = $media_tag_processor->get_updated_html();
|
||||||
|
|
||||||
// If the image is not set to fill, add the image tag inside the figure tag,
|
// Add the image tag inside the figure tag, and update the image attributes
|
||||||
// and update the image attributes in order to display the featured image.
|
// in order to display the featured image.
|
||||||
if ( ! $image_fill ) {
|
|
||||||
$media_size_slug = isset( $attributes['mediaSizeSlug'] ) ? $attributes['mediaSizeSlug'] : 'full';
|
$media_size_slug = isset( $attributes['mediaSizeSlug'] ) ? $attributes['mediaSizeSlug'] : 'full';
|
||||||
$image_tag = '<img class="wp-block-media-text__featured_image">';
|
$image_tag = '<img class="wp-block-media-text__featured_image">';
|
||||||
$content = preg_replace(
|
$content = preg_replace(
|
||||||
|
@ -96,11 +104,13 @@ function render_block_core_media_text( $attributes, $content ) {
|
||||||
$image_tag_processor->set_attribute( 'src', esc_url( $current_featured_image ) );
|
$image_tag_processor->set_attribute( 'src', esc_url( $current_featured_image ) );
|
||||||
$image_tag_processor->set_attribute( 'class', 'wp-image-' . get_post_thumbnail_id() . ' size-' . $media_size_slug );
|
$image_tag_processor->set_attribute( 'class', 'wp-image-' . get_post_thumbnail_id() . ' size-' . $media_size_slug );
|
||||||
$image_tag_processor->set_attribute( 'alt', trim( strip_tags( get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ) ) );
|
$image_tag_processor->set_attribute( 'alt', trim( strip_tags( get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ) ) );
|
||||||
|
if ( $image_fill ) {
|
||||||
|
$image_tag_processor->set_attribute( 'style', 'object-position:' . $focal_point . ';' );
|
||||||
|
}
|
||||||
|
|
||||||
$content = $image_tag_processor->get_updated_html();
|
$content = $image_tag_processor->get_updated_html();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,6 +131,14 @@ class WP_Block_Template {
|
||||||
*/
|
*/
|
||||||
public $author;
|
public $author;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
* @var string|null
|
||||||
|
*/
|
||||||
|
public $plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post types.
|
* Post types.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,256 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Templates registry functions.
|
||||||
|
*
|
||||||
|
* @package WordPress
|
||||||
|
* @since 6.7.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core class used for interacting with templates.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*/
|
||||||
|
final class WP_Block_Templates_Registry {
|
||||||
|
/**
|
||||||
|
* Registered templates, as `$name => $instance` pairs.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
* @var WP_Block_Template[] $registered_block_templates Registered templates.
|
||||||
|
*/
|
||||||
|
private $registered_templates = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container for the main instance of the class.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
* @var WP_Block_Templates_Registry|null
|
||||||
|
*/
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a template.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param string $template_name Template name including namespace.
|
||||||
|
* @param array $args Optional. Array of template arguments.
|
||||||
|
* @return WP_Block_Template|WP_Error The registered template on success, or WP_Error on failure.
|
||||||
|
*/
|
||||||
|
public function register( $template_name, $args = array() ) {
|
||||||
|
|
||||||
|
$template = null;
|
||||||
|
|
||||||
|
$error_message = '';
|
||||||
|
$error_code = '';
|
||||||
|
|
||||||
|
if ( ! is_string( $template_name ) ) {
|
||||||
|
$error_message = __( 'Template names must be strings.' );
|
||||||
|
$error_code = 'template_name_no_string';
|
||||||
|
} elseif ( preg_match( '/[A-Z]+/', $template_name ) ) {
|
||||||
|
$error_message = __( 'Template names must not contain uppercase characters.' );
|
||||||
|
$error_code = 'template_name_no_uppercase';
|
||||||
|
} elseif ( ! preg_match( '/^[a-z0-9-]+\/\/[a-z0-9-]+$/', $template_name ) ) {
|
||||||
|
$error_message = __( 'Template names must contain a namespace prefix. Example: my-plugin//my-custom-template' );
|
||||||
|
$error_code = 'template_no_prefix';
|
||||||
|
} elseif ( $this->is_registered( $template_name ) ) {
|
||||||
|
/* translators: %s: Template name. */
|
||||||
|
$error_message = sprintf( __( 'Template "%s" is already registered.' ), $template_name );
|
||||||
|
$error_code = 'template_already_registered';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $error_message ) {
|
||||||
|
_doing_it_wrong(
|
||||||
|
__METHOD__,
|
||||||
|
$error_message,
|
||||||
|
'6.7.0'
|
||||||
|
);
|
||||||
|
return new WP_Error( $error_code, $error_message );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $template ) {
|
||||||
|
$theme_name = get_stylesheet();
|
||||||
|
list( $plugin, $slug ) = explode( '//', $template_name );
|
||||||
|
$default_template_types = get_default_block_template_types();
|
||||||
|
|
||||||
|
$template = new WP_Block_Template();
|
||||||
|
$template->id = $theme_name . '//' . $slug;
|
||||||
|
$template->theme = $theme_name;
|
||||||
|
$template->plugin = $plugin;
|
||||||
|
$template->author = null;
|
||||||
|
$template->content = isset( $args['content'] ) ? $args['content'] : '';
|
||||||
|
$template->source = 'plugin';
|
||||||
|
$template->slug = $slug;
|
||||||
|
$template->type = 'wp_template';
|
||||||
|
$template->title = isset( $args['title'] ) ? $args['title'] : $template_name;
|
||||||
|
$template->description = isset( $args['description'] ) ? $args['description'] : '';
|
||||||
|
$template->status = 'publish';
|
||||||
|
$template->origin = 'plugin';
|
||||||
|
$template->is_custom = ! isset( $default_template_types[ $template_name ] );
|
||||||
|
$template->post_types = isset( $args['post_types'] ) ? $args['post_types'] : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->registered_templates[ $template_name ] = $template;
|
||||||
|
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves all registered templates.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @return WP_Block_Template[] Associative array of `$template_name => $template` pairs.
|
||||||
|
*/
|
||||||
|
public function get_all_registered() {
|
||||||
|
return $this->registered_templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a registered template by its name.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param string $template_name Template name including namespace.
|
||||||
|
* @return WP_Block_Template|null The registered template, or null if it is not registered.
|
||||||
|
*/
|
||||||
|
public function get_registered( $template_name ) {
|
||||||
|
if ( ! $this->is_registered( $template_name ) ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->registered_templates[ $template_name ];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a registered template by its slug.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param string $template_slug Slug of the template.
|
||||||
|
* @return WP_Block_Template|null The registered template, or null if it is not registered.
|
||||||
|
*/
|
||||||
|
public function get_by_slug( $template_slug ) {
|
||||||
|
$all_templates = $this->get_all_registered();
|
||||||
|
|
||||||
|
if ( ! $all_templates ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ( $all_templates as $template ) {
|
||||||
|
if ( $template->slug === $template_slug ) {
|
||||||
|
return $template;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves registered templates matching a query.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param array $query {
|
||||||
|
* Arguments to retrieve templates. Optional, empty by default.
|
||||||
|
*
|
||||||
|
* @type string[] $slug__in List of slugs to include.
|
||||||
|
* @type string[] $slug__not_in List of slugs to skip.
|
||||||
|
* @type string $post_type Post type to get the templates for.
|
||||||
|
* }
|
||||||
|
* @return WP_Block_Template[] Associative array of `$template_name => $template` pairs.
|
||||||
|
*/
|
||||||
|
public function get_by_query( $query = array() ) {
|
||||||
|
$all_templates = $this->get_all_registered();
|
||||||
|
|
||||||
|
if ( ! $all_templates ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = wp_parse_args(
|
||||||
|
$query,
|
||||||
|
array(
|
||||||
|
'slug__in' => array(),
|
||||||
|
'slug__not_in' => array(),
|
||||||
|
'post_type' => '',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$slugs_to_include = $query['slug__in'];
|
||||||
|
$slugs_to_skip = $query['slug__not_in'];
|
||||||
|
$post_type = $query['post_type'];
|
||||||
|
|
||||||
|
$matching_templates = array();
|
||||||
|
foreach ( $all_templates as $template_name => $template ) {
|
||||||
|
if ( $slugs_to_include && ! in_array( $template->slug, $slugs_to_include, true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $slugs_to_skip && in_array( $template->slug, $slugs_to_skip, true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $post_type && ! in_array( $post_type, $template->post_types, true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$matching_templates[ $template_name ] = $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $matching_templates;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a template is registered.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param string $template_name Template name.
|
||||||
|
* @return bool True if the template is registered, false otherwise.
|
||||||
|
*/
|
||||||
|
public function is_registered( $template_name ) {
|
||||||
|
return isset( $this->registered_templates[ $template_name ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters a template.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @param string $template_name Template name including namespace.
|
||||||
|
* @return WP_Block_Template|WP_Error The unregistered template on success, or WP_Error on failure.
|
||||||
|
*/
|
||||||
|
public function unregister( $template_name ) {
|
||||||
|
if ( ! $this->is_registered( $template_name ) ) {
|
||||||
|
_doing_it_wrong(
|
||||||
|
__METHOD__,
|
||||||
|
/* translators: %s: Template name. */
|
||||||
|
sprintf( __( 'Template "%s" is not registered.' ), $template_name ),
|
||||||
|
'6.7.0'
|
||||||
|
);
|
||||||
|
/* translators: %s: Template name. */
|
||||||
|
return new WP_Error( 'template_not_registered', __( 'Template "%s" is not registered.' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$unregistered_template = $this->registered_templates[ $template_name ];
|
||||||
|
unset( $this->registered_templates[ $template_name ] );
|
||||||
|
|
||||||
|
return $unregistered_template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method to retrieve the main instance of the class.
|
||||||
|
*
|
||||||
|
* The instance will be created if it does not exist yet.
|
||||||
|
*
|
||||||
|
* @since 6.7.0
|
||||||
|
*
|
||||||
|
* @return WP_Block_Templates_Registry The main instance.
|
||||||
|
*/
|
||||||
|
public static function get_instance() {
|
||||||
|
if ( null === self::$instance ) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
}
|
|
@ -326,7 +326,7 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||||
* @return WP_REST_Response|WP_Error
|
* @return WP_REST_Response|WP_Error
|
||||||
*/
|
*/
|
||||||
public function get_item( $request ) {
|
public function get_item( $request ) {
|
||||||
if ( isset( $request['source'] ) && 'theme' === $request['source'] ) {
|
if ( isset( $request['source'] ) && ( 'theme' === $request['source'] || 'plugin' === $request['source'] ) ) {
|
||||||
$template = get_block_file_template( $request['id'], $this->post_type );
|
$template = get_block_file_template( $request['id'], $this->post_type );
|
||||||
} else {
|
} else {
|
||||||
$template = get_block_template( $request['id'], $this->post_type );
|
$template = get_block_template( $request['id'], $this->post_type );
|
||||||
|
@ -776,6 +776,13 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||||
$data['original_source'] = self::get_wp_templates_original_source_field( $template );
|
$data['original_source'] = self::get_wp_templates_original_source_field( $template );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( rest_is_field_included( 'plugin', $fields ) ) {
|
||||||
|
$registered_template = WP_Block_Templates_Registry::get_instance()->get_by_slug( $template->slug );
|
||||||
|
if ( $registered_template ) {
|
||||||
|
$data['plugin'] = $registered_template->plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
|
||||||
$data = $this->add_additional_fields_to_object( $data, $request );
|
$data = $this->add_additional_fields_to_object( $data, $request );
|
||||||
$data = $this->filter_response_by_context( $data, $context );
|
$data = $this->filter_response_by_context( $data, $context );
|
||||||
|
@ -831,7 +838,7 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Added by plugin.
|
// Added by plugin.
|
||||||
if ( $template_object->has_theme_file && 'plugin' === $template_object->origin ) {
|
if ( 'plugin' === $template_object->origin ) {
|
||||||
return 'plugin';
|
return 'plugin';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -865,9 +872,41 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||||
$theme_name = wp_get_theme( $template_object->theme )->get( 'Name' );
|
$theme_name = wp_get_theme( $template_object->theme )->get( 'Name' );
|
||||||
return empty( $theme_name ) ? $template_object->theme : $theme_name;
|
return empty( $theme_name ) ? $template_object->theme : $theme_name;
|
||||||
case 'plugin':
|
case 'plugin':
|
||||||
|
if ( ! function_exists( 'get_plugins' ) || ! function_exists( 'get_plugin_data' ) ) {
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||||
|
}
|
||||||
|
if ( isset( $template_object->plugin ) ) {
|
||||||
|
$plugins = wp_get_active_and_valid_plugins();
|
||||||
|
|
||||||
|
foreach ( $plugins as $plugin_file ) {
|
||||||
|
$plugin_basename = plugin_basename( $plugin_file );
|
||||||
|
// Split basename by '/' to get the plugin slug.
|
||||||
|
list( $plugin_slug, ) = explode( '/', $plugin_basename );
|
||||||
|
|
||||||
|
if ( $plugin_slug === $template_object->plugin ) {
|
||||||
|
$plugin_data = get_plugin_data( $plugin_file );
|
||||||
|
|
||||||
|
if ( ! empty( $plugin_data['Name'] ) ) {
|
||||||
|
return $plugin_data['Name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fall back to the theme name if the plugin is not defined. That's needed to keep backwards
|
||||||
|
* compatibility with templates that were registered before the plugin attribute was added.
|
||||||
|
*/
|
||||||
$plugins = get_plugins();
|
$plugins = get_plugins();
|
||||||
$plugin = $plugins[ plugin_basename( sanitize_text_field( $template_object->theme . '.php' ) ) ];
|
$plugin_basename = plugin_basename( sanitize_text_field( $template_object->theme . '.php' ) );
|
||||||
return empty( $plugin['Name'] ) ? $template_object->theme : $plugin['Name'];
|
if ( isset( $plugins[ $plugin_basename ] ) && isset( $plugins[ $plugin_basename ]['Name'] ) ) {
|
||||||
|
return $plugins[ $plugin_basename ]['Name'];
|
||||||
|
}
|
||||||
|
return isset( $template_object->plugin ) ?
|
||||||
|
$template_object->plugin :
|
||||||
|
$template_object->theme;
|
||||||
case 'site':
|
case 'site':
|
||||||
return get_bloginfo( 'name' );
|
return get_bloginfo( 'name' );
|
||||||
case 'user':
|
case 'user':
|
||||||
|
@ -1134,6 +1173,12 @@ class WP_REST_Templates_Controller extends WP_REST_Controller {
|
||||||
'context' => array( 'embed', 'view', 'edit' ),
|
'context' => array( 'embed', 'view', 'edit' ),
|
||||||
'readonly' => true,
|
'readonly' => true,
|
||||||
);
|
);
|
||||||
|
$schema['properties']['plugin'] = array(
|
||||||
|
'type' => 'string',
|
||||||
|
'description' => __( 'Plugin that registered the template.' ),
|
||||||
|
'readonly' => true,
|
||||||
|
'context' => array( 'view', 'edit', 'embed' ),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'wp_template_part' === $this->post_type ) {
|
if ( 'wp_template_part' === $this->post_type ) {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '6.7-alpha-59072';
|
$wp_version = '6.7-alpha-59073';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
|
|
@ -192,6 +192,7 @@ require ABSPATH . WPINC . '/class-wp-theme-json-resolver.php';
|
||||||
require ABSPATH . WPINC . '/class-wp-duotone.php';
|
require ABSPATH . WPINC . '/class-wp-duotone.php';
|
||||||
require ABSPATH . WPINC . '/global-styles-and-settings.php';
|
require ABSPATH . WPINC . '/global-styles-and-settings.php';
|
||||||
require ABSPATH . WPINC . '/class-wp-block-template.php';
|
require ABSPATH . WPINC . '/class-wp-block-template.php';
|
||||||
|
require ABSPATH . WPINC . '/class-wp-block-templates-registry.php';
|
||||||
require ABSPATH . WPINC . '/block-template-utils.php';
|
require ABSPATH . WPINC . '/block-template-utils.php';
|
||||||
require ABSPATH . WPINC . '/block-template.php';
|
require ABSPATH . WPINC . '/block-template.php';
|
||||||
require ABSPATH . WPINC . '/theme-templates.php';
|
require ABSPATH . WPINC . '/theme-templates.php';
|
||||||
|
|
Loading…
Reference in New Issue