diff --git a/lib/compat/wordpress-6.1/rest-api.php b/lib/compat/wordpress-6.1/rest-api.php index f2293e5169a9c4..5dd06d3aad855b 100644 --- a/lib/compat/wordpress-6.1/rest-api.php +++ b/lib/compat/wordpress-6.1/rest-api.php @@ -5,6 +5,22 @@ * @package gutenberg */ +/** + * Update `wp_template` and `wp_template-part` post types to use + * Gutenberg's REST controller. + * + * @param array $args Array of arguments for registering a post type. + * @param string $post_type Post type key. + */ +function gutenberg_update_templates_template_parts_rest_controller( $args, $post_type ) { + if ( in_array( $post_type, array( 'wp_template', 'wp_template-part' ), true ) ) { + $args['rest_controller_class'] = 'Gutenberg_REST_Templates_Controller'; + } + return $args; +} +add_filter( 'register_post_type_args', 'gutenberg_update_templates_template_parts_rest_controller', 10, 2 ); + + /** * Add the post type's `icon`(menu_icon) in the response. * When we backport this change we will need to add the diff --git a/lib/compat/wordpress-6.2/class-gutenberg-rest-templates-controller-6-2.php b/lib/compat/wordpress-6.2/class-gutenberg-rest-templates-controller-6-2.php deleted file mode 100644 index 16d38ac073e68d..00000000000000 --- a/lib/compat/wordpress-6.2/class-gutenberg-rest-templates-controller-6-2.php +++ /dev/null @@ -1,68 +0,0 @@ -namespace, - '/' . $this->rest_base . '/lookup', - array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_template_fallback' ), - 'permission_callback' => array( $this, 'get_item_permissions_check' ), - 'args' => array( - 'slug' => array( - 'description' => __( 'The slug of the template to get the fallback for', 'gutenberg' ), - 'type' => 'string', - 'required' => true, - ), - 'is_custom' => array( - 'description' => __( 'Indicates if a template is custom or part of the template hierarchy', 'gutenberg' ), - 'type' => 'boolean', - ), - 'template_prefix' => array( - 'description' => __( 'The template prefix for the created template. This is used to extract the main template type ex. in `taxonomy-books` we extract the `taxonomy`', 'gutenberg' ), - 'type' => 'string', - ), - ), - ), - ) - ); - parent::register_routes(); - // Get fallback template content. - } - - /** - * Returns the fallback template for a given slug. - * - * @param WP_REST_Request $request The request instance. - * - * @return WP_REST_Response|WP_Error - */ - public function get_template_fallback( $request ) { - $hierarchy = get_template_hierarchy( $request['slug'], $request['is_custom'], $request['template_prefix'] ); - $fallback_template = null; - do { - $fallback_template = resolve_block_template( $request['slug'], $hierarchy, '' ); - array_shift( $hierarchy ); - } while ( ! empty( $hierarchy ) && empty( $fallback_template->content ) ); - $response = $this->prepare_item_for_response( $fallback_template, $request ); - return rest_ensure_response( $response ); - } -} diff --git a/lib/compat/wordpress-6.2/rest-api.php b/lib/compat/wordpress-6.2/rest-api.php index 06780aceb245e3..a504be4dca2a6b 100644 --- a/lib/compat/wordpress-6.2/rest-api.php +++ b/lib/compat/wordpress-6.2/rest-api.php @@ -5,21 +5,6 @@ * @package gutenberg */ -/** - * Update `wp_template` and `wp_template-part` post types to use - * Gutenberg's REST controller. - * - * @param array $args Array of arguments for registering a post type. - * @param string $post_type Post type key. - */ -function gutenberg_update_templates_template_parts_rest_controller( $args, $post_type ) { - if ( in_array( $post_type, array( 'wp_template', 'wp_template-part' ), true ) ) { - $args['rest_controller_class'] = 'Gutenberg_REST_Templates_Controller_6_2'; - } - return $args; -} -add_filter( 'register_post_type_args', 'gutenberg_update_templates_template_parts_rest_controller', 10, 2 ); - /** * Registers the block pattern categories REST API routes. */ diff --git a/lib/load.php b/lib/load.php index dc253408a92899..fd8a7b90577536 100644 --- a/lib/load.php +++ b/lib/load.php @@ -44,7 +44,6 @@ function gutenberg_is_experiment_enabled( $name ) { require_once __DIR__ . '/compat/wordpress-6.2/class-gutenberg-rest-block-patterns-controller-6-2.php'; require_once __DIR__ . '/compat/wordpress-6.2/class-gutenberg-rest-block-pattern-categories-controller.php'; require_once __DIR__ . '/compat/wordpress-6.2/class-gutenberg-rest-pattern-directory-controller-6-2.php'; - require_once __DIR__ . '/compat/wordpress-6.2/class-gutenberg-rest-templates-controller-6-2.php'; require_once __DIR__ . '/compat/wordpress-6.2/rest-api.php'; require_once __DIR__ . '/compat/wordpress-6.2/block-patterns.php'; require_once __DIR__ . '/compat/wordpress-6.2/class-gutenberg-rest-global-styles-controller-6-2.php'; diff --git a/packages/edit-site/src/components/add-new-template/new-template.js b/packages/edit-site/src/components/add-new-template/new-template.js index 09f4319f708daa..2fb715dddbcf9b 100644 --- a/packages/edit-site/src/components/add-new-template/new-template.js +++ b/packages/edit-site/src/components/add-new-template/new-template.js @@ -1,6 +1,8 @@ /** * WordPress dependencies */ +import apiFetch from '@wordpress/api-fetch'; +import { addQueryArgs } from '@wordpress/url'; import { DropdownMenu, MenuGroup, @@ -107,7 +109,19 @@ export default function NewTemplate( { } setIsCreatingTemplate( true ); try { - const { title, description, slug } = template; + const { title, description, slug, templatePrefix } = template; + let templateContent = template.content; + // Try to find fallback content from existing templates. + if ( ! templateContent ) { + const fallbackTemplate = await apiFetch( { + path: addQueryArgs( '/wp/v2/templates/lookup', { + slug, + is_custom: ! isWPSuggestion, + template_prefix: templatePrefix, + } ), + } ); + templateContent = fallbackTemplate.content.raw; + } const newTemplate = await saveEntityRecord( 'postType', 'wp_template', @@ -117,6 +131,7 @@ export default function NewTemplate( { slug: slug.toString(), status: 'publish', title, + content: templateContent, // This adds a post meta field in template that is part of `is_custom` value calculation. is_wp_suggestion: isWPSuggestion, }, diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index 901a66d2e31218..745fa4d6e6d78a 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -29,7 +29,6 @@ import KeyboardShortcuts from '../keyboard-shortcuts'; import InserterSidebar from '../secondary-sidebar/inserter-sidebar'; import ListViewSidebar from '../secondary-sidebar/list-view-sidebar'; import WelcomeGuide from '../welcome-guide'; -import StartTemplateOptions from '../start-template-options'; import { store as editSiteStore } from '../../store'; import { GlobalStylesRenderer } from '../global-styles-renderer'; import { GlobalStylesProvider } from '../global-styles/global-styles-provider'; @@ -171,7 +170,6 @@ export default function Editor() { - { isEditMode && } { - apiFetch( { - path: addQueryArgs( '/wp/v2/templates/lookup', { - slug, - is_custom: isCustom, - ignore_empty: true, - } ), - } ).then( ( { content } ) => setTemplateContent( content.raw ) ); - }, [ slug ] ); - return templateContent; -} - -const START_BLANK_TITLE = __( 'Start blank' ); - -function PatternSelection( { fallbackContent, onChoosePattern, postType } ) { - const [ , , onChange ] = useEntityBlockEditor( 'postType', postType ); - const blockPatterns = useMemo( - () => [ - { - name: 'fallback', - blocks: parse( fallbackContent ), - title: __( 'Fallback content' ), - }, - { - name: 'start-blank', - blocks: parse( - '

' - ), - title: START_BLANK_TITLE, - }, - ], - [ fallbackContent ] - ); - const shownBlockPatterns = useAsyncList( blockPatterns ); - - return ( -
- { - onChange( 'start-blank' === pattern.name ? [] : blocks, { - selection: undefined, - } ); - onChoosePattern(); - } } - /> -
- ); -} - -function StartModal( { slug, isCustom, onClose, postType } ) { - const fallbackContent = useFallbackTemplateContent( slug, isCustom ); - if ( ! fallbackContent ) { - return null; - } - return ( - -
- { - onClose(); - } } - /> -
-
- ); -} - -const START_TEMPLATE_MODAL_STATES = { - INITIAL: 'INITIAL', - CLOSED: 'CLOSED', -}; - -export default function StartTemplateOptions() { - const [ modalState, setModalState ] = useState( - START_TEMPLATE_MODAL_STATES.INITIAL - ); - const { shouldOpenModel, slug, isCustom, postType } = useSelect( - ( select ) => { - const { getEditedPostType, getEditedPostId } = - select( editSiteStore ); - const _postType = getEditedPostType(); - const postId = getEditedPostId(); - const { - __experimentalGetDirtyEntityRecords, - getEditedEntityRecord, - } = select( coreStore ); - const templateRecord = getEditedEntityRecord( - 'postType', - _postType, - postId - ); - - const hasDirtyEntityRecords = - __experimentalGetDirtyEntityRecords().length > 0; - - return { - shouldOpenModel: - ! hasDirtyEntityRecords && - '' === templateRecord.content && - 'wp_template' === _postType && - ! select( preferencesStore ).get( - 'core/edit-site', - 'welcomeGuide' - ), - slug: templateRecord.slug, - isCustom: templateRecord.is_custom, - postType: _postType, - }; - }, - [] - ); - - if ( - ( modalState === START_TEMPLATE_MODAL_STATES.INITIAL && - ! shouldOpenModel ) || - modalState === START_TEMPLATE_MODAL_STATES.CLOSED - ) { - return null; - } - - return ( - - setModalState( START_TEMPLATE_MODAL_STATES.CLOSED ) - } - /> - ); -} diff --git a/packages/edit-site/src/components/start-template-options/style.scss b/packages/edit-site/src/components/start-template-options/style.scss deleted file mode 100644 index ca086ef0858848..00000000000000 --- a/packages/edit-site/src/components/start-template-options/style.scss +++ /dev/null @@ -1,76 +0,0 @@ -.edit-site-start-template-options__modal.components-modal__frame { - // To keep modal dimensions consistent as subsections are navigated, width - // and height are used instead of max-(width/height). - @include break-small() { - width: calc(100% - #{ $grid-unit-20 * 2 }); - height: calc(100% - #{ $header-height * 2 }); - } - @include break-medium() { - width: 50%; - } - @include break-large() { - height: fit-content; - } -} - -.edit-site-start-template-options__modal-content .block-editor-block-patterns-list { - display: grid; - width: 100%; - margin-top: $grid-unit-05; - gap: $grid-unit-30; - grid-template-columns: repeat(auto-fit, minmax(min(100%/2, max(240px, 100%/10)), 1fr)); - .block-editor-block-patterns-list__list-item { - break-inside: avoid-column; - margin-bottom: 0; - width: 100%; - aspect-ratio: 3/4; - - .block-editor-block-preview__container { - height: 100%; - box-shadow: 0 0 0 1px $gray-300; - } - - .block-editor-block-preview__content { - width: 100%; - position: absolute; - } - - .block-editor-block-patterns-list__item-title { - display: none; - } - - &:hover { - .block-editor-block-preview__container { - box-shadow: 0 0 0 2px var(--wp-admin-theme-color); - } - } - - &:focus { - .block-editor-block-preview__container { - box-shadow: inset 0 0 0 1px $white, 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); - - // Windows High Contrast mode will show this outline, but not the box-shadow. - outline: 2px solid transparent; - } - } - } - - // The start blank pattern is the last and we are selecting it. - .block-editor-block-patterns-list__list-item:nth-last-child(2) { - .block-editor-block-preview__container { - position: absolute; - padding: 0; - background: #f0f0f0; - &::after { - width: 100%; - top: 50%; - margin-top: -1em; - content: var(--wp-edit-site-start-template-options-start-blank); - text-align: center; - } - } - iframe { - display: none; - } - } -} diff --git a/packages/edit-site/src/style.scss b/packages/edit-site/src/style.scss index 950d1c286274de..f73bc019f30361 100644 --- a/packages/edit-site/src/style.scss +++ b/packages/edit-site/src/style.scss @@ -17,7 +17,6 @@ @import "./components/create-template-part-modal/style.scss"; @import "./components/secondary-sidebar/style.scss"; @import "./components/welcome-guide/style.scss"; -@import "./components/start-template-options/style.scss"; @import "./components/keyboard-shortcut-help-modal/style.scss"; @import "./components/layout/style.scss"; @import "./components/save-panel/style.scss"; diff --git a/phpunit/class-gutenberg-rest-templates-controller-test.php b/phpunit/class-gutenberg-rest-templates-controller-test.php index e8d770ee55b174..2c8521d63fd825 100644 --- a/phpunit/class-gutenberg-rest-templates-controller-test.php +++ b/phpunit/class-gutenberg-rest-templates-controller-test.php @@ -49,12 +49,6 @@ public function test_get_template_fallback() { $response = rest_get_server()->dispatch( $request ); $this->assertSame( 'singular', $response->get_data()['slug'], 'Should fallback to `singular.html`.' ); // Should fallback to `index.html`. - $request->set_param( 'slug', 'tag' ); - $request->set_param( 'ignore_empty', true ); - $request->set_param( 'is_custom', false ); - $response = rest_get_server()->dispatch( $request ); - $this->assertSame( 'index', $response->get_data()['slug'], 'Should fallback to `index.html`.' ); - // Should fallback to `index.html`. $request->set_param( 'slug', 'tag-rigas' ); $request->set_param( 'is_custom', false ); $request->set_param( 'template_prefix', 'tag' ); diff --git a/test/emptytheme/templates/tag.html b/test/emptytheme/templates/tag.html deleted file mode 100644 index e69de29bb2d1d6..00000000000000