Skip to content

Commit

Permalink
Try using the block connections api
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronrobertshaw authored and kevin940726 committed Nov 24, 2023
1 parent fce345d commit dc91763
Show file tree
Hide file tree
Showing 11 changed files with 479 additions and 55 deletions.
36 changes: 36 additions & 0 deletions lib/block-supports/pattern.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/**
* Pattern block support flag.
*
* @package gutenberg
*/

$gutenberg_experiments = get_option( 'gutenberg-experiments' );
if ( $gutenberg_experiments && array_key_exists( 'gutenberg-connections', $gutenberg_experiments ) ) {
/**
* Registers the dynamicContent context for block types that support it.
*
* @param WP_Block_Type $block_type Block Type.
*/
function gutenberg_register_pattern_support( $block_type ) {
$pattern_support = property_exists( $block_type, 'supports' ) ? _wp_array_get( $block_type->supports, array( '__experimentalConnections' ), false ) : false;

if ( $pattern_support ) {
if ( ! $block_type->uses_context ) {
$block_type->uses_context = array();
}

if ( ! in_array( 'dynamicContent', $block_type->uses_context, true ) ) {
$block_type->uses_context[] = 'dynamicContent';
}
}
}

// Register the block support.
WP_Block_Supports::get_instance()->register(
'pattern',
array(
'register_attribute' => 'gutenberg_register_pattern_support',
)
);
}
10 changes: 7 additions & 3 deletions lib/experimental/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,8 @@ function gutenberg_render_block_connections( $block_content, $block, $block_inst
continue;
}

