From e33a49f691e60685bf2553095fd2edac860a535b Mon Sep 17 00:00:00 2001 From: Enrique Piqueras Date: Thu, 16 Jan 2020 10:04:41 -0500 Subject: [PATCH] Edit Site: Add template loading. (#19081) * Edit Site: Add root template ID to editor settings. * Edit Site: Load root template in block editor. * Lib: Update demo block template. * Lib: Rename demo block template. * Edit Site: Serialize blocks on persistent changes. * Edit Site: Add multiple entity saving functionality. --- .../{index.html => front-page.html} | 4 +- lib/edit-site-page.php | 7 +++ lib/template-loader.php | 18 +++--- package-lock.json | 3 + packages/edit-site/package.json | 3 + .../src/components/block-editor/index.js | 27 ++++++++- .../edit-site/src/components/editor/index.js | 31 +++++++--- .../edit-site/src/components/header/index.js | 8 +++ .../src/components/header/style.scss | 4 ++ .../src/components/save-button/index.js | 56 +++++++++++++++++++ 10 files changed, 142 insertions(+), 19 deletions(-) rename lib/demo-block-templates/{index.html => front-page.html} (95%) create mode 100644 packages/edit-site/src/components/save-button/index.js diff --git a/lib/demo-block-templates/index.html b/lib/demo-block-templates/front-page.html similarity index 95% rename from lib/demo-block-templates/index.html rename to lib/demo-block-templates/front-page.html index a6a93733a70799..627b7ad76aecf8 100644 --- a/lib/demo-block-templates/index.html +++ b/lib/demo-block-templates/front-page.html @@ -8,14 +8,14 @@
- + - +
diff --git a/lib/edit-site-page.php b/lib/edit-site-page.php index bdd467c2f5913d..8fffad69ef6f3b 100644 --- a/lib/edit-site-page.php +++ b/lib/edit-site-page.php @@ -28,6 +28,7 @@ class="edit-site" * @param string $hook Page. */ function gutenberg_edit_site_init( $hook ) { + global $_wp_current_template_id; if ( 'gutenberg_page_gutenberg-edit-site' !== $hook ) { return; } @@ -73,6 +74,12 @@ function gutenberg_edit_site_init( $hook ) { $settings['fontSizes'] = $font_sizes; } + // Get root template by trigerring `./template-loader.php`'s logic. + get_front_page_template(); + get_index_template(); + apply_filters( 'template_include', null ); + $settings['templateId'] = $_wp_current_template_id; + // Initialize editor. wp_add_inline_script( 'wp-edit-site', diff --git a/lib/template-loader.php b/lib/template-loader.php index 84ab186fe2ed16..035802505896aa 100644 --- a/lib/template-loader.php +++ b/lib/template-loader.php @@ -114,7 +114,7 @@ function create_auto_draft_for_template_part_block( $block ) { * @return string Path to the canvas file to include. */ function gutenberg_find_template( $template_file ) { - global $_wp_current_template_content, $_wp_current_template_hierarchy; + global $_wp_current_template_id, $_wp_current_template_content, $_wp_current_template_hierarchy; // Bail if no relevant template hierarchy was determined, or if the template file // was overridden another way. @@ -149,15 +149,17 @@ function gutenberg_find_template( $template_file ) { $higher_priority_block_template_priority = PHP_INT_MAX; $block_template_files = glob( get_stylesheet_directory() . '/block-templates/*.html' ) ?: array(); if ( is_child_theme() ) { - $block_template_files = array_merge( $block_template_files, glob( get_template_directory() . '/block-templates/*.html' ) ?: array() ); + $block_template_files = array_merge( $block_template_files, glob( get_template_directory() . '/block-templates/*.html' ) ?: array() ); } if ( gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing-demo' ) ) { $block_template_files = array_merge( $block_template_files, glob( dirname( __FILE__ ) . '/demo-block-templates/*.html' ) ?: array() ); } foreach ( $block_template_files as $path ) { + if ( ! isset( $slug_priorities[ basename( $path, '.html' ) ] ) ) { + continue; + } $theme_block_template_priority = $slug_priorities[ basename( $path, '.html' ) ]; if ( - isset( $theme_block_template_priority ) && $theme_block_template_priority < $higher_priority_block_template_priority && ( empty( $current_template_post ) || $theme_block_template_priority < $slug_priorities[ $current_template_post->post_name ] ) ) { @@ -183,10 +185,6 @@ function gutenberg_find_template( $template_file ) { $current_template_post = get_post( wp_insert_post( $current_template_post ) ); - - foreach ( parse_blocks( $current_template_post->post_content ) as $block ) { - create_auto_draft_for_template_part_block( $block ); - } } else { $current_template_post = new WP_Post( (object) $current_template_post @@ -195,6 +193,12 @@ function gutenberg_find_template( $template_file ) { } if ( $current_template_post ) { + if ( is_admin() ) { + foreach ( parse_blocks( $current_template_post->post_content ) as $block ) { + create_auto_draft_for_template_part_block( $block ); + } + } + $_wp_current_template_id = $current_template_post->ID; $_wp_current_template_content = $current_template_post->post_content; } diff --git a/package-lock.json b/package-lock.json index 062b60cd87d1f4..83d32e847a5b0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9814,8 +9814,11 @@ "@babel/runtime": "^7.4.4", "@wordpress/block-editor": "file:packages/block-editor", "@wordpress/block-library": "file:packages/block-library", + "@wordpress/blocks": "file:packages/blocks", "@wordpress/components": "file:packages/components", + "@wordpress/core-data": "file:packages/core-data", "@wordpress/data": "file:packages/data", + "@wordpress/editor": "file:packages/editor", "@wordpress/element": "file:packages/element", "@wordpress/hooks": "file:packages/hooks", "@wordpress/i18n": "file:packages/i18n", diff --git a/packages/edit-site/package.json b/packages/edit-site/package.json index 6d8793910a6fa8..21a66e75628438 100644 --- a/packages/edit-site/package.json +++ b/packages/edit-site/package.json @@ -24,8 +24,11 @@ "@babel/runtime": "^7.4.4", "@wordpress/block-editor": "file:../block-editor", "@wordpress/block-library": "file:../block-library", + "@wordpress/blocks": "file:../blocks", "@wordpress/components": "file:../components", + "@wordpress/core-data": "file:../core-data", "@wordpress/data": "file:../data", + "@wordpress/editor": "file:../editor", "@wordpress/element": "file:../element", "@wordpress/hooks": "file:../hooks", "@wordpress/i18n": "file:../i18n", diff --git a/packages/edit-site/src/components/block-editor/index.js b/packages/edit-site/src/components/block-editor/index.js index c049e78e0c51da..360f7823d89f0a 100644 --- a/packages/edit-site/src/components/block-editor/index.js +++ b/packages/edit-site/src/components/block-editor/index.js @@ -2,8 +2,10 @@ * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { useMemo, useState } from '@wordpress/element'; +import { useMemo, useCallback } from '@wordpress/element'; import { uploadMedia } from '@wordpress/media-utils'; +import { useEntityProp } from '@wordpress/core-data'; +import { parse, serialize } from '@wordpress/blocks'; import { BlockEditorProvider, BlockEditorKeyboardShortcuts, @@ -39,13 +41,32 @@ export default function BlockEditor( { settings: _settings } ) { }, }; }, [ canUserCreateMedia, _settings ] ); - const [ blocks, setBlocks ] = useState( [] ); + const [ content, _setContent ] = useEntityProp( + 'postType', + 'wp_template', + 'content' + ); + const initialBlocks = useMemo( () => { + if ( typeof content !== 'function' ) { + const parsedContent = parse( content ); + return parsedContent.length ? parsedContent : undefined; + } + }, [] ); + const [ blocks = initialBlocks, setBlocks ] = useEntityProp( + 'postType', + 'wp_template', + 'blocks' + ); + const setContent = useCallback( ( nextBlocks ) => { + setBlocks( nextBlocks ); + _setContent( serialize( nextBlocks ) ); + }, [] ); return ( diff --git a/packages/edit-site/src/components/editor/index.js b/packages/edit-site/src/components/editor/index.js index f7f0ef0286b10c..83a0f498a35fca 100644 --- a/packages/edit-site/src/components/editor/index.js +++ b/packages/edit-site/src/components/editor/index.js @@ -1,12 +1,14 @@ /** * WordPress dependencies */ +import { useSelect } from '@wordpress/data'; import { SlotFillProvider, DropZoneProvider, Popover, navigateRegions, } from '@wordpress/components'; +import { EntityProvider } from '@wordpress/core-data'; /** * Internal dependencies @@ -17,17 +19,32 @@ import Sidebar from '../sidebar'; import BlockEditor from '../block-editor'; function Editor( { settings } ) { - return ( + const template = useSelect( + ( select ) => + select( 'core' ).getEntityRecord( + 'postType', + 'wp_template', + settings.templateId + ), + [] + ); + return template ? ( - -
- - - + + +
+ + + + - ); + ) : null; } export default navigateRegions( Editor ); diff --git a/packages/edit-site/src/components/header/index.js b/packages/edit-site/src/components/header/index.js index 2b89acdafa8fbc..196b80834eadd6 100644 --- a/packages/edit-site/src/components/header/index.js +++ b/packages/edit-site/src/components/header/index.js @@ -3,6 +3,11 @@ */ import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import SaveButton from '../save-button'; + export default function Header() { return (
{ __( 'Site Editor' ) } { __( '(beta)' ) } +
+ +
); } diff --git a/packages/edit-site/src/components/header/style.scss b/packages/edit-site/src/components/header/style.scss index f280aa258020d4..84fa28b4cd5918 100644 --- a/packages/edit-site/src/components/header/style.scss +++ b/packages/edit-site/src/components/header/style.scss @@ -31,3 +31,7 @@ font-size: 16px; padding: 0 20px; } + +.edit-site-header__actions { + padding: 0 20px; +} diff --git a/packages/edit-site/src/components/save-button/index.js b/packages/edit-site/src/components/save-button/index.js new file mode 100644 index 00000000000000..ad1ab25b832258 --- /dev/null +++ b/packages/edit-site/src/components/save-button/index.js @@ -0,0 +1,56 @@ +/** + * WordPress dependencies + */ +import { useEntityProp } from '@wordpress/core-data'; +import { useEffect, useState, useCallback } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { EntitiesSavedStates } from '@wordpress/editor'; + +export default function SaveButton() { + const [ , setStatus ] = useEntityProp( 'postType', 'wp_template', 'status' ); + // Publish template if not done yet. + useEffect( () => setStatus( 'publish' ), [] ); + + const { isDirty, isSaving } = useSelect( ( select ) => { + const { getEntityRecordChangesByRecord, isSavingEntityRecord } = select( + 'core' + ); + const entityRecordChangesByRecord = getEntityRecordChangesByRecord(); + const changedKinds = Object.keys( entityRecordChangesByRecord ); + return { + isDirty: changedKinds.length > 0, + isSaving: changedKinds.some( ( changedKind ) => + Object.keys( + entityRecordChangesByRecord[ changedKind ] + ).some( ( changedName ) => + Object.keys( + entityRecordChangesByRecord[ changedKind ][ changedName ] + ).some( ( changedKey ) => + isSavingEntityRecord( changedKind, changedName, changedKey ) + ) + ) + ), + }; + } ); + const disabled = ! isDirty || isSaving; + + const [ isOpen, setIsOpen ] = useState( false ); + const open = useCallback( setIsOpen.bind( null, true ), [] ); + const close = useCallback( setIsOpen.bind( null, false ), [] ); + return ( + <> + + + + ); +}