From 39175327b784035bde2dffc2944eed6e91f91fe9 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Tue, 5 May 2020 12:34:51 -0700 Subject: [PATCH 01/16] Lib: Support forcing non dynamic renders in WP_Block. --- lib/class-wp-block.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/class-wp-block.php b/lib/class-wp-block.php index d362dea65a071..e3ff3de172a41 100644 --- a/lib/class-wp-block.php +++ b/lib/class-wp-block.php @@ -169,12 +169,14 @@ public function __get( $name ) { /** * Generates the render output for the block. * + * @param bool $no_dynamic Optionally set to true to avoid using the block's render_callback. + * * @return string Rendered block output. */ - public function render() { + public function render( $no_dynamic = false ) { global $post; - $is_dynamic = $this->name && null !== $this->block_type && $this->block_type->is_dynamic(); + $is_dynamic = ! $no_dynamic && $this->name && null !== $this->block_type && $this->block_type->is_dynamic(); $block_content = ''; $index = 0; From a95280e9b98dedb2b63a7d048ab284c4ccaf4c33 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Tue, 5 May 2020 12:35:15 -0700 Subject: [PATCH 02/16] Block Editor: Support live block previews in BlockPreview. --- .../src/components/block-preview/index.js | 15 ++++++++---- .../src/components/block-preview/live.js | 24 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 packages/block-editor/src/components/block-preview/live.js diff --git a/packages/block-editor/src/components/block-preview/index.js b/packages/block-editor/src/components/block-preview/index.js index 3b0658c45dcd8..bace284f9c8dc 100644 --- a/packages/block-editor/src/components/block-preview/index.js +++ b/packages/block-editor/src/components/block-preview/index.js @@ -13,12 +13,15 @@ import { memo, useMemo } from '@wordpress/element'; * Internal dependencies */ import BlockEditorProvider from '../provider'; +import LiveBlockPreview from './live'; import AutoHeightBlockPreview from './auto'; export function BlockPreview( { blocks, __experimentalPadding = 0, viewportWidth = 700, + __experimentalLive = false, + __experimentalOnClick, } ) { const settings = useSelect( ( select ) => select( 'core/block-editor' ).getSettings() @@ -29,10 +32,14 @@ export function BlockPreview( { } return ( - + { __experimentalLive ? ( + + ) : ( + + ) } ); } diff --git a/packages/block-editor/src/components/block-preview/live.js b/packages/block-editor/src/components/block-preview/live.js new file mode 100644 index 0000000000000..792740bb2c02b --- /dev/null +++ b/packages/block-editor/src/components/block-preview/live.js @@ -0,0 +1,24 @@ +/** + * WordPress dependencies + */ +import { Disabled } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import BlockList from '../block-list'; + +export default function LiveBlockPreview( { onClick } ) { + return ( +
+ + + +
+ ); +} From bcf9a0c527461c80138af578c5b38c1d644ab51e Mon Sep 17 00:00:00 2001 From: epiqueras Date: Tue, 5 May 2020 12:36:24 -0700 Subject: [PATCH 03/16] Block Library: Add query block. --- lib/blocks.php | 1 + packages/block-library/src/index.js | 2 + packages/block-library/src/query/block.json | 4 ++ .../block-library/src/query/edit/index.js | 57 +++++++++++++++++++ packages/block-library/src/query/index.js | 23 ++++++++ packages/block-library/src/query/index.php | 55 ++++++++++++++++++ packages/block-library/src/query/save.js | 8 +++ 7 files changed, 150 insertions(+) create mode 100644 packages/block-library/src/query/block.json create mode 100644 packages/block-library/src/query/edit/index.js create mode 100644 packages/block-library/src/query/index.js create mode 100644 packages/block-library/src/query/index.php create mode 100644 packages/block-library/src/query/save.js diff --git a/lib/blocks.php b/lib/blocks.php index 9a381d73a1fd1..740e7645a379d 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -48,6 +48,7 @@ function gutenberg_reregister_core_block_types() { 'post-tags.php' => 'core/post-tags', 'site-title.php' => 'core/site-title', 'template-part.php' => 'core/template-part', + 'query.php' => 'core/query', ) ); } diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index 206c705651e9a..82e0316f6e155 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -65,6 +65,7 @@ import * as socialLink from './social-link'; // Full Site Editing Blocks import * as siteTitle from './site-title'; import * as templatePart from './template-part'; +import * as query from './query'; import * as postTitle from './post-title'; import * as postContent from './post-content'; import * as postAuthor from './post-author'; @@ -197,6 +198,7 @@ export const __experimentalRegisterExperimentalCoreBlocks = ? [ siteTitle, templatePart, + query, postTitle, postContent, postAuthor, diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json new file mode 100644 index 0000000000000..55b19a44b8d6f --- /dev/null +++ b/packages/block-library/src/query/block.json @@ -0,0 +1,4 @@ +{ + "name": "core/query", + "category": "layout" +} diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js new file mode 100644 index 0000000000000..71d6bd1f88e85 --- /dev/null +++ b/packages/block-library/src/query/edit/index.js @@ -0,0 +1,57 @@ +/** + * WordPress dependencies + */ +import { useSelect } from '@wordpress/data'; +import { useMemo, useState } from '@wordpress/element'; +import { + BlockContextProvider, + InnerBlocks, + BlockPreview, +} from '@wordpress/block-editor'; + +export default function QueryEdit( { clientId } ) { + const { posts, blocks } = useSelect( + ( select ) => ( { + // TODO: Import UI for customizing query from sibling files. + posts: select( 'core' ).getEntityRecords( 'postType', 'post', { + per_page: 10, + } ), + blocks: select( 'core/block-editor' ).getBlocks( clientId ), + } ), + [ clientId ] + ); + const blockContexts = useMemo( + () => + posts?.map( ( post ) => ( { + postType: post.type, + postId: post.id, + } ) ), + [ posts ] + ); + const [ activeBlockContext, setActiveBlockContext ] = useState(); + + if ( ! blockContexts ) { + return null; + } + return blockContexts.map( ( blockContext ) => { + return ( + + { blockContext === + ( activeBlockContext || blockContexts[ 0 ] ) ? ( + + ) : ( + + setActiveBlockContext( blockContext ) + } + /> + ) } + + ); + } ); +} diff --git a/packages/block-library/src/query/index.js b/packages/block-library/src/query/index.js new file mode 100644 index 0000000000000..778bce1b1a062 --- /dev/null +++ b/packages/block-library/src/query/index.js @@ -0,0 +1,23 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import edit from './edit'; +import save from './save'; + +const { name } = metadata; +export { metadata, name }; + +export const settings = { + title: __( 'Query' ), + supports: { + html: false, + }, + edit, + save, +}; diff --git a/packages/block-library/src/query/index.php b/packages/block-library/src/query/index.php new file mode 100644 index 0000000000000..25d003158b998 --- /dev/null +++ b/packages/block-library/src/query/index.php @@ -0,0 +1,55 @@ + 'post', + 'posts_per_page' => 10, + ) + ); + + $content = ''; + foreach ( $posts as $post ) { + $content .= ( + new WP_Block( + $block->parsed_block, + array_merge( + $block->available_context ? $block->available_context : array(), + array( + 'postType' => $post->post_type, + 'postId' => $post->ID, + ) + ) + ) + )->render( true ); + } + return $content; +} + +/** + * Registers the `core/query` block on the server. + */ +function register_block_core_query() { + register_block_type_from_metadata( + __DIR__ . '/query', + array( + 'render_callback' => 'render_block_core_query', + ) + ); +} +add_action( 'init', 'register_block_core_query' ); diff --git a/packages/block-library/src/query/save.js b/packages/block-library/src/query/save.js new file mode 100644 index 0000000000000..d9b9bec9c7bc2 --- /dev/null +++ b/packages/block-library/src/query/save.js @@ -0,0 +1,8 @@ +/** + * WordPress dependencies + */ +import { InnerBlocks } from '@wordpress/block-editor'; + +export default function QuerySave() { + return ; +} From d8f1dc557d048b56cb7a12ea7dbc715689d2431b Mon Sep 17 00:00:00 2001 From: epiqueras Date: Tue, 5 May 2020 16:14:31 -0700 Subject: [PATCH 04/16] Query Block: Add query toolbar with per_page control. --- packages/block-library/src/query/block.json | 10 ++- .../block-library/src/query/edit/index.js | 79 ++++++++++++------- .../src/query/edit/query-toolbar.js | 39 +++++++++ 3 files changed, 98 insertions(+), 30 deletions(-) create mode 100644 packages/block-library/src/query/edit/query-toolbar.js diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index 55b19a44b8d6f..b4c67d7d68afa 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -1,4 +1,12 @@ { "name": "core/query", - "category": "layout" + "category": "layout", + "attributes": { + "query": { + "type": "object", + "default": { + "per_page": 3 + } + } + } } diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index 71d6bd1f88e85..06b4fe3adce47 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -4,21 +4,33 @@ import { useSelect } from '@wordpress/data'; import { useMemo, useState } from '@wordpress/element'; import { + BlockControls, BlockContextProvider, InnerBlocks, BlockPreview, } from '@wordpress/block-editor'; -export default function QueryEdit( { clientId } ) { +/** + * Internal dependencies + */ +import QueryToolbar from './query-toolbar'; + +export default function QueryEdit( { + clientId, + attributes: { query }, + setAttributes, +} ) { const { posts, blocks } = useSelect( ( select ) => ( { // TODO: Import UI for customizing query from sibling files. - posts: select( 'core' ).getEntityRecords( 'postType', 'post', { - per_page: 10, - } ), + posts: select( 'core' ).getEntityRecords( + 'postType', + 'post', + query + ), blocks: select( 'core/block-editor' ).getBlocks( clientId ), } ), - [ clientId ] + [ query, clientId ] ); const blockContexts = useMemo( () => @@ -30,28 +42,37 @@ export default function QueryEdit( { clientId } ) { ); const [ activeBlockContext, setActiveBlockContext ] = useState(); - if ( ! blockContexts ) { - return null; - } - return blockContexts.map( ( blockContext ) => { - return ( - - { blockContext === - ( activeBlockContext || blockContexts[ 0 ] ) ? ( - - ) : ( - - setActiveBlockContext( blockContext ) - } - /> - ) } - - ); - } ); + return ( + <> + + + setAttributes( { query: { ...query, ...newQuery } } ) + } + /> + + { blockContexts?.map( ( blockContext ) => { + return ( + + { blockContext === + ( activeBlockContext || blockContexts[ 0 ] ) ? ( + + ) : ( + + setActiveBlockContext( blockContext ) + } + /> + ) } + + ); + } ) } + + ); } diff --git a/packages/block-library/src/query/edit/query-toolbar.js b/packages/block-library/src/query/edit/query-toolbar.js new file mode 100644 index 0000000000000..f4b9519f1c92b --- /dev/null +++ b/packages/block-library/src/query/edit/query-toolbar.js @@ -0,0 +1,39 @@ +/** + * WordPress dependencies + */ +import { + Toolbar, + Dropdown, + ToolbarButton, + RangeControl, +} from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { list } from '@wordpress/icons'; + +export default function QueryToolbar( { query, setQuery } ) { + return ( + + ( + + ) } + renderContent={ () => ( + + setQuery( { per_page: value ?? -1 } ) + } + /> + ) } + /> + + ); +} From 6f94be82dbec273df205aad2c8dd922f0f1b2668 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Tue, 5 May 2020 17:26:31 -0700 Subject: [PATCH 05/16] Components: Fix toolbar CSS selectors. --- packages/block-library/src/query/edit/query-toolbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/query/edit/query-toolbar.js b/packages/block-library/src/query/edit/query-toolbar.js index f4b9519f1c92b..c2d88907718c2 100644 --- a/packages/block-library/src/query/edit/query-toolbar.js +++ b/packages/block-library/src/query/edit/query-toolbar.js @@ -12,7 +12,7 @@ import { list } from '@wordpress/icons'; export default function QueryToolbar( { query, setQuery } ) { return ( - + ( Date: Tue, 5 May 2020 17:40:31 -0700 Subject: [PATCH 06/16] Query Block: Unfocus posts on Query block blur. --- .../block-library/src/query/edit/index.js | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index 06b4fe3adce47..ed2e1b9236381 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { useMemo, useState } from '@wordpress/element'; +import { useMemo, useState, useEffect } from '@wordpress/element'; import { BlockControls, BlockContextProvider, @@ -20,16 +20,21 @@ export default function QueryEdit( { attributes: { query }, setAttributes, } ) { - const { posts, blocks } = useSelect( - ( select ) => ( { - // TODO: Import UI for customizing query from sibling files. - posts: select( 'core' ).getEntityRecords( - 'postType', - 'post', - query - ), - blocks: select( 'core/block-editor' ).getBlocks( clientId ), - } ), + const { posts, isInnerBlockSelected, blocks } = useSelect( + ( select ) => { + const { hasSelectedInnerBlock, getBlocks } = select( + 'core/block-editor' + ); + return { + posts: select( 'core' ).getEntityRecords( + 'postType', + 'post', + query + ), + isInnerBlockSelected: hasSelectedInnerBlock( clientId ), + blocks: getBlocks( clientId ), + }; + }, [ query, clientId ] ); const blockContexts = useMemo( @@ -41,6 +46,11 @@ export default function QueryEdit( { [ posts ] ); const [ activeBlockContext, setActiveBlockContext ] = useState(); + useEffect( () => { + if ( ! isInnerBlockSelected ) { + setActiveBlockContext( null ); + } + }, [ isInnerBlockSelected ] ); return ( <> @@ -58,8 +68,7 @@ export default function QueryEdit( { key={ blockContext.postId } value={ blockContext } > - { blockContext === - ( activeBlockContext || blockContexts[ 0 ] ) ? ( + { blockContext === activeBlockContext ? ( ) : ( Date: Tue, 5 May 2020 19:08:32 -0700 Subject: [PATCH 07/16] Query Block: Add pagination on the edit side. --- packages/block-library/src/query/block.json | 4 +- .../block-library/src/query/edit/index.js | 39 ++++++++++------ .../src/query/edit/pagination.js | 35 +++++++++++++++ .../src/query/edit/query-toolbar.js | 45 +++++++++++++------ 4 files changed, 95 insertions(+), 28 deletions(-) create mode 100644 packages/block-library/src/query/edit/pagination.js diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index b4c67d7d68afa..d9b91ddd18b82 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -5,7 +5,9 @@ "query": { "type": "object", "default": { - "per_page": 3 + "per_page": 3, + "pages": 1, + "offset": 0 } } } diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index ed2e1b9236381..418f17e69cf0e 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -14,29 +14,40 @@ import { * Internal dependencies */ import QueryToolbar from './query-toolbar'; +import Pagination from './pagination'; export default function QueryEdit( { clientId, attributes: { query }, setAttributes, } ) { - const { posts, isInnerBlockSelected, blocks } = useSelect( + const [ page, setPage ] = useState( 1 ); + const [ activeBlockContext, setActiveBlockContext ] = useState(); + + const { isInnerBlockSelected, posts, blocks } = useSelect( ( select ) => { const { hasSelectedInnerBlock, getBlocks } = select( 'core/block-editor' ); return { - posts: select( 'core' ).getEntityRecords( - 'postType', - 'post', - query - ), isInnerBlockSelected: hasSelectedInnerBlock( clientId ), + posts: select( 'core' ).getEntityRecords( 'postType', 'post', { + ...query, + offset: query.per_page * ( page - 1 ) + query.offset, + page, + } ), blocks: getBlocks( clientId ), }; }, - [ query, clientId ] + [ query, page, clientId ] ); + + useEffect( () => { + if ( ! isInnerBlockSelected ) { + setActiveBlockContext( null ); + } + }, [ isInnerBlockSelected ] ); + const blockContexts = useMemo( () => posts?.map( ( post ) => ( { @@ -45,13 +56,6 @@ export default function QueryEdit( { } ) ), [ posts ] ); - const [ activeBlockContext, setActiveBlockContext ] = useState(); - useEffect( () => { - if ( ! isInnerBlockSelected ) { - setActiveBlockContext( null ); - } - }, [ isInnerBlockSelected ] ); - return ( <> @@ -82,6 +86,13 @@ export default function QueryEdit( { ); } ) } + { query.pages !== 1 && ( + + ) } ); } diff --git a/packages/block-library/src/query/edit/pagination.js b/packages/block-library/src/query/edit/pagination.js new file mode 100644 index 0000000000000..ab32007c63c72 --- /dev/null +++ b/packages/block-library/src/query/edit/pagination.js @@ -0,0 +1,35 @@ +/** + * WordPress dependencies + */ +import { ButtonGroup, Button } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; +import { chevronLeft, chevronRight } from '@wordpress/icons'; + +export default function Pagination( { pages, page, setPage } ) { + return ( + + { page > 1 && ( + + ) } + { page < pages && ( + + ) } + + ); +} diff --git a/packages/block-library/src/query/edit/query-toolbar.js b/packages/block-library/src/query/edit/query-toolbar.js index c2d88907718c2..da112d83eed4a 100644 --- a/packages/block-library/src/query/edit/query-toolbar.js +++ b/packages/block-library/src/query/edit/query-toolbar.js @@ -8,7 +8,7 @@ import { RangeControl, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { list } from '@wordpress/icons'; +import { postList } from '@wordpress/icons'; export default function QueryToolbar( { query, setQuery } ) { return ( @@ -16,22 +16,41 @@ export default function QueryToolbar( { query, setQuery } ) { ( ) } renderContent={ () => ( - - setQuery( { per_page: value ?? -1 } ) - } - /> + <> + + setQuery( { per_page: value ?? -1 } ) + } + /> + + setQuery( { pages: value ?? -1 } ) + } + /> + + setQuery( { offset: value ?? 0 } ) + } + /> + ) } /> From 9c633e6d5223ceb8382ec26adb2913a89fd39324 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Wed, 6 May 2020 16:26:58 -0700 Subject: [PATCH 08/16] Query Block: Add pagination on the front end side. --- packages/block-library/src/query/block.json | 3 +++ .../block-library/src/query/edit/index.js | 11 +++++++- packages/block-library/src/query/index.php | 26 ++++++++++++++++--- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index d9b91ddd18b82..38930d6837218 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -2,6 +2,9 @@ "name": "core/query", "category": "layout", "attributes": { + "id": { + "type": "number" + }, "query": { "type": "object", "default": { diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index 418f17e69cf0e..f958648e945e4 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -3,6 +3,7 @@ */ import { useSelect } from '@wordpress/data'; import { useMemo, useState, useEffect } from '@wordpress/element'; +import { useInstanceId } from '@wordpress/compose'; import { BlockControls, BlockContextProvider, @@ -18,7 +19,7 @@ import Pagination from './pagination'; export default function QueryEdit( { clientId, - attributes: { query }, + attributes: { query, id }, setAttributes, } ) { const [ page, setPage ] = useState( 1 ); @@ -42,6 +43,14 @@ export default function QueryEdit( { [ query, page, clientId ] ); + const instanceId = useInstanceId( QueryEdit ); + // We need this for multi-query block pagination. + // Query parameters for each block are scoped to their ID. + useEffect( () => { + if ( ! id ) { + setAttributes( { id: instanceId } ); + } + }, [ id, instanceId ] ); useEffect( () => { if ( ! isInnerBlockSelected ) { setActiveBlockContext( null ); diff --git a/packages/block-library/src/query/index.php b/packages/block-library/src/query/index.php index 25d003158b998..cfa0329592cc6 100644 --- a/packages/block-library/src/query/index.php +++ b/packages/block-library/src/query/index.php @@ -15,15 +15,19 @@ * @return string Returns the output of the query, structured using the layout defined by the block's inner blocks. */ function render_block_core_query( $attributes, $content, $block ) { - // TODO: Use customized query. - $posts = get_posts( + $page_key = 'query-' . $attributes['id'] . '-page'; + $page = empty( $_GET[ $page_key ] ) ? 1 : $_GET[ $page_key ]; + $posts = get_posts( array( 'post_type' => 'post', - 'posts_per_page' => 10, + 'posts_per_page' => $attributes['query']['per_page'], + 'offset' => $attributes['query']['per_page'] * ( $page - 1 ) + $attributes['query']['offset'], ) ); $content = ''; + + // Render posts. foreach ( $posts as $post ) { $content .= ( new WP_Block( @@ -38,6 +42,22 @@ function render_block_core_query( $attributes, $content, $block ) { ) )->render( true ); } + + // Render pagination. + // TODO: Make pagination buttons inner blocks of the Query block. + if ( 1 !== $page ) { + $content .= sprintf( + '', + add_query_arg( $page_key, '2' === $page ? false : $page - 1 ) + ); + } + if ( $page < $attributes['query']['pages'] ) { + $content .= sprintf( + '', + add_query_arg( $page_key, $page + 1 ) + ); + } + return $content; } From d4ac061c675fe1ae8fcbf97a55ae76e767b5a303 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Thu, 7 May 2020 17:29:56 -0700 Subject: [PATCH 09/16] Block Library: Break Query block into multiple sub-blocks. --- lib/blocks.php | 2 + packages/block-library/src/index.js | 4 + .../block-library/src/query-loop/block.json | 5 ++ packages/block-library/src/query-loop/edit.js | 63 ++++++++++++++ .../block-library/src/query-loop/index.js | 26 ++++++ .../block-library/src/query-loop/index.php | 57 +++++++++++++ packages/block-library/src/query-loop/save.js | 8 ++ .../src/query-pagination/block.json | 5 ++ .../src/query-pagination/edit.js | 52 ++++++++++++ .../src/query-pagination/index.js | 24 ++++++ .../src/query-pagination/index.php | 48 +++++++++++ packages/block-library/src/query/block.json | 4 + .../block-library/src/query/edit/index.js | 83 +++---------------- .../src/query/edit/pagination.js | 35 -------- .../src/query/edit/query-provider.js | 35 ++++++++ packages/block-library/src/query/index.js | 2 + packages/block-library/src/query/index.php | 61 +------------- 17 files changed, 346 insertions(+), 168 deletions(-) create mode 100644 packages/block-library/src/query-loop/block.json create mode 100644 packages/block-library/src/query-loop/edit.js create mode 100644 packages/block-library/src/query-loop/index.js create mode 100644 packages/block-library/src/query-loop/index.php create mode 100644 packages/block-library/src/query-loop/save.js create mode 100644 packages/block-library/src/query-pagination/block.json create mode 100644 packages/block-library/src/query-pagination/edit.js create mode 100644 packages/block-library/src/query-pagination/index.js create mode 100644 packages/block-library/src/query-pagination/index.php delete mode 100644 packages/block-library/src/query/edit/pagination.js create mode 100644 packages/block-library/src/query/edit/query-provider.js diff --git a/lib/blocks.php b/lib/blocks.php index 740e7645a379d..98e340de1ab56 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -49,6 +49,8 @@ function gutenberg_reregister_core_block_types() { 'site-title.php' => 'core/site-title', 'template-part.php' => 'core/template-part', 'query.php' => 'core/query', + 'query-loop.php' => 'core/query-loop', + 'query-pagination.php' => 'core/query-pagination', ) ); } diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index 82e0316f6e155..1af6c150e3f13 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -66,6 +66,8 @@ import * as socialLink from './social-link'; 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 queryPagination from './query-pagination'; import * as postTitle from './post-title'; import * as postContent from './post-content'; import * as postAuthor from './post-author'; @@ -199,6 +201,8 @@ export const __experimentalRegisterExperimentalCoreBlocks = siteTitle, templatePart, query, + queryLoop, + queryPagination, postTitle, postContent, postAuthor, diff --git a/packages/block-library/src/query-loop/block.json b/packages/block-library/src/query-loop/block.json new file mode 100644 index 0000000000000..e4405a29a8d47 --- /dev/null +++ b/packages/block-library/src/query-loop/block.json @@ -0,0 +1,5 @@ +{ + "name": "core/query-loop", + "category": "layout", + "context": [ "id", "query" ] +} diff --git a/packages/block-library/src/query-loop/edit.js b/packages/block-library/src/query-loop/edit.js new file mode 100644 index 0000000000000..cd9ebe3db5dbe --- /dev/null +++ b/packages/block-library/src/query-loop/edit.js @@ -0,0 +1,63 @@ +/** + * WordPress dependencies + */ +import { useState, useMemo } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { + BlockContextProvider, + InnerBlocks, + BlockPreview, +} from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import { useQueryContext } from '../query'; + +const TEMPLATE = [ [ 'core/post-title' ] ]; +export default function QueryLoopEdit( { clientId, context: { query } } ) { + const [ { page } ] = useQueryContext(); + const [ activeBlockContext, setActiveBlockContext ] = useState(); + + const { posts, blocks } = useSelect( + ( select ) => ( { + posts: select( 'core' ).getEntityRecords( 'postType', 'post', { + ...query, + offset: query.per_page * ( page - 1 ) + query.offset, + page, + } ), + blocks: select( 'core/block-editor' ).getBlocks( clientId ), + } ), + [ query, page, clientId ] + ); + + const blockContexts = useMemo( + () => + posts?.map( ( post ) => ( { + postType: post.type, + postId: post.id, + } ) ), + [ posts ] + ); + return blockContexts + ? blockContexts.map( ( blockContext ) => ( + + { blockContext === + ( activeBlockContext || blockContexts[ 0 ] ) ? ( + + ) : ( + + setActiveBlockContext( blockContext ) + } + /> + ) } + + ) ) + : null; +} diff --git a/packages/block-library/src/query-loop/index.js b/packages/block-library/src/query-loop/index.js new file mode 100644 index 0000000000000..2e4715e2260a3 --- /dev/null +++ b/packages/block-library/src/query-loop/index.js @@ -0,0 +1,26 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import edit from './edit'; +import save from './save'; + +const { name } = metadata; +export { metadata, name }; + +export const settings = { + title: __( 'Query Loop' ), + parent: [ 'core/query' ], + supports: { + inserter: false, + reusable: false, + html: false, + }, + edit, + save, +}; diff --git a/packages/block-library/src/query-loop/index.php b/packages/block-library/src/query-loop/index.php new file mode 100644 index 0000000000000..ae08d0a252ede --- /dev/null +++ b/packages/block-library/src/query-loop/index.php @@ -0,0 +1,57 @@ +context['id'] . '-page'; + $page = empty( $_GET[ $page_key ] ) ? 1 : $_GET[ $page_key ]; + $posts = get_posts( + array( + 'post_type' => 'post', + 'posts_per_page' => $block->context['query']['per_page'], + 'offset' => $block->context['query']['per_page'] * ( $page - 1 ) + $block->context['query']['offset'], + ) + ); + + $content = ''; + foreach ( $posts as $post ) { + $content .= ( + new WP_Block( + $block->parsed_block, + array_merge( + $block->available_context ? $block->available_context : array(), + array( + 'postType' => $post->post_type, + 'postId' => $post->ID, + ) + ) + ) + )->render( true ); + } + return $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', + ) + ); +} +add_action( 'init', 'register_block_core_query_loop' ); diff --git a/packages/block-library/src/query-loop/save.js b/packages/block-library/src/query-loop/save.js new file mode 100644 index 0000000000000..25c0128386512 --- /dev/null +++ b/packages/block-library/src/query-loop/save.js @@ -0,0 +1,8 @@ +/** + * WordPress dependencies + */ +import { InnerBlocks } from '@wordpress/block-editor'; + +export default function QueryLoopSave() { + return ; +} diff --git a/packages/block-library/src/query-pagination/block.json b/packages/block-library/src/query-pagination/block.json new file mode 100644 index 0000000000000..634b84e6d9e1d --- /dev/null +++ b/packages/block-library/src/query-pagination/block.json @@ -0,0 +1,5 @@ +{ + "name": "core/query-pagination", + "category": "layout", + "context": [ "id", "query" ] +} diff --git a/packages/block-library/src/query-pagination/edit.js b/packages/block-library/src/query-pagination/edit.js new file mode 100644 index 0000000000000..3f30aef90de92 --- /dev/null +++ b/packages/block-library/src/query-pagination/edit.js @@ -0,0 +1,52 @@ +/** + * WordPress dependencies + */ +import { Button, ButtonGroup } from '@wordpress/components'; +import { chevronLeft, chevronRight } from '@wordpress/icons'; +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import { useQueryContext } from '../query'; + +export default function QueryPaginationEdit( { + context: { + query: { pages }, + }, +} ) { + const [ { page }, setQueryContext ] = useQueryContext(); + + let previous; + if ( page > 1 ) { + previous = ( + + ); + } + let next; + if ( page < pages ) { + next = ( + + ); + } + return previous || next ? ( + + { previous } + { next } + + ) : ( + 'No pages to paginate.' + ); +} diff --git a/packages/block-library/src/query-pagination/index.js b/packages/block-library/src/query-pagination/index.js new file mode 100644 index 0000000000000..74ed41fe145f3 --- /dev/null +++ b/packages/block-library/src/query-pagination/index.js @@ -0,0 +1,24 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; + +/** + * Internal dependencies + */ +import metadata from './block.json'; +import edit from './edit'; + +const { name } = metadata; +export { metadata, name }; + +export const settings = { + title: __( 'Query Pagination' ), + parent: [ 'core/query' ], + supports: { + inserter: false, + reusable: false, + html: false, + }, + edit, +}; diff --git a/packages/block-library/src/query-pagination/index.php b/packages/block-library/src/query-pagination/index.php new file mode 100644 index 0000000000000..a0748fe78dd07 --- /dev/null +++ b/packages/block-library/src/query-pagination/index.php @@ -0,0 +1,48 @@ +context['id'] . '-page'; + $page = empty( $_GET[ $page_key ] ) ? 1 : $_GET[ $page_key ]; + + $content = ''; + if ( 1 !== $page ) { + $content .= sprintf( + '', + add_query_arg( $page_key, '2' === $page ? false : $page - 1 ) + ); + } + if ( $page < $block->context['query']['pages'] ) { + $content .= sprintf( + '', + add_query_arg( $page_key, $page + 1 ) + ); + } + return $content; +} + +/** + * Registers the `core/query-pagination` block on the server. + */ +function register_block_core_query_pagination() { + register_block_type_from_metadata( + __DIR__ . '/query-pagination', + array( + 'render_callback' => 'render_block_core_query_pagination', + ) + ); +} +add_action( 'init', 'register_block_core_query_pagination' ); diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index 38930d6837218..a758be3a2eaa4 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -13,5 +13,9 @@ "offset": 0 } } + }, + "providesContext": { + "id": "id", + "query": "query" } } diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index f958648e945e4..56dace199f1da 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -1,48 +1,21 @@ /** * WordPress dependencies */ -import { useSelect } from '@wordpress/data'; -import { useMemo, useState, useEffect } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; -import { - BlockControls, - BlockContextProvider, - InnerBlocks, - BlockPreview, -} from '@wordpress/block-editor'; +import { useEffect } from '@wordpress/element'; +import { BlockControls, InnerBlocks } from '@wordpress/block-editor'; /** * Internal dependencies */ import QueryToolbar from './query-toolbar'; -import Pagination from './pagination'; +import QueryProvider from './query-provider'; +const TEMPLATE = [ [ 'core/query-loop' ], [ 'core/query-pagination' ] ]; export default function QueryEdit( { - clientId, - attributes: { query, id }, + attributes: { id, query }, setAttributes, } ) { - const [ page, setPage ] = useState( 1 ); - const [ activeBlockContext, setActiveBlockContext ] = useState(); - - const { isInnerBlockSelected, posts, blocks } = useSelect( - ( select ) => { - const { hasSelectedInnerBlock, getBlocks } = select( - 'core/block-editor' - ); - return { - isInnerBlockSelected: hasSelectedInnerBlock( clientId ), - posts: select( 'core' ).getEntityRecords( 'postType', 'post', { - ...query, - offset: query.per_page * ( page - 1 ) + query.offset, - page, - } ), - blocks: getBlocks( clientId ), - }; - }, - [ query, page, clientId ] - ); - const instanceId = useInstanceId( QueryEdit ); // We need this for multi-query block pagination. // Query parameters for each block are scoped to their ID. @@ -51,20 +24,6 @@ export default function QueryEdit( { setAttributes( { id: instanceId } ); } }, [ id, instanceId ] ); - useEffect( () => { - if ( ! isInnerBlockSelected ) { - setActiveBlockContext( null ); - } - }, [ isInnerBlockSelected ] ); - - const blockContexts = useMemo( - () => - posts?.map( ( post ) => ( { - postType: post.type, - postId: post.id, - } ) ), - [ posts ] - ); return ( <> @@ -75,33 +34,11 @@ export default function QueryEdit( { } /> - { blockContexts?.map( ( blockContext ) => { - return ( - - { blockContext === activeBlockContext ? ( - - ) : ( - - setActiveBlockContext( blockContext ) - } - /> - ) } - - ); - } ) } - { query.pages !== 1 && ( - - ) } + + + ); } + +export * from './query-provider'; diff --git a/packages/block-library/src/query/edit/pagination.js b/packages/block-library/src/query/edit/pagination.js deleted file mode 100644 index ab32007c63c72..0000000000000 --- a/packages/block-library/src/query/edit/pagination.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * WordPress dependencies - */ -import { ButtonGroup, Button } from '@wordpress/components'; -import { __ } from '@wordpress/i18n'; -import { chevronLeft, chevronRight } from '@wordpress/icons'; - -export default function Pagination( { pages, page, setPage } ) { - return ( - - { page > 1 && ( - - ) } - { page < pages && ( - - ) } - - ); -} diff --git a/packages/block-library/src/query/edit/query-provider.js b/packages/block-library/src/query/edit/query-provider.js new file mode 100644 index 0000000000000..01aa8cecdb98e --- /dev/null +++ b/packages/block-library/src/query/edit/query-provider.js @@ -0,0 +1,35 @@ +/** + * WordPress dependencies + */ +import { + createContext, + useState, + useMemo, + useContext, +} from '@wordpress/element'; + +const QueryContext = createContext(); +export default function QueryProvider( { children } ) { + const [ queryContext, setQueryContext ] = useState( { page: 1 } ); + return ( + [ + queryContext, + ( newQueryContext ) => + setQueryContext( ( currentQueryContext ) => ( { + ...currentQueryContext, + ...newQueryContext, + } ) ), + ], + [ queryContext ] + ) } + > + { children } + + ); +} + +export function useQueryContext() { + return useContext( QueryContext ); +} diff --git a/packages/block-library/src/query/index.js b/packages/block-library/src/query/index.js index 778bce1b1a062..a6271a5c0740d 100644 --- a/packages/block-library/src/query/index.js +++ b/packages/block-library/src/query/index.js @@ -21,3 +21,5 @@ export const settings = { edit, save, }; + +export { useQueryContext } from './edit'; diff --git a/packages/block-library/src/query/index.php b/packages/block-library/src/query/index.php index cfa0329592cc6..2d22338a97df3 100644 --- a/packages/block-library/src/query/index.php +++ b/packages/block-library/src/query/index.php @@ -5,71 +5,12 @@ * @package WordPress */ -/** - * Renders the `core/query` 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( $attributes, $content, $block ) { - $page_key = 'query-' . $attributes['id'] . '-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : $_GET[ $page_key ]; - $posts = get_posts( - array( - 'post_type' => 'post', - 'posts_per_page' => $attributes['query']['per_page'], - 'offset' => $attributes['query']['per_page'] * ( $page - 1 ) + $attributes['query']['offset'], - ) - ); - - $content = ''; - - // Render posts. - foreach ( $posts as $post ) { - $content .= ( - new WP_Block( - $block->parsed_block, - array_merge( - $block->available_context ? $block->available_context : array(), - array( - 'postType' => $post->post_type, - 'postId' => $post->ID, - ) - ) - ) - )->render( true ); - } - - // Render pagination. - // TODO: Make pagination buttons inner blocks of the Query block. - if ( 1 !== $page ) { - $content .= sprintf( - '', - add_query_arg( $page_key, '2' === $page ? false : $page - 1 ) - ); - } - if ( $page < $attributes['query']['pages'] ) { - $content .= sprintf( - '', - add_query_arg( $page_key, $page + 1 ) - ); - } - - return $content; -} - /** * Registers the `core/query` block on the server. */ function register_block_core_query() { register_block_type_from_metadata( - __DIR__ . '/query', - array( - 'render_callback' => 'render_block_core_query', - ) + __DIR__ . '/query' ); } add_action( 'init', 'register_block_core_query' ); From 41288fb0b8a2f07e05dd324437c694b13068187f Mon Sep 17 00:00:00 2001 From: epiqueras Date: Thu, 7 May 2020 17:59:11 -0700 Subject: [PATCH 10/16] Query Block: Support Post Content blocks. --- lib/class-wp-block.php | 12 +++++++----- packages/block-library/src/query-loop/edit.js | 2 +- packages/block-library/src/query-loop/index.php | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/class-wp-block.php b/lib/class-wp-block.php index e3ff3de172a41..1da81fcd0398d 100644 --- a/lib/class-wp-block.php +++ b/lib/class-wp-block.php @@ -179,11 +179,13 @@ public function render( $no_dynamic = false ) { $is_dynamic = ! $no_dynamic && $this->name && null !== $this->block_type && $this->block_type->is_dynamic(); $block_content = ''; - $index = 0; - foreach ( $this->inner_content as $chunk ) { - $block_content .= is_string( $chunk ) ? - $chunk : - $this->inner_blocks[ $index++ ]->render(); + if ( $no_dynamic || empty( $this->block_type->skip_inner_blocks ) ) { + $index = 0; + foreach ( $this->inner_content as $chunk ) { + $block_content .= is_string( $chunk ) ? + $chunk : + $this->inner_blocks[ $index++ ]->render(); + } } if ( $is_dynamic ) { diff --git a/packages/block-library/src/query-loop/edit.js b/packages/block-library/src/query-loop/edit.js index cd9ebe3db5dbe..5e1721ae65ec6 100644 --- a/packages/block-library/src/query-loop/edit.js +++ b/packages/block-library/src/query-loop/edit.js @@ -14,7 +14,7 @@ import { */ import { useQueryContext } from '../query'; -const TEMPLATE = [ [ 'core/post-title' ] ]; +const TEMPLATE = [ [ 'core/post-title' ], [ 'core/post-content' ] ]; export default function QueryLoopEdit( { clientId, context: { query } } ) { const [ { page } ] = useQueryContext(); const [ activeBlockContext, setActiveBlockContext ] = useState(); diff --git a/packages/block-library/src/query-loop/index.php b/packages/block-library/src/query-loop/index.php index ae08d0a252ede..24cc5feb1ac61 100644 --- a/packages/block-library/src/query-loop/index.php +++ b/packages/block-library/src/query-loop/index.php @@ -50,7 +50,8 @@ function register_block_core_query_loop() { register_block_type_from_metadata( __DIR__ . '/query-loop', array( - 'render_callback' => 'render_block_core_query_loop', + 'render_callback' => 'render_block_core_query_loop', + 'skip_inner_blocks' => true, ) ); } From 6c42e5baa002c33ea25f4c8d8402c7dd1d3d2cac Mon Sep 17 00:00:00 2001 From: epiqueras Date: Fri, 8 May 2020 14:26:29 -0700 Subject: [PATCH 11/16] Query Block: Add translations and icon. --- packages/block-library/src/query-loop/index.js | 2 ++ packages/block-library/src/query-pagination/edit.js | 2 +- .../block-library/src/query-pagination/index.php | 10 ++++++---- packages/icons/src/index.js | 1 + packages/icons/src/library/loop.js | 12 ++++++++++++ 5 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 packages/icons/src/library/loop.js diff --git a/packages/block-library/src/query-loop/index.js b/packages/block-library/src/query-loop/index.js index 2e4715e2260a3..31e248678d872 100644 --- a/packages/block-library/src/query-loop/index.js +++ b/packages/block-library/src/query-loop/index.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; +import { loop } from '@wordpress/icons'; /** * Internal dependencies @@ -15,6 +16,7 @@ export { metadata, name }; export const settings = { title: __( 'Query Loop' ), + icon: loop, parent: [ 'core/query' ], supports: { inserter: false, diff --git a/packages/block-library/src/query-pagination/edit.js b/packages/block-library/src/query-pagination/edit.js index 3f30aef90de92..3e93a66367e97 100644 --- a/packages/block-library/src/query-pagination/edit.js +++ b/packages/block-library/src/query-pagination/edit.js @@ -47,6 +47,6 @@ export default function QueryPaginationEdit( { { next } ) : ( - 'No pages to paginate.' + __( 'No pages to paginate.' ) ); } diff --git a/packages/block-library/src/query-pagination/index.php b/packages/block-library/src/query-pagination/index.php index a0748fe78dd07..68ebd8b34f957 100644 --- a/packages/block-library/src/query-pagination/index.php +++ b/packages/block-library/src/query-pagination/index.php @@ -21,14 +21,16 @@ function render_block_core_query_pagination( $attributes, $content, $block ) { $content = ''; if ( 1 !== $page ) { $content .= sprintf( - '', - add_query_arg( $page_key, '2' === $page ? false : $page - 1 ) + '', + add_query_arg( $page_key, '2' === $page ? false : $page - 1 ), + __( 'Previous', 'gutenberg' ) ); } if ( $page < $block->context['query']['pages'] ) { $content .= sprintf( - '', - add_query_arg( $page_key, $page + 1 ) + '', + add_query_arg( $page_key, $page + 1 ), + __( 'Next', 'gutenberg' ) ); } return $content; diff --git a/packages/icons/src/index.js b/packages/icons/src/index.js index a998627afd83a..f0f63d2964263 100644 --- a/packages/icons/src/index.js +++ b/packages/icons/src/index.js @@ -80,6 +80,7 @@ export { default as lifesaver } from './library/lifesaver'; export { default as link } from './library/link'; export { default as linkOff } from './library/link-off'; export { default as list } from './library/list'; +export { default as loop } from './library/loop'; export { default as mapMarker } from './library/map-marker'; export { default as media } from './library/media'; export { default as mediaAndText } from './library/media-and-text'; diff --git a/packages/icons/src/library/loop.js b/packages/icons/src/library/loop.js new file mode 100644 index 0000000000000..ea1ddd8b2940a --- /dev/null +++ b/packages/icons/src/library/loop.js @@ -0,0 +1,12 @@ +/** + * WordPress dependencies + */ +import { SVG, Path } from '@wordpress/primitives'; + +const loop = ( + + + +); + +export default loop; From 73e28ac2e1868692fd00e95bb4bea73af739bb81 Mon Sep 17 00:00:00 2001 From: Enrique Piqueras Date: Tue, 12 May 2020 09:27:11 -0700 Subject: [PATCH 12/16] Update packages/block-library/src/query-pagination/index.php Co-authored-by: Andrew Duthie --- packages/block-library/src/query-pagination/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/query-pagination/index.php b/packages/block-library/src/query-pagination/index.php index 68ebd8b34f957..ce5013fca3429 100644 --- a/packages/block-library/src/query-pagination/index.php +++ b/packages/block-library/src/query-pagination/index.php @@ -22,7 +22,7 @@ function render_block_core_query_pagination( $attributes, $content, $block ) { if ( 1 !== $page ) { $content .= sprintf( '', - add_query_arg( $page_key, '2' === $page ? false : $page - 1 ), + esc_url( add_query_arg( $page_key, '2' === $page ? false : $page - 1 ) ), __( 'Previous', 'gutenberg' ) ); } From f2827e9caa0c44c86976225f91b7483038d19090 Mon Sep 17 00:00:00 2001 From: Enrique Piqueras Date: Tue, 12 May 2020 09:27:22 -0700 Subject: [PATCH 13/16] Update packages/block-library/src/query-pagination/index.php Co-authored-by: Andrew Duthie --- packages/block-library/src/query-pagination/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/query-pagination/index.php b/packages/block-library/src/query-pagination/index.php index ce5013fca3429..ad829921858e3 100644 --- a/packages/block-library/src/query-pagination/index.php +++ b/packages/block-library/src/query-pagination/index.php @@ -29,7 +29,7 @@ function render_block_core_query_pagination( $attributes, $content, $block ) { if ( $page < $block->context['query']['pages'] ) { $content .= sprintf( '', - add_query_arg( $page_key, $page + 1 ), + esc_url( add_query_arg( $page_key, $page + 1 ) ), __( 'Next', 'gutenberg' ) ); } From 9a2bd88dd01294147f651934b335af607bd3c603 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Tue, 12 May 2020 09:30:51 -0700 Subject: [PATCH 14/16] Lib: Wrap the new block render parameter in an options array. --- lib/class-wp-block.php | 17 ++++++++++++----- packages/block-library/src/query-loop/index.php | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/class-wp-block.php b/lib/class-wp-block.php index 1da81fcd0398d..e6ae099c198c9 100644 --- a/lib/class-wp-block.php +++ b/lib/class-wp-block.php @@ -169,17 +169,24 @@ public function __get( $name ) { /** * Generates the render output for the block. * - * @param bool $no_dynamic Optionally set to true to avoid using the block's render_callback. + * @param array $options Optional options object. + * bool $options.dynamic Optionally set to false to avoid using the block's render_callback. * * @return string Rendered block output. */ - public function render( $no_dynamic = false ) { + public function render( $options = array() ) { global $post; - - $is_dynamic = ! $no_dynamic && $this->name && null !== $this->block_type && $this->block_type->is_dynamic(); + $options = array_replace( + array( + 'dynamic' => true, + ), + $options + ); + + $is_dynamic = $options['dynamic'] && $this->name && null !== $this->block_type && $this->block_type->is_dynamic(); $block_content = ''; - if ( $no_dynamic || empty( $this->block_type->skip_inner_blocks ) ) { + if ( ! $options['dynamic'] || empty( $this->block_type->skip_inner_blocks ) ) { $index = 0; foreach ( $this->inner_content as $chunk ) { $block_content .= is_string( $chunk ) ? diff --git a/packages/block-library/src/query-loop/index.php b/packages/block-library/src/query-loop/index.php index 24cc5feb1ac61..4324d07de1510 100644 --- a/packages/block-library/src/query-loop/index.php +++ b/packages/block-library/src/query-loop/index.php @@ -38,7 +38,7 @@ function render_block_core_query_loop( $attributes, $content, $block ) { ) ) ) - )->render( true ); + )->render( array( 'dynamic' => false ) ); } return $content; } From fb75adc3d3d015fcb66963d8f55d442f5d4905c6 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Wed, 13 May 2020 11:32:37 -0700 Subject: [PATCH 15/16] E2E Tests: Add fixtures. --- .../fixtures/blocks/core__query-loop.html | 1 + .../fixtures/blocks/core__query-loop.json | 10 ++++++++++ .../blocks/core__query-loop.parsed.json | 18 ++++++++++++++++++ .../blocks/core__query-loop.serialized.html | 1 + .../blocks/core__query-pagination.html | 1 + .../blocks/core__query-pagination.json | 10 ++++++++++ .../blocks/core__query-pagination.parsed.json | 18 ++++++++++++++++++ .../core__query-pagination.serialized.html | 1 + .../e2e-tests/fixtures/blocks/core__query.html | 1 + .../e2e-tests/fixtures/blocks/core__query.json | 16 ++++++++++++++++ .../fixtures/blocks/core__query.parsed.json | 18 ++++++++++++++++++ .../blocks/core__query.serialized.html | 1 + 12 files changed, 96 insertions(+) create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-loop.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-loop.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-loop.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-pagination.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-pagination.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-pagination.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__query-pagination.serialized.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__query.html create mode 100644 packages/e2e-tests/fixtures/blocks/core__query.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__query.parsed.json create mode 100644 packages/e2e-tests/fixtures/blocks/core__query.serialized.html diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.html b/packages/e2e-tests/fixtures/blocks/core__query-loop.html new file mode 100644 index 0000000000000..16de7db3703b0 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-loop.html @@ -0,0 +1 @@ + diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.json b/packages/e2e-tests/fixtures/blocks/core__query-loop.json new file mode 100644 index 0000000000000..a0ef058ebe6b2 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-loop.json @@ -0,0 +1,10 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/query-loop", + "isValid": true, + "attributes": {}, + "innerBlocks": [], + "originalContent": "" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.parsed.json b/packages/e2e-tests/fixtures/blocks/core__query-loop.parsed.json new file mode 100644 index 0000000000000..87dc8a385cc60 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-loop.parsed.json @@ -0,0 +1,18 @@ +[ + { + "blockName": "core/query-loop", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html b/packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html new file mode 100644 index 0000000000000..16de7db3703b0 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-loop.serialized.html @@ -0,0 +1 @@ + diff --git a/packages/e2e-tests/fixtures/blocks/core__query-pagination.html b/packages/e2e-tests/fixtures/blocks/core__query-pagination.html new file mode 100644 index 0000000000000..912a9515fee7f --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-pagination.html @@ -0,0 +1 @@ + diff --git a/packages/e2e-tests/fixtures/blocks/core__query-pagination.json b/packages/e2e-tests/fixtures/blocks/core__query-pagination.json new file mode 100644 index 0000000000000..079862a6cd1af --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-pagination.json @@ -0,0 +1,10 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/query-pagination", + "isValid": true, + "attributes": {}, + "innerBlocks": [], + "originalContent": "" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__query-pagination.parsed.json b/packages/e2e-tests/fixtures/blocks/core__query-pagination.parsed.json new file mode 100644 index 0000000000000..580f3b5ef78a7 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-pagination.parsed.json @@ -0,0 +1,18 @@ +[ + { + "blockName": "core/query-pagination", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__query-pagination.serialized.html b/packages/e2e-tests/fixtures/blocks/core__query-pagination.serialized.html new file mode 100644 index 0000000000000..912a9515fee7f --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query-pagination.serialized.html @@ -0,0 +1 @@ + diff --git a/packages/e2e-tests/fixtures/blocks/core__query.html b/packages/e2e-tests/fixtures/blocks/core__query.html new file mode 100644 index 0000000000000..b15b17b5bd419 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query.html @@ -0,0 +1 @@ + diff --git a/packages/e2e-tests/fixtures/blocks/core__query.json b/packages/e2e-tests/fixtures/blocks/core__query.json new file mode 100644 index 0000000000000..6f1430d192b7b --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query.json @@ -0,0 +1,16 @@ +[ + { + "clientId": "_clientId_0", + "name": "core/query", + "isValid": true, + "attributes": { + "query": { + "per_page": 3, + "pages": 1, + "offset": 0 + } + }, + "innerBlocks": [], + "originalContent": "" + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__query.parsed.json b/packages/e2e-tests/fixtures/blocks/core__query.parsed.json new file mode 100644 index 0000000000000..168738416c6dc --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query.parsed.json @@ -0,0 +1,18 @@ +[ + { + "blockName": "core/query", + "attrs": {}, + "innerBlocks": [], + "innerHTML": "", + "innerContent": [] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n", + "innerContent": [ + "\n" + ] + } +] diff --git a/packages/e2e-tests/fixtures/blocks/core__query.serialized.html b/packages/e2e-tests/fixtures/blocks/core__query.serialized.html new file mode 100644 index 0000000000000..b15b17b5bd419 --- /dev/null +++ b/packages/e2e-tests/fixtures/blocks/core__query.serialized.html @@ -0,0 +1 @@ + From 30e0684409190fae35c3815e435236829b7361e5 Mon Sep 17 00:00:00 2001 From: epiqueras Date: Wed, 13 May 2020 12:14:59 -0700 Subject: [PATCH 16/16] Query Block: Refactor variable names. --- lib/class-wp-block.php | 7 +++++-- packages/block-library/src/query-loop/block.json | 2 +- packages/block-library/src/query-loop/index.php | 4 ++-- packages/block-library/src/query-pagination/block.json | 2 +- packages/block-library/src/query-pagination/index.php | 4 ++-- packages/block-library/src/query/block.json | 4 ++-- packages/block-library/src/query/edit/index.js | 8 ++++---- 7 files changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/class-wp-block.php b/lib/class-wp-block.php index e6ae099c198c9..7d1871251bde8 100644 --- a/lib/class-wp-block.php +++ b/lib/class-wp-block.php @@ -169,8 +169,11 @@ public function __get( $name ) { /** * Generates the render output for the block. * - * @param array $options Optional options object. - * bool $options.dynamic Optionally set to false to avoid using the block's render_callback. + * @param array $options { + * Optional options object. + * + * @type bool $dynamic Defaults to 'true'. Optionally set to false to avoid using the block's render_callback. + * } * * @return string Rendered block output. */ diff --git a/packages/block-library/src/query-loop/block.json b/packages/block-library/src/query-loop/block.json index e4405a29a8d47..f79ec0ac1db11 100644 --- a/packages/block-library/src/query-loop/block.json +++ b/packages/block-library/src/query-loop/block.json @@ -1,5 +1,5 @@ { "name": "core/query-loop", "category": "layout", - "context": [ "id", "query" ] + "context": [ "queryId", "query" ] } diff --git a/packages/block-library/src/query-loop/index.php b/packages/block-library/src/query-loop/index.php index 4324d07de1510..bb8fed8fa3ed9 100644 --- a/packages/block-library/src/query-loop/index.php +++ b/packages/block-library/src/query-loop/index.php @@ -15,8 +15,8 @@ * @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 = 'query-' . $block->context['id'] . '-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : $_GET[ $page_key ]; + $page_key = 'query-' . $block->context['queryId'] . '-page'; + $page = empty( $_GET[ $page_key ] ) ? 1 : filter_var( $_GET[ $page_key ], FILTER_VALIDATE_INT ); $posts = get_posts( array( 'post_type' => 'post', diff --git a/packages/block-library/src/query-pagination/block.json b/packages/block-library/src/query-pagination/block.json index 634b84e6d9e1d..e278e183020bc 100644 --- a/packages/block-library/src/query-pagination/block.json +++ b/packages/block-library/src/query-pagination/block.json @@ -1,5 +1,5 @@ { "name": "core/query-pagination", "category": "layout", - "context": [ "id", "query" ] + "context": [ "queryId", "query" ] } diff --git a/packages/block-library/src/query-pagination/index.php b/packages/block-library/src/query-pagination/index.php index ad829921858e3..6d26e5a424df6 100644 --- a/packages/block-library/src/query-pagination/index.php +++ b/packages/block-library/src/query-pagination/index.php @@ -15,8 +15,8 @@ * @return string Returns the pagination for the query. */ function render_block_core_query_pagination( $attributes, $content, $block ) { - $page_key = 'query-' . $block->context['id'] . '-page'; - $page = empty( $_GET[ $page_key ] ) ? 1 : $_GET[ $page_key ]; + $page_key = 'query-' . $block->context['queryId'] . '-page'; + $page = empty( $_GET[ $page_key ] ) ? 1 : filter_var( $_GET[ $page_key ], FILTER_VALIDATE_INT ); $content = ''; if ( 1 !== $page ) { diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index a758be3a2eaa4..a7ec559ecd405 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -2,7 +2,7 @@ "name": "core/query", "category": "layout", "attributes": { - "id": { + "queryId": { "type": "number" }, "query": { @@ -15,7 +15,7 @@ } }, "providesContext": { - "id": "id", + "queryId": "queryId", "query": "query" } } diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index 56dace199f1da..a8ed146b01e4f 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -13,17 +13,17 @@ import QueryProvider from './query-provider'; const TEMPLATE = [ [ 'core/query-loop' ], [ 'core/query-pagination' ] ]; export default function QueryEdit( { - attributes: { id, query }, + attributes: { queryId, query }, setAttributes, } ) { const instanceId = useInstanceId( QueryEdit ); // We need this for multi-query block pagination. // Query parameters for each block are scoped to their ID. useEffect( () => { - if ( ! id ) { - setAttributes( { id: instanceId } ); + if ( ! queryId ) { + setAttributes( { queryId: instanceId } ); } - }, [ id, instanceId ] ); + }, [ queryId, instanceId ] ); return ( <>