// If the source value is not "meta_fields", skip it because the only supported
// connection source is meta (custom fields) for now.
if ( 'meta_fields' !== $attribute_value['source'] ) {
// Skip if the source value is not "meta_fields" or "pattern_attributes".
if ( 'meta_fields' !== $attribute_value['source'] && 'pattern_attributes' !== $attribute_value['source'] ) {
continue;
}

Expand All @@ -154,6 +153,10 @@ function gutenberg_render_block_connections( $block_content, $block, $block_inst
$attribute_value['value']
);

if ( false === $custom_value ) {
continue;
}

$tags = new WP_HTML_Tag_Processor( $block_content );
$found = $tags->next_tag(
array(
Expand Down Expand Up @@ -181,5 +184,6 @@ function gutenberg_render_block_connections( $block_content, $block, $block_inst

return $block_content;
}

add_filter( 'render_block', 'gutenberg_render_block_connections', 10, 3 );
}
7 changes: 5 additions & 2 deletions lib/experimental/connection-sources/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
*/

return array(
'name' => 'meta',
'meta_fields' => function ( $block_instance, $meta_field ) {
'name' => 'meta',
'meta_fields' => function ( $block_instance, $meta_field ) {
// We should probably also check if the meta field exists but for now it's okay because
// if it doesn't, `get_post_meta()` will just return an empty string.
return get_post_meta( $block_instance->context['postId'], $meta_field, true );
},
'pattern_attributes' => function ( $block_instance, $meta_field ) {
return _wp_array_get( $block_instance->context, array( 'dynamicContent', $meta_field ), false );
},
);
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ function () {
require __DIR__ . '/block-supports/shadow.php';
require __DIR__ . '/block-supports/background.php';
require __DIR__ . '/block-supports/behaviors.php';
require __DIR__ . '/block-supports/pattern.php';

// Data views.
require_once __DIR__ . '/experimental/data-views.php';
90 changes: 58 additions & 32 deletions packages/block-editor/src/hooks/custom-fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { PanelBody, TextControl } from '@wordpress/components';
import { PanelBody, TextControl, SelectControl } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { hasBlockSupport } from '@wordpress/blocks';
import { createHigherOrderComponent } from '@wordpress/compose';
Expand Down Expand Up @@ -47,45 +47,71 @@ function CustomFieldsControl( props ) {
if ( props.name === 'core/paragraph' ) attributeName = 'content';
if ( props.name === 'core/image' ) attributeName = 'url';

const connectionSource =
props.attributes?.connections?.attributes?.[ attributeName ]?.source ||
'';
const connectionValue =
props.attributes?.connections?.attributes?.[ attributeName ]?.value ||
'';

function updateConnections( source, value ) {
if ( value === '' ) {
props.setAttributes( {
connections: undefined,
placeholder: undefined,
} );
} else {
props.setAttributes( {
connections: {
attributes: {
// The attributeName will be either `content` or `url`.
[ attributeName ]: {
// Source will be variable, could be post_meta, user_meta, term_meta, etc.
// Could even be a custom source like a social media attribute.
source,
value,
},
},
},
placeholder: sprintf(
'This content will be replaced on the frontend by the value of "%s" custom field.',
value
),
} );
}
}

return (
<InspectorControls>
<PanelBody title={ __( 'Connections' ) } initialOpen={ true }>
<SelectControl
label={ __( 'Source' ) }
value={ connectionSource }
options={ [
{
label: __( 'None' ),
value: '',
},
{
label: __( 'Meta fields' ),
value: 'meta_fields',
},
{
label: __( 'Pattern attributes' ),
value: 'pattern_attributes',
},
] }
onChange={ ( nextSource ) => {
updateConnections( nextSource, connectionValue );
} }
/>
<TextControl
__nextHasNoMarginBottom
autoComplete="off"
label={ __( 'Custom field meta_key' ) }
value={
props.attributes?.connections?.attributes?.[
attributeName
]?.value || ''
}
value={ connectionValue }
onChange={ ( nextValue ) => {
if ( nextValue === '' ) {
props.setAttributes( {
connections: undefined,
[ attributeName ]: undefined,
placeholder: undefined,
} );
} else {
props.setAttributes( {
connections: {
attributes: {
// The attributeName will be either `content` or `url`.
[ attributeName ]: {
// Source will be variable, could be post_meta, user_meta, term_meta, etc.
// Could even be a custom source like a social media attribute.
source: 'meta_fields',
value: nextValue,
},
},
},
[ attributeName ]: undefined,
placeholder: sprintf(
'This content will be replaced on the frontend by the value of "%s" custom field.',
nextValue
),
} );
}
updateConnections( connectionSource, nextValue );
} }
/>
</PanelBody>
Expand Down
8 changes: 8 additions & 0 deletions packages/block-editor/src/store/private-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,11 @@ export function deleteStyleOverride( id ) {
id,
};
}

export function syncDerivedBlockAttributes( clientId, attributes ) {
return {
type: 'SYNC_DERIVED_BLOCK_ATTRIBUTES',
clientIds: [ clientId ],
attributes,
};
}
8 changes: 8 additions & 0 deletions packages/block-editor/src/store/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ const withBlockTree =
false
);
break;
case 'SYNC_DERIVED_BLOCK_ATTRIBUTES':
case 'UPDATE_BLOCK_ATTRIBUTES': {
newState.tree = new Map( newState.tree );
action.clientIds.forEach( ( clientId ) => {
Expand Down Expand Up @@ -456,6 +457,12 @@ function withPersistentBlockChange( reducer ) {
return ( state, action ) => {
let nextState = reducer( state, action );

if ( action.type === 'SYNC_DERIVED_BLOCK_ATTRIBUTES' ) {
return nextState.isPersistentChange
? { ...nextState, isPersistentChange: false }
: nextState;
}

const isExplicitPersistentChange =
action.type === 'MARK_LAST_CHANGE_AS_PERSISTENT' ||
markNextChangeAsNotPersistent;
Expand Down Expand Up @@ -860,6 +867,7 @@ export const blocks = pipe(
return newState;
}

case 'SYNC_DERIVED_BLOCK_ATTRIBUTES':
case 'UPDATE_BLOCK_ATTRIBUTES': {
// Avoid a state change if none of the block IDs are known.
if ( action.clientIds.every( ( id ) => ! state.get( id ) ) ) {
Expand Down
Loading

0 comments on commit dc91763

Please sign in to comment.