Skip to content

Commit

Permalink
Experiment/add custom connections inspector control (#53241)
Browse files Browse the repository at this point in the history
* Add custom fields experimental setting

* Add connections experimental setting, block inspector control and block attributes

* Updated the 'connections' property to include 'attributes'

* Add `attributes` to TextControl value

* Update comment

* Clear the paragraph if meta value is cleared

* Use placeholders instead of content

* Rephrase the placeholder comment

* Check if current block is a paragraph or image

* Abstract the attribute name to use for the connection

* rename `connections` to `__experimentalConnections`

* Do not export `addAttribute()` or `withInspectorControl()`

* Renamed '__experimentalConnections' to 'connections' in block settings

---------

Co-authored-by: Michal Czaplinski <mmczaplinski@gmail.com>
  • Loading branch information
cbravobernal and michalczaplinski committed Aug 9, 2023
1 parent d89254a commit 621b21b
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/experimental/editor-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ function gutenberg_enable_experiments() {
wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableGroupGridVariation = true', 'before' );
}

if ( $gutenberg_experiments && array_key_exists( 'gutenberg-connections', $gutenberg_experiments ) ) {
wp_add_inline_script( 'wp-block-editor', 'window.__experimentalConnections = true', 'before' );
}

if ( gutenberg_is_experiment_enabled( 'gutenberg-no-tinymce' ) ) {
wp_add_inline_script( 'wp-block-library', 'window.__experimentalDisableTinymce = true', 'before' );
}
Expand Down
12 changes: 12 additions & 0 deletions lib/experiments-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ function gutenberg_initialize_experiments_settings() {
)
);

add_settings_field(
'gutenberg-custom-fields',
__( 'Connections', 'gutenberg' ),
'gutenberg_display_experiment_field',
'gutenberg-experiments',
'gutenberg_experiments_section',
array(
'label' => __( 'Test Connections', 'gutenberg' ),
'id' => 'gutenberg-connections',
)
);

register_setting(
'gutenberg-experiments',
'gutenberg-experiments'
Expand Down
139 changes: 139 additions & 0 deletions packages/block-editor/src/hooks/custom-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { PanelBody, TextControl } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { hasBlockSupport } from '@wordpress/blocks';
import { createHigherOrderComponent } from '@wordpress/compose';

/**
* Internal dependencies
*/
import { InspectorControls } from '../components';
import { useBlockEditingMode } from '../components/block-editing-mode';

/**
* Filters registered block settings, extending attributes to include `connections`.
*
* @param {Object} settings Original block settings.
*
* @return {Object} Filtered block settings.
*/
function addAttribute( settings ) {
if ( hasBlockSupport( settings, '__experimentalConnections', true ) ) {
// Gracefully handle if settings.attributes.connections is undefined.
settings.attributes = {
...settings.attributes,
connections: {
type: 'object',
},
};
}

return settings;
}

/**
* Override the default edit UI to include a new block inspector control for
* assigning a connection to blocks that has support for connections.
* Currently, only the `core/paragraph` block is supported and there is only a relation
* between paragraph content and a custom field.
*
* @param {WPComponent} BlockEdit Original component.
*
* @return {WPComponent} Wrapped component.
*/
const withInspectorControl = createHigherOrderComponent( ( BlockEdit ) => {
return ( props ) => {
const blockEditingMode = useBlockEditingMode();
const hasCustomFieldsSupport = hasBlockSupport(
props.name,
'__experimentalConnections',
false
);

// Check if the current block is a paragraph or image block.
// Currently, only these two blocks are supported.
if ( ! [ 'core/paragraph', 'core/image' ].includes( props.name ) ) {
return <BlockEdit { ...props } />;
}

// If the block is a paragraph or image block, we need to know which
// attribute to use for the connection. Only the `content` attribute
// of the paragraph block and the `url` attribute of the image block are supported.
let attributeName;
if ( props.name === 'core/paragraph' ) attributeName = 'content';
if ( props.name === 'core/image' ) attributeName = 'url';

if ( hasCustomFieldsSupport && props.isSelected ) {
return (
<>
<BlockEdit { ...props } />
{ blockEditingMode === 'default' && (
<InspectorControls>
<PanelBody
title={ __( 'Connections' ) }
initialOpen={ true }
>
<TextControl
__nextHasNoMarginBottom
autoComplete="off"
label={ __( 'Custom field meta_key' ) }
value={
props.attributes?.connections
?.attributes?.[ attributeName ]
?.value || ''
}
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
),
} );
}
} }
/>
</PanelBody>
</InspectorControls>
) }
</>
);
}

return <BlockEdit { ...props } />;
};
}, 'withInspectorControl' );

if ( window.__experimentalConnections ) {
addFilter(
'blocks.registerBlockType',
'core/connections/attribute',
addAttribute
);
addFilter(
'editor.BlockEdit',
'core/connections/with-inspector-control',
withInspectorControl
);
}
1 change: 1 addition & 0 deletions packages/block-editor/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import './content-lock-ui';
import './metadata';
import './metadata-name';
import './behaviors';
import './custom-fields';

export { useCustomSides } from './dimensions';
export { useLayoutClasses, useLayoutStyles } from './layout';
Expand Down
1 change: 1 addition & 0 deletions packages/block-library/src/paragraph/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"text": true
}
},
"__experimentalConnections": true,
"spacing": {
"margin": true,
"padding": true,
Expand Down

0 comments on commit 621b21b

Please sign in to comment.