Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query block setup with block patterns integration #28891

Merged
merged 14 commits into from
Feb 25, 2021
64 changes: 64 additions & 0 deletions lib/block-patterns.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* Block patterns registration.
*
* @package gutenberg
*/

// Initial Query block patterns.
register_block_pattern(
'query/large-posts',
array(
'title' => __( 'Large', 'gutenberg' ),
'scope' => array(
'inserter' => false,
'block' => array( 'core/query' ),
),
'content' => '<!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-featured-image {"isLink":true,"align":"wide"} /-->
<!-- wp:post-excerpt /-->
<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->
<!-- wp:post-date /-->',
)
);

register_block_pattern(
'query/medium-posts',
array(
'title' => __( 'Medium', 'gutenberg' ),
'scope' => array(
'inserter' => false,
'block' => array( 'core/query' ),
),
'content' => '<!-- 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>
<!-- /wp:column -->
<!-- wp:column {"width":"33.33%"} -->
<div class="wp-block-column" style="flex-basis:33.33%"><!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-excerpt /--></div>
<!-- /wp:column --></div>
<!-- /wp:columns -->',
)
);

register_block_pattern(
'query/small-posts',
array(
'title' => __( 'Small', 'gutenberg' ),
'scope' => array(
'inserter' => false,
'block' => array( 'core/query' ),
),
'content' => '<!-- 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>
<!-- /wp:column -->
<!-- wp:column {"verticalAlignment":"center","width":"75%"} -->
<div class="wp-block-column is-vertically-aligned-center" style="flex-basis:75%"><!-- wp:post-title {"isLink":true} /--></div>
<!-- /wp:column --></div>
<!-- /wp:columns -->',
)
);
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/full-site-editing/edit-site-export.php';

require __DIR__ . '/blocks.php';
require __DIR__ . '/block-patterns.php';
require __DIR__ . '/client-assets.php';
require __DIR__ . '/demo.php';
require __DIR__ . '/widgets.php';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ const usePatternsState = ( onInsert, rootClientId ) => {
const { __experimentalGetAllowedPatterns, getSettings } = select(
blockEditorStore
);
const inserterPatterns = __experimentalGetAllowedPatterns(
rootClientId
).filter(
( pattern ) => ! pattern.scope || pattern.scope.inserter
);
return {
patterns: __experimentalGetAllowedPatterns( rootClientId ),
patterns: inserterPatterns,
patternCategories: getSettings()
.__experimentalBlockPatternCategories,
};
Expand Down
26 changes: 26 additions & 0 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1801,6 +1801,32 @@ export const __experimentalGetAllowedPatterns = createSelector(
]
);

/**
* Returns the list of patterns based on specific `scope` and
* a block's name.
* `inserter` scope should be handled differently, probably in
* combination with `__experimentalGetAllowedPatterns`.
* For now `__experimentalGetScopedBlockPatterns` handles properly
* all other scopes.
* Since both APIs are experimental we should revisit this.
*
* @param {Object} state Editor state.
* @param {string} scope Block pattern scope.
* @param {string} blockName Block's name.
*
* @return {Array} The list of matched block patterns based on provided scope and block name.
*/
export const __experimentalGetScopedBlockPatterns = createSelector(
( state, scope, blockName ) => {
if ( ! scope && ! blockName ) return EMPTY_ARRAY;
const patterns = state.settings.__experimentalBlockPatterns;
return patterns.filter( ( pattern ) =>
pattern.scope?.[ scope ]?.includes?.( blockName )
);
},
( state ) => [ state.settings.__experimentalBlockPatterns ]
);

/**
* Returns the Block List settings of a block, if any exist.
*
Expand Down
48 changes: 48 additions & 0 deletions packages/block-editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const {
__experimentalGetActiveBlockIdByBlockNames: getActiveBlockIdByBlockNames,
__experimentalGetParsedReusableBlock,
__experimentalGetAllowedPatterns,
__experimentalGetScopedBlockPatterns,
} = selectors;

describe( 'selectors', () => {
Expand Down Expand Up @@ -3402,6 +3403,53 @@ describe( 'selectors', () => {
).toHaveLength( 0 );
} );
} );
describe( '__experimentalGetScopedBlockPatterns', () => {
const state = {
blocks: {},
settings: {
__experimentalBlockPatterns: [
{
title: 'pattern a',
scope: { block: [ 'test/block-a' ] },
},
{
title: 'pattern b',
scope: { block: [ 'test/block-b' ] },
},
],
},
};
it( 'should return empty array if no scope and block name is provided', () => {
expect( __experimentalGetScopedBlockPatterns( state ) ).toEqual(
[]
);
expect(
__experimentalGetScopedBlockPatterns( state, 'block' )
).toEqual( [] );
} );
it( 'shoud return empty array if no match is found', () => {
const patterns = __experimentalGetScopedBlockPatterns(
state,
'block',
'test/block-not-exists'
);
expect( patterns ).toEqual( [] );
} );
it( 'should return proper results when there are matched block patterns', () => {
const patterns = __experimentalGetScopedBlockPatterns(
state,
'block',
'test/block-a'
);
expect( patterns ).toHaveLength( 1 );
expect( patterns[ 0 ] ).toEqual(
expect.objectContaining( {
title: 'pattern a',
scope: { block: [ 'test/block-a' ] },
} )
);
} );
} );
} );

describe( '__experimentalGetParsedReusableBlock', () => {
Expand Down
49 changes: 49 additions & 0 deletions packages/block-library/src/query/edit/block-setup/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* WordPress dependencies
*/
import { useSelect } from '@wordpress/data';
import { useBlockProps } from '@wordpress/block-editor';
import { store as blocksStore } from '@wordpress/blocks';
import { Placeholder } from '@wordpress/components';

/**
* Internal dependencies
*/
import LayoutSetupStep from './layout-step';
ntsekouras marked this conversation as resolved.
Show resolved Hide resolved

const BlockSetup = ( {
blockName,
useLayoutSetup,
onVariationSelect = () => {},
onBlockPatternSelect = () => {},
children,
} ) => {
const { blockType } = useSelect(
( select ) => {
const { getBlockType } = select( blocksStore );
return { blockType: getBlockType( blockName ) };
},
[ blockName ]
);
const blockProps = useBlockProps();
return (
<div { ...blockProps }>
<Placeholder
icon={ blockType?.icon?.src }
label={ blockType?.title }
isColumnLayout
>
{ useLayoutSetup && (
<LayoutSetupStep
blockType={ blockType }
onVariationSelect={ onVariationSelect }
onBlockPatternSelect={ onBlockPatternSelect }
/>
) }
{ children }
</Placeholder>
</div>
);
};

export default BlockSetup;
Loading