Opened 2 months ago
Last modified 8 weeks ago
#62705 new feature request
Block Bindings: Expose UI options for the source from the server
Reported by: |
|
Owned by: | |
---|---|---|---|
Milestone: | 6.8 | Priority: | normal |
Severity: | normal | Version: | 6.5 |
Component: | Editor | Keywords: | has-patch |
Focuses: | Cc: |
Description (last modified by )
This ticket was mentioned in PR #7987 on WordPress/wordpress-develop by @cbravobernal.
Trac ticket: https://core.trac.wordpress.org/ticket/62705
## What?
I'm experimenting if it is possible to add sources to the UI just by defining them on the server side. It will need a PR in Gutenberg to be landed.
This registration:
register_block_bindings_source(
'bbe/now-date',
array(
'label' => __( 'Current date', 'custom-bindings' ),
'get_value_callback' => function ( array $source_args, $block_instance ) {
return gmdate( $source_args['key'] );
},
'fields' =>
array(
'Y-m-d H:i:s' => array(
'type' => 'string',
'value' => 'Y-m-d H:i:s',
),
'D' => array(
'type' => 'string',
'value' => 'D',
),
),
)
);
will return:
We are using keys as the source arguments to decide the format. It's an approach I'm not 100% comfortable with. We may need to update the JS API.
Change History (5)
@cbravobernal commented on PR #7987:
2 months ago
#3
#4
@
8 weeks ago
- Component changed from General to Editor
- Milestone changed from Awaiting Review to 6.8
- Summary changed from Block Bindings: Try fields registration on server. to Block Bindings: Expose UI options for the source from the server
- Type changed from enhancement to feature request
- Version set to 6.5
Based on the existing prototypes, I would like to better understand what information does the UI need to present all options defined on the server and set the args
in the block attribute's metadata?
To start with an example included in the ticket, the key
used in the source seems introduce a layer of indirection. In theory the only thing that the source might need to display on the frontend is the format of the data:
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"bbe/now-date","args":{"format":"D"}}}}} --> <p></p> <!-- /wp:paragraph -->
In effect, when the option gets selected from the Attributes UI in the sidebar, then the "args" need to get saved for the block. Ideally, that information is already provided from the server:
<?php $source_ui_option_day = array( 'args' => array( 'format' => 'D', ), );
Next, we need a label to present the option in the UI:
<?php $source_ui_option_day = array( 'label' => __( 'Day of the week', 'bbe' ), 'args' => array( 'format' => 'D', ), );
The type is used in the UI to filter the options based on the matching type defined for the attributes, in effect we need to provide it, too. Could we assume the default is string
?
<?php $source_ui_option_day = array( 'label' => __( 'Day of the week', 'bbe' ), 'type' => 'string', // 'datetime` in the future? 'args' => array( 'format' => 'D', ), );
The last missing element would be the preview of the data, in this case it could work pretty well:
<?php $source_ui_option_day = array( 'label' => __( 'Day of the week', 'bbe' ), 'type' => 'string', // 'datetime` in the future? 'value' => gmdate( 'D' ), 'args' => array( 'format' => 'D', ), );
What else the UI might need?
The last step would be the registration. Overall, we should take into account performance considerations as these UI options are only needed in the editor. There is some prior work for block variations that triggered refactoring in WordPress core to use a callback so the code is executed only when really necessary (dev note for context). Even in this example, we could avoid computations like the gmdate
function call if the source wants to use some logic:
<?php register_block_bindings_source( 'bbe/now-date', array( 'label' => __( 'Current date', 'bbe' ), 'get_value_callback' => function ( array $source_args, $block_instance ) { if ( empty( $source_args['format'] ) || 'D' !== $source_args['format'] ) { return ''; } return gmdate( $source_args['format'] ); }, 'ui_options_callback' => function() { return array( array( 'label' => __( 'Day of the week', 'bbe' ), 'type' => 'string', // 'datetime` in the future? 'value' => gmdate( 'D' ), 'args' => array( 'format' => 'D', ), ) ); } ) );
All the nomenclature is up for debate. I wanted to share my current understanding of how it could work so there is an universal way for all sources to integrate into the existing Attributes panel in the block editor's sidbear.
#5
@
8 weeks ago
What I've seen in most of approaches of Block Bindings is that ´$source_argskey?´ is the variable guiding the frontend rendered content.
In post meta, the list is showing all the different values that ´key´ may have. And interacting with them within the UI will set that ´key´ value. Taking that into account, an example of what the user may need with dates could be this one:
array( 'label' => __( 'Current dates', 'custom-bindings' ), 'get_value_callback' => function ( array $source_args, $block_instance ) { switch ( $source_args['key'] ) { case 'y_m_d': return gmdate( 'Y M D' ); case 'y_m_d_h_i_s': return gmdate( 'Y M D h i s' ); default: return gmdate( 'Y M D h i s' ); } }, 'args' => array( 'y_m_d' => array( 'type' => 'string', 'label' => __( 'Y M D', 'custom-bindings' ), 'value' => gmdate( 'Y M D' ), ), 'y_m_d_h_i_s' => array( 'type' => 'string', 'label' => __( 'Y M D h i s', 'custom-bindings' ), 'value' => gmdate( 'Y M D h i s' ), ), ), ),
I think we should define what we want on that UI, should we instead choose between different ´args´? Should we just focus on allowing defining just args
keys?
In the last case, ´label´ would show the format, and value would show an example of what will be rendered on the frontend.
Could we assume the default is string?
I think we could assume it. In a future, as you mention, could accept number, bool, dateformat, etc.
I agree with all the requirements you mention. I think the debate should be if we want to allow setting different args via the UI, or we just want to focus on the arg
key value. If we want to set different args, we may need to update the internals of post meta right now.
What I don't like of this approach is that only the key is needed to render the frontend. The value could be anything, and that anything would be shown on the frontend if you don't tweak it with
getValues
on the editor. Something like:register_block_bindings_source( 'bbe/now-date', array( 'label' => __( 'Current date', 'custom-bindings' ), 'get_value_callback' => function ( array $source_args, $block_instance ) { return gmdate( $source_args['key'] ); }, 'fields' => array( 'Y-m-d H:i:s' => array( 'type' => 'string', 'value' => 'i don\'t use it', ), 'D' => array( 'type' => 'string', 'value' => 'i don\'t use it', ), ), ) );
Would still render this on the editor:
And this would be the UI:
