Skip to content

Commit

Permalink
Automatically assign block ids
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Nov 24, 2023
1 parent dc91763 commit c547ad3
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 89 deletions.
26 changes: 17 additions & 9 deletions lib/experimental/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,25 @@ function gutenberg_render_block_connections( $block_content, $block, $block_inst
continue;
}

// If the attribute does not specify the name of the custom field, skip it.
if ( ! isset( $attribute_value['value'] ) ) {
continue;
if ( 'pattern_attributes' === $attribute_value['source'] ) {
if ( ! _wp_array_get( $block_instance->attributes, array( 'metadata', 'id' ), false ) ) {
continue;
}

$custom_value = $connection_sources[ $attribute_value['source'] ]( $block_instance );
} else {
// If the attribute does not specify the name of the custom field, skip it.
if ( ! isset( $attribute_value['value'] ) ) {
continue;
}

// Get the content from the connection source.
$custom_value = $connection_sources[ $attribute_value['source'] ](
$block_instance,
$attribute_value['value']
);
}

// Get the content from the connection source.
$custom_value = $connection_sources[ $attribute_value['source'] ](
$block_instance,
$attribute_value['value']
);

if ( false === $custom_value ) {
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/experimental/connection-sources/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// 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 );
'pattern_attributes' => function ( $block_instance ) {
return _wp_array_get( $block_instance->context, array( 'dynamicContent', $block_instance->attributes['metadata']['id'] ), false );
},
);
30 changes: 28 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 32 additions & 58 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, SelectControl } from '@wordpress/components';
import { PanelBody, TextControl } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { hasBlockSupport } from '@wordpress/blocks';
import { createHigherOrderComponent } from '@wordpress/compose';
Expand Down Expand Up @@ -47,71 +47,45 @@ 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={ connectionValue }
value={
props.attributes?.connections?.attributes?.[
attributeName
]?.value || ''
}
onChange={ ( nextValue ) => {
updateConnections( connectionSource, 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
),
} );
}
} }
/>
</PanelBody>
Expand Down
36 changes: 19 additions & 17 deletions packages/block-library/src/block/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,11 @@ function isPartiallySynced( block ) {
);
}
function getPartiallySyncedAttributes( block ) {
const attributes = {};
for ( const [ attribute, connection ] of Object.entries(
block.attributes.connections.attributes
) ) {
if ( connection.source !== 'pattern_attributes' ) continue;
attributes[ attribute ] = connection.value;
}
return attributes;
return Object.entries( block.attributes.connections.attributes )
.filter(
( [ , connection ] ) => connection.source === 'pattern_attributes'
)
.map( ( [ attributeKey ] ) => attributeKey );
}

const fullAlignments = [ 'full', 'wide', 'left', 'right' ];
Expand Down Expand Up @@ -98,13 +95,15 @@ function applyInitialDynamicContent(
dynamicContent,
defaultValues
);
if ( ! isPartiallySynced( block ) ) return { ...block, innerBlocks };
const blockId = block.attributes.metadata?.id;
if ( ! isPartiallySynced( block ) || ! blockId )
return { ...block, innerBlocks };
const attributes = getPartiallySyncedAttributes( block );
const newAttributes = { ...block.attributes };
for ( const [ attributeKey, id ] of Object.entries( attributes ) ) {
defaultValues[ id ] = block.attributes[ attributeKey ];
if ( dynamicContent[ id ] ) {
newAttributes[ attributeKey ] = dynamicContent[ id ];
for ( const attributeKey of attributes ) {
defaultValues[ blockId ] = block.attributes[ attributeKey ];
if ( dynamicContent[ blockId ] ) {
newAttributes[ attributeKey ] = dynamicContent[ blockId ];
}
}
return {
Expand All @@ -123,11 +122,14 @@ function getDynamicContentFromBlocks( blocks, defaultValues ) {
dynamicContent,
getDynamicContentFromBlocks( block.innerBlocks, defaultValues )
);
if ( ! isPartiallySynced( block ) ) continue;
const blockId = block.attributes.metadata?.id;
if ( ! isPartiallySynced( block ) || ! blockId ) continue;
const attributes = getPartiallySyncedAttributes( block );
for ( const [ attributeKey, id ] of Object.entries( attributes ) ) {
if ( block.attributes[ attributeKey ] !== defaultValues[ id ] ) {
dynamicContent[ id ] = block.attributes[ attributeKey ];
for ( const attributeKey of attributes ) {
if (
block.attributes[ attributeKey ] !== defaultValues[ blockId ]
) {
dynamicContent[ blockId ] = block.attributes[ attributeKey ];
}
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/edit-site/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ import './components';
import './push-changes-to-global-styles';
import './template-part-edit';
import './navigation-menu-edit';
import './pattern-partial-syncing';
69 changes: 69 additions & 0 deletions packages/edit-site/src/hooks/pattern-partial-syncing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { privateApis } from '@wordpress/patterns';
import { createHigherOrderComponent } from '@wordpress/compose';
import { useBlockEditingMode } from '@wordpress/block-editor';
import { hasBlockSupport } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { store as editSiteStore } from '../store';
import { unlock } from '../lock-unlock';

const { PartialSyncingControls, PATTERN_TYPES } = unlock( privateApis );

/**
* Override the default edit UI to include a new block inspector control for
* assigning a partial syncing controls to supported blocks in the pattern editor.
* Currently, only the `core/paragraph` block is supported.
*
* @param {Component} BlockEdit Original component.
*
* @return {Component} Wrapped component.
*/
const withPartialSyncingControls = createHigherOrderComponent(
( BlockEdit ) => ( props ) => {
const blockEditingMode = useBlockEditingMode();
const hasCustomFieldsSupport = hasBlockSupport(
props.name,
'__experimentalConnections',
false
);
const isEditingPattern = useSelect(
( select ) =>
select( editSiteStore ).getEditedPostType() ===
PATTERN_TYPES.user,
[]
);

// Check if editing a pattern and the current block is a paragraph block.
// Currently, only the paragraph block is supported.
const shouldShowPartialSyncingControls =
hasCustomFieldsSupport &&
props.isSelected &&
isEditingPattern &&
blockEditingMode === 'default' &&
[ 'core/paragraph' ].includes( props.name );

return (
<>
<BlockEdit { ...props } />
{ shouldShowPartialSyncingControls && (
<PartialSyncingControls { ...props } />
) }
</>
);
}
);

if ( window.__experimentalConnections ) {
addFilter(
'editor.BlockEdit',
'core/edit-site/with-partial-syncing-controls',
withPartialSyncingControls
);
}
3 changes: 2 additions & 1 deletion packages/patterns/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"@wordpress/icons": "file:../icons",
"@wordpress/notices": "file:../notices",
"@wordpress/private-apis": "file:../private-apis",
"@wordpress/url": "file:../url"
"@wordpress/url": "file:../url",
"nanoid": "^4.0.2"
},
"peerDependencies": {
"react": "^18.0.0",
Expand Down
Loading

0 comments on commit c547ad3

Please sign in to comment.