Skip to content

Commit

Permalink
Add __default binding for pattern overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Apr 12, 2024
1 parent 7fc8973 commit 37d44e8
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 27 deletions.
26 changes: 20 additions & 6 deletions packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ import { name as patternBlockName } from './index';
import { unlock } from '../lock-unlock';

const { useLayoutClasses } = unlock( blockEditorPrivateApis );
const { isOverridableBlock } = unlock( patternsPrivateApis );
const { isOverridableBlock, PARTIAL_SYNCING_SUPPORTED_BLOCKS } =
unlock( patternsPrivateApis );

const fullAlignments = [ 'full', 'wide', 'left', 'right' ];

Expand Down Expand Up @@ -98,11 +99,24 @@ function hasOverridableBlocks( blocks ) {
}

function getOverridableAttributes( block ) {
return Object.entries( block.attributes.metadata.bindings )
.filter(
( [ , binding ] ) => binding.source === 'core/pattern-overrides'
)
.map( ( [ attributeKey ] ) => attributeKey );
const set = new Set();
for ( const [ attributeKey, binding ] of Object.entries(
block.attributes.metadata.bindings
) ) {
if (
attributeKey === '__default' &&
binding.source === 'core/pattern-overrides'
) {
PARTIAL_SYNCING_SUPPORTED_BLOCKS[ block.name ].forEach(
( attribute ) => {
set.add( attribute );
}
);
} else if ( binding.source === 'core/pattern-overrides' ) {
set.add( attributeKey );
}
}
return Array.from( set );
}

function applyInitialContentValuesToInnerBlocks(
Expand Down
37 changes: 36 additions & 1 deletion packages/block-library/src/block/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,48 @@ function render_block_core_block( $attributes ) {
* filter so that it is available when a pattern's inner blocks are
* rendering via do_blocks given it only receives the inner content.
*/
$has_pattern_overrides = isset( $attributes['content'] );
$has_pattern_overrides = isset( $attributes['content'] ) && null !== get_block_bindings_source( 'core/pattern-overrides' );
if ( $has_pattern_overrides ) {
$filter_block_context = static function ( $context ) use ( $attributes ) {
$context['pattern/overrides'] = $attributes['content'];
return $context;
};
add_filter( 'render_block_context', $filter_block_context, 1 );

// Add bindings for the default pattern overrides source.
$apply_default_pattern_overrides_bindings = static function ( $parsed_block ) {
$supported_block_attrs = array(
'core/paragraph' => array( 'content' ),
'core/heading' => array( 'content' ),
'core/image' => array( 'id', 'url', 'title', 'alt' ),
'core/button' => array( 'url', 'text', 'linkTarget', 'rel' ),
);

if (
// Return early if the block isn't one of the supported block types,
! isset( $supported_block_attrs[ $parsed_block['blockName'] ] ) ||
// or doesn't have a name,
! isset( $parsed_block['attrs']['metadata']['name'] ) ||
// or doesn't have the default binding.
empty( $parsed_block['attrs']['metadata']['bindings']['__default'] ) ||
// or the default binding isn't the pattern overrides source.
'core/pattern-overrides' !== $parsed_block['attrs']['metadata']['bindings']['__default']['source']
) {
return $parsed_block;
}

$bindings = array();
foreach ( $supported_block_attrs[ $parsed_block['blockName'] ] as $attribute_name ) {
$bindings[ $attribute_name ] = array( 'source' => 'core/pattern-overrides' );
}
$parsed_block['attrs']['metadata']['bindings'] = array_merge(
$bindings,
$parsed_block['attrs']['metadata']['bindings']
);

return $parsed_block;
};
add_filter( 'render_block_data', $apply_default_pattern_overrides_bindings, 10, 1 );
}

$content = do_blocks( $content );
Expand Down
36 changes: 24 additions & 12 deletions packages/patterns/src/components/pattern-overrides-controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import AllowOverridesModal from './allow-overrides-modal';

function removeBindings( bindings, syncedAttributes ) {
let updatedBindings = {};
// Back-compat: Remove existing duplicate bindings.
for ( const attributeName of syncedAttributes ) {
// Omit any bindings that's not the same source from the `updatedBindings` object.
if (
Expand All @@ -34,12 +35,17 @@ function removeBindings( bindings, syncedAttributes ) {
}

function addBindings( bindings, syncedAttributes ) {
const updatedBindings = { ...bindings };
const updatedBindings = {
...bindings,
__default: { source: PATTERN_OVERRIDES_BINDING_SOURCE },
};
// Back-compat: Remove existing duplicate bindings.
for ( const attributeName of syncedAttributes ) {
if ( ! bindings?.[ attributeName ] ) {
updatedBindings[ attributeName ] = {
source: PATTERN_OVERRIDES_BINDING_SOURCE,
};
if (
updatedBindings[ attributeName ]?.source ===
PATTERN_OVERRIDES_BINDING_SOURCE
) {
delete updatedBindings[ attributeName ];
}
}
return updatedBindings;
Expand All @@ -56,9 +62,18 @@ function PatternOverridesControls( { attributes, name, setAttributes } ) {
( attributeName ) =>
attributes.metadata?.bindings?.[ attributeName ]?.source
);
const isConnectedToOtherSources = attributeSources.every(
( source ) => source && source !== 'core/pattern-overrides'
);
const defaultBindings = attributes.metadata?.bindings?.__default;
const allowOverrides =
defaultBindings?.source === PATTERN_OVERRIDES_BINDING_SOURCE ||
attributeSources.some(
( source ) => source === PATTERN_OVERRIDES_BINDING_SOURCE
);
const isConnectedToOtherSources =
( defaultBindings?.source &&
defaultBindings.source !== PATTERN_OVERRIDES_BINDING_SOURCE ) ||
attributeSources.every(
( source ) => source && source !== PATTERN_OVERRIDES_BINDING_SOURCE
);

function updateBindings( isChecked, customName ) {
const prevBindings = attributes?.metadata?.bindings;
Expand Down Expand Up @@ -99,10 +114,7 @@ function PatternOverridesControls( { attributes, name, setAttributes } ) {
<ToggleControl
__nextHasNoMarginBottom
label={ __( 'Allow overrides' ) }
checked={ attributeSources.some(
( source ) =>
source === PATTERN_OVERRIDES_BINDING_SOURCE
) }
checked={ allowOverrides }
onChange={ ( isChecked ) => {
updateBindings( isChecked );
} }
Expand Down
16 changes: 8 additions & 8 deletions test/e2e/specs/editor/various/pattern-overrides.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ test.describe( 'Pattern Overrides', () => {
metadata: {
name: editableParagraphName,
bindings: {
content: {
__default: {
source: 'core/pattern-overrides',
},
},
Expand Down Expand Up @@ -226,7 +226,7 @@ test.describe( 'Pattern Overrides', () => {
const paragraphName = 'paragraph-name';
const { id } = await requestUtils.createBlock( {
title: 'Pattern',
content: `<!-- wp:paragraph {"metadata":{"name":"${ paragraphName }","bindings":{"content":{"source":"core/pattern-overrides"}}}} -->
content: `<!-- wp:paragraph {"metadata":{"name":"${ paragraphName }","bindings":{"__default":{"source":"core/pattern-overrides"}}}} -->
<p>Editable</p>
<!-- /wp:paragraph -->`,
status: 'publish',
Expand Down Expand Up @@ -275,7 +275,7 @@ test.describe( 'Pattern Overrides', () => {
const { id } = await requestUtils.createBlock( {
title: 'Button with target',
content: `<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button {"metadata":{"name":"${ buttonName }","bindings":{"text":{"source":"core/pattern-overrides"},"url":{"source":"core/pattern-overrides"},"linkTarget":{"source":"core/pattern-overrides"},"rel":{"source":"core/pattern-overrides"}}}} -->
<div class="wp-block-buttons"><!-- wp:button {"metadata":{"name":"${ buttonName }","bindings":{"__default":{"source":"core/pattern-overrides"}}}} -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="http://wp.org" target="_blank" rel="noreferrer noopener nofollow">Button</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->`,
Expand Down Expand Up @@ -385,14 +385,14 @@ test.describe( 'Pattern Overrides', () => {
const headingName = 'Editable heading';
const innerPattern = await requestUtils.createBlock( {
title: 'Inner Pattern',
content: `<!-- wp:paragraph {"metadata":{"name":"${ paragraphName }","bindings":{"content":{"source":"core/pattern-overrides"}}}} -->
content: `<!-- wp:paragraph {"metadata":{"name":"${ paragraphName }","bindings":{"__default":{"source":"core/pattern-overrides"}}}} -->
<p>Inner paragraph</p>
<!-- /wp:paragraph -->`,
status: 'publish',
} );
const outerPattern = await requestUtils.createBlock( {
title: 'Outer Pattern',
content: `<!-- wp:heading {"metadata":{"name":"${ headingName }","bindings":{"content":{"source":"core/pattern-overrides"}}}} -->
content: `<!-- wp:heading {"metadata":{"name":"${ headingName }","bindings":{"__default":{"source":"core/pattern-overrides"}}}} -->
<h2 class="wp-block-heading">Outer heading</h2>
<!-- /wp:heading -->
<!-- wp:block {"ref":${ innerPattern.id },"content":{"${ paragraphName }":{"content":"Inner paragraph (edited)"}}} /-->`,
Expand Down Expand Up @@ -502,10 +502,10 @@ test.describe( 'Pattern Overrides', () => {
const paragraphName = 'Editable paragraph';
const { id } = await requestUtils.createBlock( {
title: 'Pattern',
content: `<!-- wp:heading {"metadata":{"name":"${ headingName }","bindings":{"content":{"source":"core/pattern-overrides"}}}} -->
content: `<!-- wp:heading {"metadata":{"name":"${ headingName }","bindings":{"__default":{"source":"core/pattern-overrides"}}}} -->
<h2 class="wp-block-heading">Heading</h2>
<!-- /wp:heading -->
<!-- wp:paragraph {"metadata":{"name":"${ paragraphName }","bindings":{"content":{"source":"core/pattern-overrides"}}}} -->
<!-- wp:paragraph {"metadata":{"name":"${ paragraphName }","bindings":{"__default":{"source":"core/pattern-overrides"}}}} -->
<p>Paragraph</p>
<!-- /wp:paragraph -->`,
status: 'publish',
Expand Down Expand Up @@ -597,7 +597,7 @@ test.describe( 'Pattern Overrides', () => {
);
const { id } = await requestUtils.createBlock( {
title: 'Pattern',
content: `<!-- wp:image {"metadata":{"name":"${ imageName }","bindings":{"id":{"source":"core/pattern-overrides"},"url":{"source":"core/pattern-overrides"},"title":{"source":"core/pattern-overrides"},"alt":{"source":"core/pattern-overrides"}}}} -->
content: `<!-- wp:image {"metadata":{"name":"${ imageName }","bindings":{"__default":{"source":"core/pattern-overrides"}}}} -->
<figure class="wp-block-image"><img alt=""/></figure>
<!-- /wp:image -->`,
status: 'publish',
Expand Down

0 comments on commit 37d44e8

Please sign in to comment.