diff --git a/src/wp-admin/menu.php b/src/wp-admin/menu.php index 5d550fb55d856..f45a2811fc2b0 100644 --- a/src/wp-admin/menu.php +++ b/src/wp-admin/menu.php @@ -214,12 +214,20 @@ ); } +if ( ! wp_is_block_theme() && current_theme_supports( 'block-template-parts' ) ) { + $submenu['themes.php'][6] = array( + __( 'Template Parts' ), + 'edit_theme_options', + 'site-editor.php?postType=wp_template_part', + ); +} + $customize_url = add_query_arg( 'return', urlencode( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ), 'customize.php' ); // Hide Customize link on block themes unless a plugin or theme // is using 'customize_register' to add a setting. if ( ! wp_is_block_theme() || has_action( 'customize_register' ) ) { - $position = wp_is_block_theme() ? 7 : 6; + $position = ( wp_is_block_theme() || current_theme_supports( 'block-template-parts' ) ) ? 7 : 6; $submenu['themes.php'][ $position ] = array( __( 'Customize' ), 'customize', esc_url( $customize_url ), '', 'hide-if-no-customize' ); } diff --git a/src/wp-admin/site-editor.php b/src/wp-admin/site-editor.php index 365c6d701eaf1..e97470814eaf6 100644 --- a/src/wp-admin/site-editor.php +++ b/src/wp-admin/site-editor.php @@ -19,10 +19,15 @@ ); } -if ( ! wp_is_block_theme() ) { +if ( ! ( current_theme_supports( 'block-template-parts' ) || wp_is_block_theme() ) ) { wp_die( __( 'The theme you are currently using is not compatible with Full Site Editing.' ) ); } +$is_template_part_editor = isset( $_GET['postType'] ) && 'wp_template_part' === sanitize_key( $_GET['postType'] ); +if ( ! wp_is_block_theme() && ! $is_template_part_editor ) { + wp_die( __( 'The theme you are currently using is not compatible with the Site Editor.' ) ); +} + /** * Do a server-side redirection if missing `postType` and `postId` * query args when visiting Site Editor. @@ -64,14 +69,24 @@ static function( $classes ) { $block_editor_context = new WP_Block_Editor_Context( array( 'name' => 'core/edit-site' ) ); $custom_settings = array( - 'siteUrl' => site_url(), - 'postsPerPage' => get_option( 'posts_per_page' ), - 'styles' => get_block_editor_theme_styles(), - 'defaultTemplateTypes' => $indexed_template_types, - 'defaultTemplatePartAreas' => get_allowed_block_template_part_areas(), - '__unstableHomeTemplate' => $home_template, + 'siteUrl' => site_url(), + 'postsPerPage' => get_option( 'posts_per_page' ), + 'styles' => get_block_editor_theme_styles(), + 'defaultTemplateTypes' => $indexed_template_types, + 'defaultTemplatePartAreas' => get_allowed_block_template_part_areas(), + 'supportsLayout' => WP_Theme_JSON_Resolver::theme_has_support(), + 'supportsTemplatePartsMode' => ! wp_is_block_theme() && current_theme_supports( 'block-template-parts' ), + '__unstableHomeTemplate' => $home_template, ); +/** + * We don't need home template resolution when block template parts are supported. + * Set the value to true to satisfy the editor initialization guard clause. + */ +if ( $custom_settings['supportsTemplatePartsMode'] ) { + $custom_settings['__unstableHomeTemplate'] = true; +} + // Add additional back-compat patterns registered by `current_screen` et al. $custom_settings['__experimentalAdditionalBlockPatterns'] = WP_Block_Patterns_Registry::get_instance()->get_all_registered( true ); $custom_settings['__experimentalAdditionalBlockPatternCategories'] = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered( true ); diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 946853c361b73..0e95f270d15e6 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -5261,7 +5261,7 @@ function wp_widgets_add_menu() { } $menu_name = __( 'Widgets' ); - if ( wp_is_block_theme() ) { + if ( wp_is_block_theme() || current_theme_supports( 'block-template-parts' ) ) { $submenu['themes.php'][] = array( $menu_name, 'edit_theme_options', 'widgets.php' ); } else { $submenu['themes.php'][7] = array( $menu_name, 'edit_theme_options', 'widgets.php' ); diff --git a/src/wp-includes/theme.php b/src/wp-includes/theme.php index 3c7b297b2a802..a8f1e2f2c8b65 100644 --- a/src/wp-includes/theme.php +++ b/src/wp-includes/theme.php @@ -3843,6 +3843,13 @@ function create_initial_theme_features() { 'show_in_rest' => true, ) ); + register_theme_feature( + 'block-template-parts', + array( + 'description' => __( 'Whether a theme uses block-based template parts.' ), + 'show_in_rest' => true, + ) + ); register_theme_feature( 'custom-background', array( diff --git a/tests/phpunit/tests/rest-api/rest-themes-controller.php b/tests/phpunit/tests/rest-api/rest-themes-controller.php index da03319286136..cbc9f989f5fc3 100644 --- a/tests/phpunit/tests/rest-api/rest-themes-controller.php +++ b/tests/phpunit/tests/rest-api/rest-themes-controller.php @@ -388,6 +388,7 @@ public function test_get_item_schema() { $this->assertArrayHasKey( 'align-wide', $theme_supports ); $this->assertArrayHasKey( 'automatic-feed-links', $theme_supports ); $this->assertArrayHasKey( 'block-templates', $theme_supports ); + $this->assertArrayHasKey( 'block-template-parts', $theme_supports ); $this->assertArrayHasKey( 'custom-header', $theme_supports ); $this->assertArrayHasKey( 'custom-background', $theme_supports ); $this->assertArrayHasKey( 'custom-logo', $theme_supports ); @@ -406,7 +407,7 @@ public function test_get_item_schema() { $this->assertArrayHasKey( 'responsive-embeds', $theme_supports ); $this->assertArrayHasKey( 'title-tag', $theme_supports ); $this->assertArrayHasKey( 'wp-block-styles', $theme_supports ); - $this->assertCount( 21, $theme_supports ); + $this->assertCount( 22, $theme_supports ); } /**