diff --git a/wp-includes/block-template-utils.php b/wp-includes/block-template-utils.php
index fb9076c42e..2900781172 100644
--- a/wp-includes/block-template-utils.php
+++ b/wp-includes/block-template-utils.php
@@ -592,6 +592,15 @@ function _build_block_template_result_from_file( $template_file, $template_type
$template->is_custom = true;
$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'] ] ) ) {
$template->description = $default_template_types[ $template_file['slug'] ]['description'];
$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();
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' );
@@ -1157,6 +1179,23 @@ function get_block_templates( $query = array(), $template_type = 'wp_template' )
foreach ( $template_files as $template_file ) {
$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;
- 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 );
+ if ( get_stylesheet() === $theme ) {
+ $template_file = _get_block_template_file( $template_type, $slug );
+ 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 */
+ return apply_filters( 'get_block_file_template', $block_template, $id, $template_type );
+ }
}
- $template_file = _get_block_template_file( $template_type, $slug );
- if ( null === $template_file ) {
- /** This filter is documented in wp-includes/block-template-utils.php */
- return apply_filters( 'get_block_file_template', null, $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.
@@ -1665,12 +1703,12 @@ function inject_ignored_hooked_blocks_metadata_attributes( $changes, $deprecated
);
}
- $content = get_comment_delimited_block_content(
+ $content = get_comment_delimited_block_content(
'core/template-part',
$attributes,
$changes->post_content
);
- $content = apply_block_hooks_to_content( $content, $template, 'set_ignored_hooked_blocks_metadata' );
+ $content = apply_block_hooks_to_content( $content, $template, 'set_ignored_hooked_blocks_metadata' );
$changes->post_content = remove_serialized_parent_block( $content );
$wrapper_block_markup = extract_serialized_parent_block( $content );
diff --git a/wp-includes/block-template.php b/wp-includes/block-template.php
index 0a4d85ac71..d42a74479c 100644
--- a/wp-includes/block-template.php
+++ b/wp-includes/block-template.php
@@ -358,3 +358,38 @@ function _resolve_template_for_new_post( $wp_query ) {
$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 );
+}
diff --git a/wp-includes/blocks/media-text.php b/wp-includes/blocks/media-text.php
index 87be164a04..b65137b150 100644
--- a/wp-includes/blocks/media-text.php
+++ b/wp-includes/blocks/media-text.php
@@ -29,15 +29,32 @@ function render_block_core_media_text( $attributes, $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 );
$wrapping_figure_query = array(
'tag_name' => 'figure',
'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 ) {
// Loop through all the figure tags and set a bookmark on the last figure tag.
@@ -46,59 +63,52 @@ function render_block_core_media_text( $attributes, $content ) {
}
if ( $media_tag_processor->has_bookmark( '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.
- $media_tag_processor->set_attribute( 'id', $unique_id );
- }
+ // Insert a unique ID to identify the figure tag.
+ $media_tag_processor->set_attribute( 'id', $unique_id );
}
} else {
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.
- $media_tag_processor->set_attribute( 'id', $unique_id );
- }
+ // Insert a unique ID to identify the figure tag.
+ $media_tag_processor->set_attribute( 'id', $unique_id );
}
}
$content = $media_tag_processor->get_updated_html();
- // If the image is not set to fill, add the image tag inside the figure tag,
- // and update the image attributes in order to display the featured image.
- if ( ! $image_fill ) {
- $media_size_slug = isset( $attributes['mediaSizeSlug'] ) ? $attributes['mediaSizeSlug'] : 'full';
- $image_tag = '';
- $content = preg_replace(
- '/(