From 7fe60ffeeaa178250b29f10839f4d9ace46fba72 Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Mon, 7 Jun 2021 20:48:51 +1000 Subject: [PATCH 1/5] Fix inspector opening on click outside widget area (#32450) --- .../edit-widgets/src/components/sidebar/index.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/edit-widgets/src/components/sidebar/index.js b/packages/edit-widgets/src/components/sidebar/index.js index 9f643c2ad9852..7101d2daca153 100644 --- a/packages/edit-widgets/src/components/sidebar/index.js +++ b/packages/edit-widgets/src/components/sidebar/index.js @@ -78,17 +78,17 @@ export default function Sidebar() { const selectedBlock = getSelectedBlock(); - let activeArea = getActiveComplementaryArea( editWidgetsStore.name ); - if ( ! activeArea ) { + const activeArea = getActiveComplementaryArea( editWidgetsStore.name ); + + let currentSelection = activeArea; + if ( ! currentSelection ) { if ( selectedBlock ) { - activeArea = BLOCK_INSPECTOR_IDENTIFIER; + currentSelection = BLOCK_INSPECTOR_IDENTIFIER; } else { - activeArea = WIDGET_AREAS_IDENTIFIER; + currentSelection = WIDGET_AREAS_IDENTIFIER; } } - const isSidebarOpen = !! activeArea; - let widgetAreaBlock; if ( selectedBlock ) { if ( selectedBlock.name === 'core/widget-area' ) { @@ -104,11 +104,11 @@ export default function Sidebar() { } return { - currentArea: activeArea, + currentArea: currentSelection, hasSelectedNonAreaBlock: !! ( selectedBlock && selectedBlock.name !== 'core/widget-area' ), - isGeneralSidebarOpen: isSidebarOpen, + isGeneralSidebarOpen: !! activeArea, selectedWidgetAreaBlock: widgetAreaBlock, }; }, [] ); From 0b6ca99bb7ab06578524d86a038a2d9cf1f1f83c Mon Sep 17 00:00:00 2001 From: tellthemachines Date: Tue, 8 Jun 2021 10:37:36 +1000 Subject: [PATCH 2/5] Assume light theme when editor canvas background color isn't set (#32477) --- packages/block-editor/src/components/editor-styles/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/editor-styles/index.js b/packages/block-editor/src/components/editor-styles/index.js index c9ed97a81cf03..f254715e0d0ac 100644 --- a/packages/block-editor/src/components/editor-styles/index.js +++ b/packages/block-editor/src/components/editor-styles/index.js @@ -31,7 +31,11 @@ function useDarkThemeBodyClassName( styles ) { .getComputedStyle( canvas, null ) .getPropertyValue( 'background-color' ); - if ( tinycolor( backgroundColor ).getLuminance() > 0.5 ) { + // If background is transparent, it should be treated as light color. + if ( + tinycolor( backgroundColor ).getLuminance() > 0.5 || + tinycolor( backgroundColor ).getAlpha() === 0 + ) { body.classList.remove( 'is-dark-theme' ); } else { body.classList.add( 'is-dark-theme' ); From 2d12d52bdba24fc524f3185e84250cf27dbfdd84 Mon Sep 17 00:00:00 2001 From: Nik Tsekouras Date: Tue, 8 Jun 2021 14:30:06 +0300 Subject: [PATCH 3/5] Query Block: Make nested post blocks uneditable (#32505) --- .../block-library/src/post-author/edit.js | 16 +++++++- .../block-library/src/post-content/edit.js | 38 +++++++++++++++-- packages/block-library/src/post-date/edit.js | 15 ++++++- .../block-library/src/post-excerpt/edit.js | 38 +++++++++++------ .../src/post-featured-image/edit.js | 21 +++++++--- packages/block-library/src/post-title/edit.js | 21 ++++++++-- packages/block-library/src/utils/hooks.js | 41 +++++++++++++++++++ 7 files changed, 162 insertions(+), 28 deletions(-) create mode 100644 packages/block-library/src/utils/hooks.js diff --git a/packages/block-library/src/post-author/edit.js b/packages/block-library/src/post-author/edit.js index 6110b36338230..4c5e0d4f4bcf3 100644 --- a/packages/block-library/src/post-author/edit.js +++ b/packages/block-library/src/post-author/edit.js @@ -19,9 +19,21 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { store as coreStore } from '@wordpress/core-data'; -function PostAuthorEdit( { isSelected, context, attributes, setAttributes } ) { +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + +function PostAuthorEdit( { + clientId, + isSelected, + context, + attributes, + setAttributes, +} ) { const { postType, postId } = context; + const isEditable = useIsEditablePostBlock( clientId ); const { authorId, authorDetails, authors } = useSelect( ( select ) => { const { getEditedEntityRecord, getUser, getUsers } = select( @@ -66,7 +78,7 @@ function PostAuthorEdit( { isSelected, context, attributes, setAttributes } ) { <> - { !! authors?.length && ( + { isEditable && !! authors?.length && ( + { content?.rendered } + + ); +} + +function EditableContent( { layout, postType, postId } ) { const themeSupportsLayout = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); return getSettings()?.supportsLayout; @@ -53,6 +73,16 @@ function Content( { layout, postType, postId } ) { return
; } +function Content( props ) { + const { clientId, postType, postId } = props; + const isEditable = useIsEditablePostBlock( clientId ); + return isEditable ? ( + + ) : ( + + ); +} + function Placeholder() { const blockProps = useBlockProps(); return ( @@ -76,6 +106,7 @@ function RecursionError() { } export default function PostContentEdit( { + clientId, context: { postId: contextPostId, postType: contextPostType }, attributes, } ) { @@ -95,6 +126,7 @@ export default function PostContentEdit( { postType={ contextPostType } postId={ contextPostId } layout={ layout } + clientId={ clientId } /> ) : ( diff --git a/packages/block-library/src/post-date/edit.js b/packages/block-library/src/post-date/edit.js index 5e38d307404da..e9d42961a098c 100644 --- a/packages/block-library/src/post-date/edit.js +++ b/packages/block-library/src/post-date/edit.js @@ -26,10 +26,21 @@ import { import { __, sprintf } from '@wordpress/i18n'; import { edit } from '@wordpress/icons'; -export default function PostDateEdit( { attributes, context, setAttributes } ) { +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + +export default function PostDateEdit( { + clientId, + attributes, + context, + setAttributes, +} ) { const { textAlign, format, isLink } = attributes; const { postId, postType } = context; + const isEditable = useIsEditablePostBlock( clientId ); const [ siteFormat ] = useEntityProp( 'root', 'site', 'date_format' ); const [ date, setDate ] = useEntityProp( 'postType', @@ -98,7 +109,7 @@ export default function PostDateEdit( { attributes, context, setAttributes } ) { } } /> - { date && ( + { date && isEditable && ( ); + const excerptContent = isEditable ? ( + + ) : ( + excerpt || postContentExcerpt || __( 'No post excerpt found' ) + ); return ( <> @@ -119,19 +143,7 @@ export default function PostExcerptEditor( {
- + { excerptContent } { ! showMoreOnNewLine && ' ' } { showMoreOnNewLine ? (

diff --git a/packages/block-library/src/post-featured-image/edit.js b/packages/block-library/src/post-featured-image/edit.js index 3acbef2776273..59c5fdac00ca8 100644 --- a/packages/block-library/src/post-featured-image/edit.js +++ b/packages/block-library/src/post-featured-image/edit.js @@ -20,6 +20,11 @@ import { import { __, sprintf } from '@wordpress/i18n'; import { postFeaturedImage } from '@wordpress/icons'; +/** + * Internal dependencies + */ +import { useIsEditablePostBlock } from '../utils/hooks'; + const ALLOWED_MEDIA_TYPES = [ 'image' ]; const placeholderChip = (

@@ -29,12 +34,14 @@ const placeholderChip = ( ); function PostFeaturedImageDisplay( { + clientId, attributes: { isLink }, setAttributes, context: { postId, postType }, noticeUI, noticeOperations, } ) { + const isEditable = useIsEditablePostBlock( clientId ); const [ featuredImage, setFeaturedImage ] = useEntityProp( 'postType', postType, @@ -46,6 +53,7 @@ function PostFeaturedImageDisplay( { featuredImage && select( coreStore ).getMedia( featuredImage ), [ featuredImage ] ); + const blockProps = useBlockProps(); const onSelectImage = ( value ) => { if ( value?.id ) { setFeaturedImage( value.id ); @@ -56,6 +64,9 @@ function PostFeaturedImageDisplay( { noticeOperations.createErrorNotice( message ); } let image; + if ( ! featuredImage && ! isEditable ) { + return
{ placeholderChip }
; + } if ( ! featuredImage ) { image = ( - - { !! media && ( + { !! media && isEditable && ( + - ) } - -
{ image }
+
+ ) } +
{ image }
); } diff --git a/packages/block-library/src/post-title/edit.js b/packages/block-library/src/post-title/edit.js index 2bd3e69d00b6f..d7682fc15ef28 100644 --- a/packages/block-library/src/post-title/edit.js +++ b/packages/block-library/src/post-title/edit.js @@ -22,14 +22,16 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import HeadingLevelDropdown from '../heading/heading-level-dropdown'; +import { useIsEditablePostBlock } from '../utils/hooks'; export default function PostTitleEdit( { + clientId, attributes: { level, textAlign, isLink, rel, linkTarget }, setAttributes, context: { postType, postId }, } ) { const TagName = 0 === level ? 'p' : 'h' + level; - + const isEditable = useIsEditablePostBlock( clientId ); const post = useSelect( ( select ) => select( coreStore ).getEditedEntityRecord( @@ -60,7 +62,7 @@ export default function PostTitleEdit( { ); if ( postType && postId ) { - titleElement = ( + titleElement = isEditable ? ( + ) : ( + <TagName { ...( isLink ? {} : blockProps ) }>{ title }</TagName> ); } if ( isLink ) { - titleElement = ( + titleElement = isEditable ? ( <TagName { ...blockProps }> <PlainText tagName="a" @@ -94,6 +98,17 @@ export default function PostTitleEdit( { __experimentalVersion={ 2 } /> </TagName> + ) : ( + <TagName { ...blockProps }> + <a + href={ link } + target={ linkTarget } + rel={ rel } + onClick={ ( event ) => event.preventDefault() } + > + { title } + </a> + </TagName> ); } diff --git a/packages/block-library/src/utils/hooks.js b/packages/block-library/src/utils/hooks.js new file mode 100644 index 0000000000000..c2ad1ee8999e6 --- /dev/null +++ b/packages/block-library/src/utils/hooks.js @@ -0,0 +1,41 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import queryMetaData from '../query/block.json'; +const { name: queryBlockName } = queryMetaData; + +/** + * Hook that determines if a Post block is editable or not. + * The returned value is used to determine if the specific + * Post block will be rendered in `readonly` mode or not. + * + * For now this is checking if a Post block is nested in + * a Query block. If it is, the block should not be editable. + * + * @param {string} clientId The ID of the block to be checked. + * @return {boolean} Whether the block can be edited or not. + */ +export function useIsEditablePostBlock( clientId ) { + return useSelect( + ( select ) => { + const { getBlockParents, getBlockName } = select( + blockEditorStore + ); + const blockParents = getBlockParents( clientId ); + const hasQueryParent = blockParents.some( + ( parentClientId ) => + getBlockName( parentClientId ) === queryBlockName + ); + return ! hasQueryParent; + }, + [ clientId ] + ); +} + +export default { useIsEditablePostBlock }; From ffc9de172e2b2b8229629c96bf3c63efcefbbd5f Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos <aristath@gmail.com> Date: Tue, 8 Jun 2021 14:03:22 +0300 Subject: [PATCH 4/5] Allow themes to add inline styles for all blocks when using lazy styles loading (#32275) * register empty styles for blocks that don't have any * add style & editorStyle in block.json where missing * only do this if the file doesn't exist * meh, missed the 2nd arg here * Use a filter instead of modifying each block.json file. * Use the register_block_type_args filter * Move filter to compat files --- lib/blocks.php | 5 ++++- lib/compat/wordpress-5.8/block-editor.php | 24 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/blocks.php b/lib/blocks.php index 470148668e892..68d3404a589e9 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -199,6 +199,8 @@ function gutenberg_register_core_block_styles( $block_name ) { // Add a reference to the stylesheet's path to allow calculations for inlining styles in `wp_head`. wp_style_add_data( "wp-block-{$block_name}", 'path', gutenberg_dir_path() . $style_path ); + } else { + wp_register_style( "wp-block-{$block_name}", false ); } if ( file_exists( gutenberg_dir_path() . $editor_style_path ) ) { @@ -210,6 +212,8 @@ function gutenberg_register_core_block_styles( $block_name ) { filemtime( gutenberg_dir_path() . $editor_style_path ) ); wp_style_add_data( "wp-block-{$block_name}-editor", 'rtl', 'replace' ); + } else { + wp_register_style( "wp-block-{$block_name}-editor", false ); } } @@ -466,5 +470,4 @@ function gutenberg_migrate_old_typography_shape( $metadata ) { return $metadata; } - add_filter( 'block_type_metadata', 'gutenberg_migrate_old_typography_shape' ); diff --git a/lib/compat/wordpress-5.8/block-editor.php b/lib/compat/wordpress-5.8/block-editor.php index f7efc7f1ebf6d..983889dd3fbcf 100644 --- a/lib/compat/wordpress-5.8/block-editor.php +++ b/lib/compat/wordpress-5.8/block-editor.php @@ -371,3 +371,27 @@ function gutenberg_block_editor_rest_api_preload( array $preload_paths, $block_e 'after' ); } + +/** + * Filters the arguments for registering a block type. + * + * @todo Remove from the Gutenberg plugin when WordPress 5.8 is the minimum required version. + * + * @param array $args Array of arguments for registering a block type. + * + * @return array Returns the $metadata with any missing `style` and `editorStyle` added. + */ +function gutenberg_add_missing_styles_to_core_block_json( $args ) { + if ( ! empty( $args['name'] ) && 0 === strpos( $args['name'], 'core/' ) ) { + $block_name = str_replace( 'core/', '', $args['name'] ); + + if ( ! isset( $args['style'] ) ) { + $args['style'] = "wp-block-$block_name"; + } + if ( ! isset( $args['editor_style'] ) ) { + $args['editor_style'] = "wp-block-$block_name-editor"; + } + } + return $args; +} +add_filter( 'register_block_type_args', 'gutenberg_add_missing_styles_to_core_block_json' ); From de80f6e76863ad77366a9b186a17965f997eaf4e Mon Sep 17 00:00:00 2001 From: Nik Tsekouras <ntsekouras@outlook.com> Date: Tue, 8 Jun 2021 19:03:17 +0300 Subject: [PATCH 5/5] Rename QueryLoop to PostTemplate and change Query label (#32514) --- lib/block-patterns.php | 28 ++-- lib/blocks.php | 2 +- packages/block-library/src/editor.scss | 2 +- packages/block-library/src/index.js | 4 +- .../{query-loop => post-template}/block.json | 10 +- .../src/{query-loop => post-template}/edit.js | 2 +- .../{query-loop => post-template}/editor.scss | 2 +- .../{query-loop => post-template}/index.js | 0 .../block-library/src/post-template/index.php | 148 ++++++++++++++++++ .../src/{query-loop => post-template}/save.js | 2 +- .../{query-loop => post-template}/style.scss | 6 + .../block-library/src/query-loop/index.php | 88 ----------- packages/block-library/src/query/block.json | 2 +- .../block-library/src/query/edit/index.js | 2 +- .../block-library/src/query/variations.js | 9 +- packages/block-library/src/style.scss | 2 +- packages/blocks/src/api/parser.js | 6 + .../fixtures/blocks/core__post-template.html | 1 + ...ery-loop.json => core__post-template.json} | 2 +- ...d.json => core__post-template.parsed.json} | 2 +- .../core__post-template.serialized.html | 1 + .../fixtures/blocks/core__query-loop.html | 1 - .../blocks/core__query-loop.serialized.html | 1 - packages/e2e-tests/plugins/query-block.php | 8 +- 24 files changed, 202 insertions(+), 129 deletions(-) rename packages/block-library/src/{query-loop => post-template}/block.json (60%) rename packages/block-library/src/{query-loop => post-template}/edit.js (98%) rename packages/block-library/src/{query-loop => post-template}/editor.scss (75%) rename packages/block-library/src/{query-loop => post-template}/index.js (100%) create mode 100644 packages/block-library/src/post-template/index.php rename packages/block-library/src/{query-loop => post-template}/save.js (73%) rename packages/block-library/src/{query-loop => post-template}/style.scss (60%) delete mode 100644 packages/block-library/src/query-loop/index.php create mode 100644 packages/e2e-tests/fixtures/blocks/core__post-template.html rename packages/e2e-tests/fixtures/blocks/{core__query-loop.json => core__post-template.json} (79%) rename packages/e2e-tests/fixtures/blocks/{core__query-loop.parsed.json => core__post-template.parsed.json} (69%) create mode 100644 packages/e2e-tests/fixtures/blocks/core__post-template.serialized.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__query-loop.html delete mode 100644 packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html diff --git a/lib/block-patterns.php b/lib/block-patterns.php index ccc6f8bbf7b68..ff58b6df019a2 100644 --- a/lib/block-patterns.php +++ b/lib/block-patterns.php @@ -21,7 +21,7 @@ function register_gutenberg_patterns() { 'categories' => array( 'query' ), 'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} --> <div class="wp-block-query"> - <!-- wp:query-loop --> + <!-- wp:post-template --> <!-- wp:post-title {"isLink":true} /--> <!-- wp:post-featured-image {"isLink":true,"align":"wide"} /--> <!-- wp:post-excerpt /--> @@ -29,7 +29,7 @@ function register_gutenberg_patterns() { <hr class="wp-block-separator"/> <!-- /wp:separator --> <!-- wp:post-date /--> - <!-- /wp:query-loop --> + <!-- /wp:post-template --> </div> <!-- /wp:query -->', ) @@ -43,7 +43,7 @@ function register_gutenberg_patterns() { 'categories' => array( 'query' ), 'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} --> <div class="wp-block-query"> - <!-- wp:query-loop --> + <!-- wp:post-template --> <!-- wp:columns {"align":"wide"} --> <div class="wp-block-columns alignwide"><!-- wp:column {"width":"66.66%"} --> <div class="wp-block-column" style="flex-basis:66.66%"><!-- wp:post-featured-image {"isLink":true} /--></div> @@ -53,7 +53,7 @@ function register_gutenberg_patterns() { <!-- wp:post-excerpt /--></div> <!-- /wp:column --></div> <!-- /wp:columns --> - <!-- /wp:query-loop --> + <!-- /wp:post-template --> </div> <!-- /wp:query -->', ) @@ -67,7 +67,7 @@ function register_gutenberg_patterns() { 'categories' => array( 'query' ), 'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} --> <div class="wp-block-query"> - <!-- wp:query-loop --> + <!-- wp:post-template --> <!-- wp:columns {"verticalAlignment":"center"} --> <div class="wp-block-columns are-vertically-aligned-center"><!-- wp:column {"verticalAlignment":"center","width":"25%"} --> <div class="wp-block-column is-vertically-aligned-center" style="flex-basis:25%"><!-- wp:post-featured-image {"isLink":true} /--></div> @@ -76,7 +76,7 @@ function register_gutenberg_patterns() { <div class="wp-block-column is-vertically-aligned-center" style="flex-basis:75%"><!-- wp:post-title {"isLink":true} /--></div> <!-- /wp:column --></div> <!-- /wp:columns --> - <!-- /wp:query-loop --> + <!-- /wp:post-template --> </div> <!-- /wp:query -->', ) @@ -90,13 +90,13 @@ function register_gutenberg_patterns() { 'categories' => array( 'query' ), 'content' => '<!-- wp:query {"query":{"perPage":6,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"exclude","inherit":false},"displayLayout":{"type":"flex","columns":3}} --> <div class="wp-block-query"> - <!-- wp:query-loop --> + <!-- wp:post-template --> <!-- wp:group {"tagName":"main","style":{"spacing":{"padding":{"top":"30px","right":"30px","bottom":"30px","left":"30px"}}},"layout":{"inherit":false}} --> <main class="wp-block-group" style="padding-top:30px;padding-right:30px;padding-bottom:30px;padding-left:30px"><!-- wp:post-title {"isLink":true} /--> <!-- wp:post-excerpt {"wordCount":20} /--> <!-- wp:post-date /--></div> <!-- /wp:group --> - <!-- /wp:query-loop --> + <!-- /wp:post-template --> </div> <!-- /wp:query -->', ) @@ -110,7 +110,7 @@ function register_gutenberg_patterns() { 'categories' => array( 'query' ), 'content' => '<!-- wp:group {"align":"full","style":{"spacing":{"padding":{"top":"100px","right":"100px","bottom":"100px","left":"100px"}},"color":{"text":"#ffffff","background":"#000000"}}} --> <div class="wp-block-group alignfull has-text-color has-background" style="background-color:#000000;color:#ffffff;padding-top:100px;padding-right:100px;padding-bottom:100px;padding-left:100px"><!-- wp:query {"query":{"perPage":3,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":false}} --> - <div class="wp-block-query"><!-- wp:query-loop --> + <div class="wp-block-query"><!-- wp:post-template --> <!-- wp:separator {"customColor":"#ffffff","align":"wide","className":"is-style-wide"} --> <hr class="wp-block-separator alignwide has-text-color has-background is-style-wide" style="background-color:#ffffff;color:#ffffff"/> <!-- /wp:separator --> @@ -124,7 +124,7 @@ function register_gutenberg_patterns() { <div class="wp-block-column is-vertically-aligned-center" style="flex-basis:80%"><!-- wp:post-title {"isLink":true,"style":{"typography":{"fontSize":"72px","lineHeight":"1.1"},"color":{"text":"#ffffff","link":"#ffffff"}}} /--></div> <!-- /wp:column --></div> <!-- /wp:columns --> - <!-- /wp:query-loop --></div> + <!-- /wp:post-template --></div> <!-- /wp:query --></div> <!-- /wp:group -->', ) @@ -140,26 +140,26 @@ function register_gutenberg_patterns() { <main class="wp-block-group" style="padding-top:30px;padding-right:30px;padding-bottom:30px;padding-left:30px"><!-- wp:columns --> <div class="wp-block-columns"><!-- wp:column {"width":"50%"} --> <div class="wp-block-column" style="flex-basis:50%"><!-- wp:query {"query":{"perPage":2,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"exclude","inherit":false},"displayLayout":{"type":"list"}} --> - <div class="wp-block-query"><!-- wp:query-loop --> + <div class="wp-block-query"><!-- wp:post-template --> <!-- wp:post-featured-image /--> <!-- wp:post-title /--> <!-- wp:post-date /--> <!-- wp:spacer {"height":200} --> <div style="height:200px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer --> - <!-- /wp:query-loop --></div> + <!-- /wp:post-template --></div> <!-- /wp:query --></div> <!-- /wp:column --> <!-- wp:column {"width":"50%"} --> <div class="wp-block-column" style="flex-basis:50%"><!-- wp:query {"query":{"perPage":2,"pages":0,"offset":2,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"exclude","inherit":false},"displayLayout":{"type":"list"}} --> - <div class="wp-block-query"><!-- wp:query-loop --> + <div class="wp-block-query"><!-- wp:post-template --> <!-- wp:spacer {"height":200} --> <div style="height:200px" aria-hidden="true" class="wp-block-spacer"></div> <!-- /wp:spacer --> <!-- wp:post-featured-image /--> <!-- wp:post-title /--> <!-- wp:post-date /--> - <!-- /wp:query-loop --></div> + <!-- /wp:post-template --></div> <!-- /wp:query --></div> <!-- /wp:column --></div> <!-- /wp:columns --></main> diff --git a/lib/blocks.php b/lib/blocks.php index 68d3404a589e9..e04842e8a9445 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -102,7 +102,7 @@ function gutenberg_reregister_core_block_types() { 'post-navigation-link.php' => 'core/post-navigation-link', 'post-title.php' => 'core/post-title', 'query.php' => 'core/query', - 'query-loop.php' => 'core/query-loop', + 'post-template.php' => 'core/post-template', 'query-title.php' => 'core/query-title', 'query-pagination.php' => 'core/query-pagination', 'query-pagination-next.php' => 'core/query-pagination-next', diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index cef09dbb86549..4118213572e23 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -46,7 +46,7 @@ @import "./text-columns/editor.scss"; @import "./video/editor.scss"; @import "./query-title/editor.scss"; -@import "./query-loop/editor.scss"; +@import "./post-template/editor.scss"; @import "./query/editor.scss"; @import "./query-pagination/editor.scss"; @import "./query-pagination-numbers/editor.scss"; diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index b0e36ae6dba9e..73713305c1030 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -70,7 +70,7 @@ import * as siteTagline from './site-tagline'; import * as siteTitle from './site-title'; import * as templatePart from './template-part'; import * as query from './query'; -import * as queryLoop from './query-loop'; +import * as postTemplate from './post-template'; import * as queryTitle from './query-title'; import * as queryPagination from './query-pagination'; import * as queryPaginationNext from './query-pagination-next'; @@ -175,7 +175,7 @@ export const __experimentalGetCoreBlocks = () => [ siteTitle, query, - queryLoop, + postTemplate, queryTitle, queryPagination, queryPaginationNext, diff --git a/packages/block-library/src/query-loop/block.json b/packages/block-library/src/post-template/block.json similarity index 60% rename from packages/block-library/src/query-loop/block.json rename to packages/block-library/src/post-template/block.json index 1d714c2f38366..e4d5de8281514 100644 --- a/packages/block-library/src/query-loop/block.json +++ b/packages/block-library/src/post-template/block.json @@ -1,10 +1,10 @@ { "apiVersion": 2, - "name": "core/query-loop", - "title": "Query Loop", + "name": "core/post-template", + "title": "Post Template", "category": "design", "parent": [ "core/query" ], - "description": "Query loop.", + "description": "Post Template.", "textdomain": "default", "usesContext": [ "queryId", @@ -18,6 +18,6 @@ "html": false, "align": true }, - "style": "wp-block-query-loop", - "editorStyle": "wp-block-query-loop-editor" + "style": "wp-block-post-template", + "editorStyle": "wp-block-post-template-editor" } diff --git a/packages/block-library/src/query-loop/edit.js b/packages/block-library/src/post-template/edit.js similarity index 98% rename from packages/block-library/src/query-loop/edit.js rename to packages/block-library/src/post-template/edit.js index ec55be2d0d6df..a1fd750cdc861 100644 --- a/packages/block-library/src/query-loop/edit.js +++ b/packages/block-library/src/post-template/edit.js @@ -24,7 +24,7 @@ const TEMPLATE = [ [ 'core/post-date' ], [ 'core/post-excerpt' ], ]; -export default function QueryLoopEdit( { +export default function PostTemplateEdit( { clientId, context: { query: { diff --git a/packages/block-library/src/query-loop/editor.scss b/packages/block-library/src/post-template/editor.scss similarity index 75% rename from packages/block-library/src/query-loop/editor.scss rename to packages/block-library/src/post-template/editor.scss index d0c05ad060565..7b426b0f3d37a 100644 --- a/packages/block-library/src/query-loop/editor.scss +++ b/packages/block-library/src/post-template/editor.scss @@ -1,5 +1,5 @@ .editor-styles-wrapper { - ul.wp-block-query-loop { + ul.wp-block-post-template { padding-left: 0; margin-left: 0; list-style: none; diff --git a/packages/block-library/src/query-loop/index.js b/packages/block-library/src/post-template/index.js similarity index 100% rename from packages/block-library/src/query-loop/index.js rename to packages/block-library/src/post-template/index.js diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php new file mode 100644 index 0000000000000..88e029946c830 --- /dev/null +++ b/packages/block-library/src/post-template/index.php @@ -0,0 +1,148 @@ +<?php +/** + * Server-side rendering of the `core/post-template` block. + * + * @package WordPress + */ + +/** + * Renders the `core/post-template` block on the server. + * + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. + * + * @return string Returns the output of the query, structured using the layout defined by the block's inner blocks. + */ +function render_block_core_post_template( $attributes, $content, $block ) { + $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; + $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; + + $query_args = build_query_vars_from_query_block( $block, $page ); + // Override the custom query with the global query if needed. + $use_global_query = ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ); + if ( $use_global_query ) { + global $wp_query; + if ( $wp_query && isset( $wp_query->query_vars ) && is_array( $wp_query->query_vars ) ) { + // Unset `offset` because if is set, $wp_query overrides/ignores the paged parameter and breaks pagination. + unset( $query_args['offset'] ); + $query_args = wp_parse_args( $wp_query->query_vars, $query_args ); + + if ( empty( $query_args['post_type'] ) && is_singular() ) { + $query_args['post_type'] = get_post_type( get_the_ID() ); + } + } + } + + $query = new WP_Query( $query_args ); + + if ( ! $query->have_posts() ) { + return ''; + } + + $classnames = ''; + if ( isset( $block->context['displayLayout'] ) && isset( $block->context['query'] ) ) { + if ( isset( $block->context['displayLayout']['type'] ) && 'flex' === $block->context['displayLayout']['type'] ) { + $classnames = "is-flex-container columns-{$block->context['displayLayout']['columns']}"; + } + } + + $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) ); + + $content = ''; + while ( $query->have_posts() ) { + $query->the_post(); + $block_content = ( + new WP_Block( + $block->parsed_block, + array( + 'postType' => get_post_type(), + 'postId' => get_the_ID(), + ) + ) + )->render( array( 'dynamic' => false ) ); + $content .= "<li>{$block_content}</li>"; + } + + wp_reset_postdata(); + + return sprintf( + '<ul %1$s>%2$s</ul>', + $wrapper_attributes, + $content + ); +} + +/** + * Registers the `core/post-template` block on the server. + */ +function register_block_core_post_template() { + register_block_type_from_metadata( + __DIR__ . '/post-template', + array( + 'render_callback' => 'render_block_core_post_template', + 'skip_inner_blocks' => true, + ) + ); +} +add_action( 'init', 'register_block_core_post_template' ); + +/** + * Renders the legacy `core/query-loop` block on the server. + * It triggers a developer warning and then calls the renamed + * block's `render_callback` function output. + * + * This can be removed when WordPress 5.9 is released. + * + * @param array $attributes Block attributes. + * @param string $content Block default content. + * @param WP_Block $block Block instance. + * + * @return string Returns the output of the query, structured using the layout defined by the block's inner blocks. + */ +function render_legacy_query_loop_block( $attributes, $content, $block ) { + trigger_error( + /* translators: %1$s: Block type */ + sprintf( __( 'Block %1$s has been renamed to Post Template. %1$s will be supported until WordPress version 5.9.', 'gutenberg' ), $block->name ), + headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE + ); + return render_block_core_post_template( $attributes, $content, $block ); +} + +/** + * Complements the renaming of `Query Loop` to `Post Template`. + * This ensures backwards compatibility for any users running the Gutenberg + * plugin who have used Query Loop prior to its renaming. + * + * This can be removed when WordPress 5.9 is released. + * + * @see https://github.com/WordPress/gutenberg/pull/32514 + */ +function gutenberg_register_legacy_query_loop_block() { + $registry = WP_Block_Type_Registry::get_instance(); + if ( $registry->is_registered( 'core/query-loop' ) ) { + unregister_block_type( 'core/query-loop' ); + } + register_block_type( + 'core/query-loop', + array( + 'category' => 'design', + 'uses_context' => array( + 'queryId', + 'query', + 'queryContext', + 'displayLayout', + 'templateSlug', + ), + 'supports' => array( + 'reusable' => false, + 'html' => false, + 'align' => true, + ), + 'style' => 'wp-block-post-template', + 'render_callback' => 'render_legacy_query_loop_block', + 'skip_inner_blocks' => true, + ) + ); +} +add_action( 'init', 'gutenberg_register_legacy_query_loop_block' ); diff --git a/packages/block-library/src/query-loop/save.js b/packages/block-library/src/post-template/save.js similarity index 73% rename from packages/block-library/src/query-loop/save.js rename to packages/block-library/src/post-template/save.js index 25c0128386512..0533b07693160 100644 --- a/packages/block-library/src/query-loop/save.js +++ b/packages/block-library/src/post-template/save.js @@ -3,6 +3,6 @@ */ import { InnerBlocks } from '@wordpress/block-editor'; -export default function QueryLoopSave() { +export default function PostTemplateSave() { return <InnerBlocks.Content />; } diff --git a/packages/block-library/src/query-loop/style.scss b/packages/block-library/src/post-template/style.scss similarity index 60% rename from packages/block-library/src/query-loop/style.scss rename to packages/block-library/src/post-template/style.scss index 676040b147ebb..7a83a79bcb11f 100644 --- a/packages/block-library/src/query-loop/style.scss +++ b/packages/block-library/src/post-template/style.scss @@ -1,3 +1,9 @@ +.wp-block-post-template, +// We have kept `wp-block-query-loop` class as well for backwards +// compatibility with existing `QueryLoop` blocks that haven't been +// updated, after the renaming of the block to `Post Template`. +// See: https://github.com/WordPress/gutenberg/pull/32514. +// TODO: Remove this class when WordPress 5.9 is released. .wp-block-query-loop { max-width: 100%; list-style: none; diff --git a/packages/block-library/src/query-loop/index.php b/packages/block-library/src/query-loop/index.php deleted file mode 100644 index 9bdeb13f4b81d..0000000000000 --- a/packages/block-library/src/query-loop/index.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * Server-side rendering of the `core/query-loop` block. - * - * @package WordPress - */ - -/** - * Renders the `core/query-loop` block on the server. - * - * @param array $attributes Block attributes. - * @param string $content Block default content. - * @param WP_Block $block Block instance. - * - * @return string Returns the output of the query, structured using the layout defined by the block's inner blocks. - */ -function render_block_core_query_loop( $attributes, $content, $block ) { - $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; - - $query_args = build_query_vars_from_query_block( $block, $page ); - // Override the custom query with the global query if needed. - $use_global_query = ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ); - if ( $use_global_query ) { - global $wp_query; - if ( $wp_query && isset( $wp_query->query_vars ) && is_array( $wp_query->query_vars ) ) { - // Unset `offset` because if is set, $wp_query overrides/ignores the paged parameter and breaks pagination. - unset( $query_args['offset'] ); - $query_args = wp_parse_args( $wp_query->query_vars, $query_args ); - - if ( empty( $query_args['post_type'] ) && is_singular() ) { - $query_args['post_type'] = get_post_type( get_the_ID() ); - } - } - } - - $query = new WP_Query( $query_args ); - - if ( ! $query->have_posts() ) { - return ''; - } - - $classnames = ''; - if ( isset( $block->context['displayLayout'] ) && isset( $block->context['query'] ) ) { - if ( isset( $block->context['displayLayout']['type'] ) && 'flex' === $block->context['displayLayout']['type'] ) { - $classnames = "is-flex-container columns-{$block->context['displayLayout']['columns']}"; - } - } - - $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) ); - - $content = ''; - while ( $query->have_posts() ) { - $query->the_post(); - $block_content = ( - new WP_Block( - $block->parsed_block, - array( - 'postType' => get_post_type(), - 'postId' => get_the_ID(), - ) - ) - )->render( array( 'dynamic' => false ) ); - $content .= "<li>{$block_content}</li>"; - } - - wp_reset_postdata(); - - return sprintf( - '<ul %1$s>%2$s</ul>', - $wrapper_attributes, - $content - ); -} - -/** - * Registers the `core/query-loop` block on the server. - */ -function register_block_core_query_loop() { - register_block_type_from_metadata( - __DIR__ . '/query-loop', - array( - 'render_callback' => 'render_block_core_query_loop', - 'skip_inner_blocks' => true, - ) - ); -} -add_action( 'init', 'register_block_core_query_loop' ); diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index b54713a75aac6..a08dbc2e1326e 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -1,7 +1,7 @@ { "apiVersion": 2, "name": "core/query", - "title": "Query", + "title": "Query Loop", "category": "design", "description": "Displays a list of posts as a result of a query.", "textdomain": "default", diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index 4612033981426..637f05c18a1be 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -24,7 +24,7 @@ import QueryInspectorControls from './query-inspector-controls'; import QueryPlaceholder from './query-placeholder'; import { DEFAULTS_POSTS_PER_PAGE } from '../constants'; -const TEMPLATE = [ [ 'core/query-loop' ] ]; +const TEMPLATE = [ [ 'core/post-template' ] ]; export function QueryContent( { attributes, setAttributes } ) { const { queryId, diff --git a/packages/block-library/src/query/variations.js b/packages/block-library/src/query/variations.js index dbf9290cc58fc..d5790da204810 100644 --- a/packages/block-library/src/query/variations.js +++ b/packages/block-library/src/query/variations.js @@ -35,6 +35,7 @@ const variations = [ author: '', search: '', sticky: 'exclude', + inherit: false, }, }, scope: [ 'inserter' ], @@ -45,7 +46,7 @@ const variations = [ icon: titleDate, innerBlocks: [ [ - 'core/query-loop', + 'core/post-template', {}, [ [ 'core/post-title' ], [ 'core/post-date' ] ], ], @@ -58,7 +59,7 @@ const variations = [ icon: titleExcerpt, innerBlocks: [ [ - 'core/query-loop', + 'core/post-template', {}, [ [ 'core/post-title' ], [ 'core/post-excerpt' ] ], ], @@ -71,7 +72,7 @@ const variations = [ icon: titleDateExcerpt, innerBlocks: [ [ - 'core/query-loop', + 'core/post-template', {}, [ [ 'core/post-title' ], @@ -88,7 +89,7 @@ const variations = [ icon: imageDateTitle, innerBlocks: [ [ - 'core/query-loop', + 'core/post-template', {}, [ [ 'core/post-featured-image' ], diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index 92f072e3bccfb..9cca5d3233e27 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -33,7 +33,7 @@ @import "./post-title/style.scss"; @import "./preformatted/style.scss"; @import "./pullquote/style.scss"; -@import "./query-loop/style.scss"; +@import "./post-template/style.scss"; @import "./query-pagination/style.scss"; @import "./quote/style.scss"; @import "./rss/style.scss"; diff --git a/packages/blocks/src/api/parser.js b/packages/blocks/src/api/parser.js index 829557f89f201..edffe4b4af462 100644 --- a/packages/blocks/src/api/parser.js +++ b/packages/blocks/src/api/parser.js @@ -454,6 +454,12 @@ export function convertLegacyBlocks( name, attributes ) { } name = 'core/embed'; } + + // Convert 'core/query-loop' blocks in existing content to 'core/post-template'. + // TODO: Remove this check when WordPress 5.9 is released. + if ( name === 'core/query-loop' ) { + name = 'core/post-template'; + } return { name, attributes: newAttributes }; } diff --git a/packages/e2e-tests/fixtures/blocks/core__post-template.html b/packages/e2e-tests/fixtures/blocks/core__post-template.html new file mode 100644 index 0000000000000..0664d674bdf95 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__post-template.html @@ -0,0 +1 @@ +<!-- wp:post-template /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.json b/packages/e2e-tests/fixtures/blocks/core__post-template.json similarity index 79% rename from packages/e2e-tests/fixtures/blocks/core__query-loop.json rename to packages/e2e-tests/fixtures/blocks/core__post-template.json index e7edef8b5eb8c..0b67fa4c62cb3 100644 --- a/packages/e2e-tests/fixtures/blocks/core__query-loop.json +++ b/packages/e2e-tests/fixtures/blocks/core__post-template.json @@ -1,7 +1,7 @@ [ { "clientId": "_clientId_0", - "name": "core/query-loop", + "name": "core/post-template", "isValid": true, "attributes": {}, "innerBlocks": [], diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.parsed.json b/packages/e2e-tests/fixtures/blocks/core__post-template.parsed.json similarity index 69% rename from packages/e2e-tests/fixtures/blocks/core__query-loop.parsed.json rename to packages/e2e-tests/fixtures/blocks/core__post-template.parsed.json index 12985d2dd36f8..f7f1fbd82e69c 100644 --- a/packages/e2e-tests/fixtures/blocks/core__query-loop.parsed.json +++ b/packages/e2e-tests/fixtures/blocks/core__post-template.parsed.json @@ -1,6 +1,6 @@ [ { - "blockName": "core/query-loop", + "blockName": "core/post-template", "attrs": {}, "innerBlocks": [], "innerHTML": "", diff --git a/packages/e2e-tests/fixtures/blocks/core__post-template.serialized.html b/packages/e2e-tests/fixtures/blocks/core__post-template.serialized.html new file mode 100644 index 0000000000000..0664d674bdf95 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__post-template.serialized.html @@ -0,0 +1 @@ +<!-- wp:post-template /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.html b/packages/e2e-tests/fixtures/blocks/core__query-loop.html deleted file mode 100644 index 16de7db3703b0..0000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__query-loop.html +++ /dev/null @@ -1 +0,0 @@ -<!-- wp:query-loop /--> diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html b/packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html deleted file mode 100644 index 16de7db3703b0..0000000000000 --- a/packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html +++ /dev/null @@ -1 +0,0 @@ -<!-- wp:query-loop /--> diff --git a/packages/e2e-tests/plugins/query-block.php b/packages/e2e-tests/plugins/query-block.php index f985c0d772224..46f9c363b3278 100644 --- a/packages/e2e-tests/plugins/query-block.php +++ b/packages/e2e-tests/plugins/query-block.php @@ -17,9 +17,9 @@ 'title' => __( 'Query Test 1', 'gutenberg' ), 'blockTypes' => array( 'core/query' ), 'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} --> - <!-- wp:query-loop --> + <!-- wp:post-template --> <!-- wp:post-title {"isLink":true} /--> - <!-- /wp:query-loop --> + <!-- /wp:post-template --> <!-- /wp:query -->', ) ); @@ -29,10 +29,10 @@ 'title' => __( 'Query Test 2', 'gutenberg' ), 'blockTypes' => array( 'core/query' ), 'content' => '<!-- wp:query {"query":{"perPage":1,"pages":0,"offset":0,"postType":"post","categoryIds":[],"tagIds":[],"order":"desc","orderBy":"date","author":"","search":"","exclude":[],"sticky":"","inherit":true}} --> - <!-- wp:query-loop --> + <!-- wp:post-template --> <!-- wp:post-title {"isLink":true} /--> <!-- wp:post-date /--> - <!-- /wp:query-loop --> + <!-- /wp:post-template --> <!-- /wp:query -->', ) );