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

Provide a way to filter dynamic/server side render block attributes #15707

Open
thomasplevy opened this issue May 17, 2019 · 8 comments
Open
Labels
[Feature] Block API API that allows to express the block paradigm. [Feature] Extensibility The ability to extend blocks or the editing experience [Type] Enhancement A suggestion for improvement.

Comments

@thomasplevy
Copy link
Contributor

Is your feature request related to a problem? Please describe.

I've been following along on #11730 and while this does provide a way to modify existing attributes it does not provide a way for plugins to register custom attributes.

Use case: We'd like to be able to conditionally display a block on the frontend based on whether or not there is a logged in user. EG: Show this paragraph to logged in users and show this other paragraph to logged out users.

My plugin currently registers custom attributes on blocks (like the paragraph block) via JS filters blocks.registerBlockType

However, with a dynamic block (like core/archives) while I can filter to add custom attributes to the block via Javascript I cannot save them since they are validated via unfilterable rest api methods.

I can add the attributes via the render_block_data filter but these attributes are then validated by WP_Block_Type->prepare_attributes_for_render(). Since it's impossible to filter the $attributes property on the WP_Block_Type class it's impossible to save these custom attributes via the block editor.

Describe the solution you'd like
Add a PHP filter which would allow custom attributes to be registered for dynamic blocks

Describe alternatives you've considered
The solution I've come up with is to simply not filter dynamic blocks but even this is kind of ugly since it's impossible (as far as I've been able to tell) to know in JS if a block is dynamic or otherwise when via the blocks.registerBlockType filter. So I've resorted to pulling a list of dynamic blocks and outputting it as a window variable as an array that I can access in Javascript so I can conditionally not render custom attributes on dynamic blocks. It doesn't feel right.

I also considered (but didn't pursue due to similar ugliness) pulling all dynamic blocks from the main block registry and, storing their registration data (temporarily) unregistering them and then reregistering them after adding my custom attributes. This feels really bad and maybe wouldn't even work (I didn't try it).

If this feels like something that could be included I'm happy to submit a PR but I didn't want to spend time writing it until I open the discussion. I'm feeling like there may be a good reason why this has not already been included but I haven't been able to track it down via google searches and reading through the related discussions here and on trac.

Thanks

@swissspidy swissspidy added [Feature] Block API API that allows to express the block paradigm. Needs Technical Feedback Needs testing from a developer perspective. labels May 17, 2019
@youknowriad
Copy link
Contributor

Use case: We'd like to be able to conditionally display a block on the frontend based on whether or not there is a logged in user. EG: Show this paragraph to logged in users and show this other paragraph to logged out users.

did you try the https://developer.wordpress.org/reference/hooks/render_block/ filter. It feels like it can address the use-case you mention here.

@youknowriad youknowriad added [Status] Needs More Info Follow-up required in order to be actionable. and removed Needs Technical Feedback Needs testing from a developer perspective. labels May 21, 2019
@thomasplevy
Copy link
Contributor Author

thomasplevy commented May 21, 2019

@youknowriad,

This absolutely works for determining whether or not to render the block on the frontend but the issue I'm encountering arises before we get here.

I am attempting to create a custom block attribute which will allow a content creator to choose the settings from within the editor. I can very easily do this for a static block (like a paragraph) but I cannot do this for a static dynamic block (like the archives) because the attribute cannot be validated properly because it cannot be rendered registered.

So the issue is not that I am unable to actually hide the block via the render_block filter, it's that there is no place for me to register custom attributes in PHP which, again, only really matters for dynamic blocks.

Edit: I used the wrong words and corrected the words

@youknowriad
Copy link
Contributor

Makes sense @thomasplevy I'm thinking the work being done in the Block Registration API will ultimately solve this.

@youknowriad youknowriad added [Feature] Extensibility The ability to extend blocks or the editing experience and removed [Status] Needs More Info Follow-up required in order to be actionable. labels May 21, 2019
@strarsis
Copy link
Contributor

strarsis commented Mar 8, 2020

render_block_data is basically useless in its current state because it is not possible to actually filter the attributes of a block.

This example should add the class test to all blocks:

function gutenberg_block_test($block) {
    $block['attrs']['className'] .= ' ' . 'test';
    return $block;
}
add_filter( 'render_block_data', 'gutenberg_block_test' );

However, nothing happens at all, the filter can't change the classes...

@thomasplevy
Copy link
Contributor Author

@youknowriad I know it's been quite a while on this but I just noticed that you added a "Need more info" label -- is there any additional information I could provide?

@youknowriad
Copy link
Contributor

I also added and removed that label a long time ago :) so no need for new information.

That said, thinking here I believe you can register block server side by using the same name if they are not registered already or by unregistering them, altering their attributes and register them again to add new attributes on the server.

@leeshadle
Copy link

leeshadle commented Sep 9, 2020

@thomasplevy I just ran into a similar issue, trying to add custom attributes to php rendered blocks.

I took a peak at @phpbits editorskit plugin and it looks like he found a solution by hijacking the rest api call using the rest_pre_dispatch hook:
https://developer.wordpress.org/reference/hooks/rest_pre_dispatch/

And then unsetting the custom attribute(s). Works like a charm...

@RavishaHeshanE25
Copy link

If someone runs into this issue in the future this can be achieved with

function add_extra_attributes_to_registered_block()
{
	$block = WP_Block_Type_Registry::get_instance()
		->get_registered('<block_name>');
	if ($block) {
		$additional_attributes = [
			...
		];
		$block->attributes
			= array_merge($block->attributes, $additional_attributes);
	}
}
add_action( 'wp_loaded', 'add_extra_attributes_to_registered_block');

@jordesign jordesign added the [Type] Enhancement A suggestion for improvement. label Aug 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Block API API that allows to express the block paradigm. [Feature] Extensibility The ability to extend blocks or the editing experience [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests

7 participants