Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Bindings: Add context needed by block bindings sources during its processing #6456

Open
wants to merge 7 commits into
base: trunk
Choose a base branch
from

Conversation

SantosGuillamot
Copy link

What?

Block bindings sources sometimes need to access some context that is not initially available in the block. Right now, we are extending it when the source is registered. This pull request moves the logic so it is added when the block bindings are processed. This means:

  • Before: Extend context during block bindings source registration. This implies that the blocks extend the context even when they don't use bindings.
  • After: Extend context during block bindings processing. This implies that the context is extended ONLY for the blocks where bindings are defined.

How?

Instead of using the get_block_type_uses_context created back then for this use case, use the available_context in the block class during bindings processing.

I assume it is not possible to remove that filter because of backward-compatibility.

Testing instructions

  1. Register a custom field in your site to test it. You can use a code snippet like this:
register_meta(
	'post',
	'url_custom_field',
	array(
		'show_in_rest' => true,
		'single'       => true,
		'type'         => 'string',
		'default'	   => 'https://wpmovies.dev/wp-content/uploads/2023/04/goncharov-poster-original-1-682x1024.jpeg',
	)
);
  1. Go to a page and insert an image block.
  2. Go to the Code editor and connect the image to the custom field by adding the metadata bindings property. It should look something like this:
<!-- wp:image {"id":134,"sizeSlug":"large","linkDestination":"none","metadata":{"bindings":{"url":{"source":"core/post-meta","args":{"key":"url_custom_field"}},"alt":{"source":"core/post-meta","args":{"key":"text_custom_field"}}}}} -->
<figure class="wp-block-image size-large"><img src="https://wpmovies.dev/wp-content/uploads/2023/04/goncharov-poster-original-1-682x1024.jpeg" alt="Alt content" class="wp-image-134"/></figure>
<!-- /wp:image -->
  1. Save the page and check that in the frontend, the URL defined in the custom field is used.
  2. Repeat the process for paragraph, heading, and button blocks.
Copy link

github-actions bot commented Apr 29, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props santosguillamot, gziolo.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

Copy link

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • The Plugin and Theme Directories cannot be accessed within Playground.
  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks very promising.

@@ -265,6 +265,15 @@ private function process_block_bindings() {
continue;
}

// Add the necessary context defined by the source.
if ( ! empty( $block_binding_source->uses_context ) ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't occur to me that we could inject the context just as we are about to compute it. Great idea!

I think the fact that we have a formal block binding source instance helps a ton here.

@SantosGuillamot SantosGuillamot marked this pull request as ready for review May 1, 2024 07:40
Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need to provide an alternative way to expose the uses_context defined for the block binding sources to the client. Previously it was handled through the block type definitions exposed on the server. In the revised approach, that information is only available on the server, so that might have some implications on how existing block binding sources work in the editor.

/**
* Tests passing `uses_context` as argument to the source.
*
* @ticket 99999
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to change before committing.

'sourceTwoContext' => 'source two context value',
)
);
$second_block_render = $second_block->render();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's enough to test a single block with the current implementation.

Copy link
Author

@SantosGuillamot SantosGuillamot Jul 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that it feels repetitive. I've removed the "multiple sources" test and just rely on the one testing uses_context: link.

I changed it for another test to ensure that the second source can't access the context defined by the first one. I check and it fails with the previous implementation.

Let me know what you think.

@SantosGuillamot
Copy link
Author

I've been looking at exposing the uses_context to the client, and I pushed some changes to expose it through editor settings: link. That way it could be consumed by the client with getEditorSettings as explained here.

Is it okay to use editor settings for that? Any other alternative?

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some comments related to the idea to expose setting for block bindings together with the editor settings.

Is it okay to use editor settings for that? Any other alternative?

We are using the same approach for many editor features so that should be acceptable approach.

@@ -129,3 +129,6 @@ function get_all_registered_block_bindings_sources() {
function get_block_bindings_source( string $source_name ) {
return WP_Block_Bindings_Registry::get_instance()->get_registered( $source_name );
}

// Add the `uses_context` to the block editor settings to ensure it can be consumed in the client.
add_filter( 'block_editor_settings_all', array( 'WP_Block_Bindings_Registry', 'add_uses_context_to_editor_settings' ), 10 );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved to one of the existing functions that applies the filter. Adding filters is for plugins and themes when they don't have access to internals of WordPress.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it to the place where (I believe) the editor settings are initialized: link.

$registered_block_bindings_sources = get_all_registered_block_bindings_sources();
foreach ( $registered_block_bindings_sources as $source ) {
if ( ! empty( $source->uses_context ) ) {
$settings['__experimentalBlockBindings'][ $source->name ]['usesContext'] = $source->uses_context;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In PHP you need to initialize all the arrays at any level.

Should we also pass the label to the client?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the way arrays are initialized and I added the label as well here.

@SantosGuillamot SantosGuillamot force-pushed the update/add-available-context-in-bindings-processing branch from 18c83aa to 6f0a931 Compare July 3, 2024 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants