Make WordPress Core

Opened 20 months ago

Closed 18 months ago

Last modified 2 weeks ago

#45451 closed enhancement (fixed)

Filter to allow plugins override block attributes

Reported by: kkarpieszuk Owned by: pento
Milestone: 5.1 Priority: normal
Severity: normal Version: 5.0
Component: Editor Keywords: has-patch
Focuses: Cc:


## Description

Add a filter so plugins and themes can override block attributes.

Originally I submitted it as MR to Gutenberg here https://github.com/WordPress/gutenberg/pull/11730 but I have been asked to move it directly to WordPress repo.

## Why is this needed?

Dynamic blocks, rendered server side keep their values in block attributes. Some of those attributes might be texts printed in the front-end to be read by people. This kind of strings should be available for translation.

We are preparing in WPML code to make it translatable, but we need to hook somewhere in Gutenberg to filter values. This place seems to be most appropriate for this.

## How has this been tested?

This has been tested in WPML with following code example (to translate dynamic strings created with ACF Blocks beta).

add_filter( 'block_prepared_attributes', 'block_attributes_filter', 1, 10 );
function block_attributes_filter( $attributes, $block_type ) {
    if ( $block_type->name === 'my-plugin/my-block' &&  isset( $attributes['data'] ) ) {
            $original_post_id = apply_filters( 'wpml_object_id', get_the_ID(), get_post_type(), true, apply_filters( 'wpml_default_language', null) );
            foreach ( $attributes['data'] as $name => $value ) {
                $string_name = WPML_Gutenberg_Strings_In_Block::get_string_id($attributes['name'], $value);
                $translated = apply_filters( 'wpml_translate_string',
                    array('kind' => 'Gutenberg', 'name' => $original_post_id) );
                $attributes['data'][$name] = $translated;

        return $attributes;

## Types of changes

Add a new filter

## Checklist:

Attachments (2)

patch.diff (650 bytes) - added by kkarpieszuk 20 months ago.
proposed patch
45451.diff (1.1 KB) - added by pento 18 months ago.

Download all attachments as: .zip

Change History (21)

20 months ago

proposed patch

#1 @swissspidy
20 months ago

  • Keywords has-patch added
  • Milestone changed from Awaiting Review to 5.0.1

#2 @SergeyBiryukov
19 months ago

  • Component changed from General to Editor

#3 @pento
19 months ago

  • Milestone changed from 5.0.1 to 5.0.2

#4 @pento
19 months ago

  • Milestone changed from 5.0.2 to 5.0.3

#5 @kkarpieszuk
19 months ago

@swissspidy I see it is postponed again. While I understand why it was removed from the queue for 5.0.1, now I am starting to worry if it would be introduced ever :(

Bear in mind because of the lack of this filter WPML is still incompatible with WP 5.0. This is very bad for our business not to mention our users :(

#6 @swissspidy
19 months ago

@kkarpieszuk 5.0.2 is intended for bug fixes to 5.0 only, not necessarily new enhancements (which this filter basically is). I understand your frustration and I am sure we can get this filter added soon.

#7 @kkarpieszuk
19 months ago

I hope it will be soon :) Actions and filters is "WordPress blood" and it should be added a long time before 5.0. Waiting for it now, just... you know.

#8 @desrosj
18 months ago

  • Milestone changed from 5.0.3 to 5.1

New filters are not being added in 5.0.3. So going to punt this one more time.

@kkarpieszuk one nit, the $block_type description feels a little awkward. Not sure of a good alternative yet. The since needs to be changed to 5.1.0, but the person committing this can change that.

18 months ago

#9 @pento
18 months ago

Thank you for the patch, @kkarpieszuk!

I've been thinking about this some more, it seems like it would be more useful to filter a little higher, in render_block(). This will allow filtering static blocks, as well as block types that aren't registered.

#10 @desrosj
18 months ago

  • Keywords commit added

45451.diff looks good. There is an extra empty line at the end of the addition that needs to just be removed.

#11 @pento
18 months ago

  • Owner set to pento
  • Resolution set to fixed
  • Status changed from new to closed

In 44553:

Blocks: Add the pre_render_block and render_block_data filters.

At the start of render_block(), the pre_render_block filter allows the function to be short-circuited, and the render_block_data filter is applied to the $block parameter before it's processed.

Props kkarpieszuk, pento.
Fixes #45451.

#12 @pento
18 months ago

In 44555:

Blocks: Reverse the logic when checking the pre_render_block result.

We should be returning if the result isn't null, not when it is.

See #45451.

#13 @kkarpieszuk
18 months ago

@pento I agree with your idea for better placing the filter (earlier). If you need anything from me, please ask :)

#14 @dmsnell
18 months ago

I'm going to post this link to the PR in the plugin that I created some time ago to address this.


I was using the pre_ filter to perform short-circuiting and adjust the block attributes but I can see where two would be helpful. In my reasoning there was a symmetry to the pre_ and post_ filters which expressed itself as "the filter which affects how a block is rendered" and "the filter which affects what was rendered in a block."

$block = apply_filters( 'render_block_data', $block );

In the above filter definition I wonder if anyone else considered adding the $source_block. I anticipate that block-transformation will be a common way that people write plugins: for example, pulling out a child block based on an attribute such as locale for translations or es5/es2015/es2017 for example code blocks; alternatively in applying different steps of transformation, such as when we want to filter all text content generally but have a markdown render - transform first from markdown to html then run the transformed block through the next filter in the chain.

In these cases I seemed to remember some valid use-cases for where we'd want to or need to know what the original pre-transformed block data was, most-frequently the block name, but maybe that can be equally handled via filter priority?

Anyway, those are some thoughts from me. Thanks @kkarpieszuk for working on this issue - it's close to my heart as I am pretty sure that with a solid filter API for blocks we can eliminate the concept of dynamic blocks and the render_callback, instead meeting that need through the consistent filtering API.

#15 @pento
18 months ago

Good thinking, thanks @dmsnell. I'll add that extra parameter in.

#16 @pento
18 months ago

In 44576:

Blocks: Add a $source_block parameter to the render_block_data filter.

This contains a copy of the block, unmodified by other filter functions, so that plugins have a clean reference to work from, if they need.

Props dmsnell.
Fixes #45451.

#17 @desrosj
17 months ago

  • Keywords needs-dev-note added

This ticket was mentioned in Slack in #core-media by desrosj. View the logs.

15 months ago

#19 @desrosj
2 weeks ago

  • Keywords commit needs-dev-note removed

As far as I can tell, this never received a developer note. Removing the needs-dev-note keyword.

Note: See TracTickets for help on using tickets.