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 block uses_context defined by block bindings sources #6079

Conversation

SantosGuillamot
Copy link

@SantosGuillamot SantosGuillamot commented Feb 9, 2024

This pull request adds some logic to add the necessary uses_context defined by block bindings sources. Each source defines the context it needs and it is added to the blocks that are using the block bindings API.

Apart from that, it adapts the post meta and pattern overrides sources for this change.

Finally, it removes the pattern/overrides from the block.json because it is handled this way now.

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',
	)
);

Post meta source test

  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.

Pattern overrides test

  1. Go to Site Editor -> Patterns -> New pattern.
  2. Create a synced pattern and give it a name.
  3. Add a paragraph with a default value and, in the advanced panel, enable the "Allow instance overrides" setting.
  4. Repeat the process with a heading, an image, and a button.
  5. Go to a page and insert the pattern created.
  6. Modify the value of the blocks and save the page.
  7. Go to the frontend and check that the modified values are used.

Trac ticket: https://core.trac.wordpress.org/ticket/60525


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

Copy link

github-actions bot commented Feb 9, 2024

Hi @SantosGuillamot! 👋

Thank you for your contribution to WordPress! 💖

It looks like this is your first pull request to wordpress-develop. Here are a few things to be aware of that may help you out!

No one monitors this repository for new pull requests. Pull requests must be attached to a Trac ticket to be considered for inclusion in WordPress Core. To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description.

Pull requests are never merged on GitHub. The WordPress codebase continues to be managed through the SVN repository that this GitHub repository mirrors. Please feel free to open pull requests to work on any contribution you are making.

More information about how GitHub pull requests can be used to contribute to WordPress can be found in this blog post.

Please include automated tests. Including tests in your pull request is one way to help your patch be considered faster. To learn about WordPress' test suites, visit the Automated Testing page in the handbook.

If you have not had a chance, please review the Contribute with Code page in the WordPress Core Handbook.

The Developer Hub also documents the various coding standards that are followed:

Thank you,
The WordPress Project

Copy link

github-actions bot commented Feb 9, 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, czapla, thekt12.

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

@SantosGuillamot
Copy link
Author

I guess, according to the tests, that I shouldn't modify the block.json properties, right? Is that imported from Gutenberg somehow?

@gziolo
Copy link
Member

gziolo commented Feb 12, 2024

I guess, according to the tests, that I shouldn't modify the block.json properties, right? Is that imported from Gutenberg somehow?

That needs to happen in the Gutenberg plugin. It isn't as important, so that can be synced later during the 6.5 Beta phase as code quality improvement. You also need to plan to remove these useContext entries from the Gutenberg plugin by syncing back the PHP changes proposed in this patch.

@@ -60,6 +68,9 @@ public function __construct( string $name, array $source_properties ) {
$this->name = $name;
$this->label = $source_properties['label'];
$this->get_value_callback = $source_properties['get_value_callback'];
if ( isset( $source_properties['uses_context'] ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think that we should move this isset() check next to the other checks
in WP_Block_Bindings_Registry.

Copy link
Contributor

Choose a reason for hiding this comment

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

And let's cover it with a unit test as well
🙂. (Should be almost a copy-paste of the
existing ones)

Copy link
Author

Choose a reason for hiding this comment

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

My idea is to make the uses_context optional because some sources won't need to use it. Do you think it shouldn't be that case? It would make sense to add a check that, if it exists, it is an array though.

I'll work on unit tests as well 🙂

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it should be optional and default to null.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, that makes sense! It should be optional indeed 🙂

Copy link
Author

Choose a reason for hiding this comment

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

If I understood you correctly, I believe I prefer the second option. I made this commit to illustrate how I understood it. We can always revert it.

PD: I included unnecessary code I was using for testing, I just removed it in other commit 😅

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it's exactly how it could work 👍🏻

It would be nice to add a unit test for the registry that asserts that it errors when an unknown property is provided.


At the same time, we are closing the source object for an extension, which I'm a bit unsure about, given we might need to change during beta if we figure out it prevents iterations in the Gutenberg plugin. We also miss the following annotation on the class if we decide to go that path:

Copy link
Author

Choose a reason for hiding this comment

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

I am unsure about restricting it as well. I can expect we might want to increase it in Gutenberg after external developers create their own sources the same way we need now to include uses_context.

Copy link
Author

Choose a reason for hiding this comment

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

On the other hand, if we allow source to use their own properties, could we face backwards-compatibility issues in the future?

Imagine a source is using a custom property format. And in the future, we want to include it as part of the core properties and we use it somehow as we are doing with uses_context. The source that had a custom property with the same name wouldn't be working as expected, right?

Copy link
Member

Choose a reason for hiding this comment

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

I'll keep thinking about it as I don't have an ultimate answer for now as it's hard to tell what will be needed here.

@michalczaplinski
Copy link
Contributor

michalczaplinski commented Feb 12, 2024

Let's also make sure that we update the docstrings in:

  • register() method - link
  • register_block_bindings_source() function - link

@SantosGuillamot SantosGuillamot force-pushed the fix/add-context-defined-by-block-bindings-sources branch from c4fb33f to e41ba30 Compare February 13, 2024 11:28
@SantosGuillamot
Copy link
Author

I've created a bunch of tests to check uses_context:

  • Test that the value defined in uses_context is available for the source: link.
  • Test that using a string in uses_context fails: link.
  • Test that the result of registering a source has the correct values: link.
  • Test that multiple sources, with shared context, merge it properly: link.

@SantosGuillamot SantosGuillamot marked this pull request as ready for review February 15, 2024 10:31
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 additional feedback to consider, but it's already in good shape overall. Thank you for adding all the changes and covering the unit tests.

// Add `uses_context` defined by block bindings sources.
add_filter(
'get_block_type_uses_context',
function ( $uses_context, $block_type ) use ( $source ) {
Copy link
Member

@gziolo gziolo Feb 15, 2024

Choose a reason for hiding this comment

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

One more thing here and not a blocker. I believe we should use a class method and unregister the filter when unregistering the source. It would also help with documenting, as we could put all details from inline comments in the PHPDoc.

I'm not entirely sure how that would look in practice, but happy to explore together options. It can be another patch.

Copy link
Author

Choose a reason for hiding this comment

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

This makes sense to me. Although I don't know how it will work 🤔 I was thinking something like this:

	/**
	 * Source that is being processed.
	 *
	 * @since 6.5.0
	 * @var WP_Block_Bindings_Source|false
	 */
	private $source;

	/**
	 * Callback passed to the `get_block_type_uses_context` filter to add the source's `uses_context` to the block.
	 *
	 * @since 6.5.0
	 *
	 * @param array         $uses_context Array of registered uses context for a block type.
	 * @param WP_Block_Type $block_type   The full block type object.
	 * @return array Modified array of uses_context with the values provided by the source.
	 */
	public function _add_source_uses_context( $uses_context, $block_type ) {
		$source = $this->source;
		if ( ! in_array( $block_type->name, $this->supported_blocks, true ) || empty( $source->uses_context ) ) {
			return $uses_context;
		}
		// Use array_values to reset the array keys.
		return array_values( array_unique( array_merge( $uses_context, $source->uses_context ) ) );
	}

But we probably need a different callback name per source.

Anyway, I'll add a task in the tracking issue to handle it 🙂

@gziolo
Copy link
Member

gziolo commented Feb 16, 2024

Committed with https://core.trac.wordpress.org/changeset/57641.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants