-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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 API: Block context render_callback
not fully backward-compatible as array
#21797
Comments
render_callback
not fully backward-compatible as array
I agree with your personal preference, and we should also implement as many array related interfaces as possible.
|
Actually, if the interfaces were just for background compatibility, we can just drop all of them since now people are explicitly opting in. |
I agree with the idea of using an opt-in to WP_Block. Adding all those interfaces to WP_Block seems like it'd make the implementation unnecessarily complicated, and it'd still be hard to guarantee absolute backwards compatibility. |
Bugger! It's never as easy as it seems, is it! 🙂 I agree with @talldan. I don't think the convenience of re-using The simplest way to implement an "opt in" is to pick a new name.
This is my preference. |
I do like the idea of dropping |
I opened #21833 as an exploration to see how function reflection can solve this problem. It's quite straight-forward. In fact, the pull request removes more code than it adds. @noisysocks As to your concern about using reflection: I understand it. It does seem more "magical" than might be typical in WordPress code. I think I've generally been of the mind to optimize toward simple and obvious from the perspective of those integrating (the public API), even if the internal implementation needs to be more complex to support it. In this case, the public API difference is To the thought about changing the name, a few extra considerations:
|
I'm still worried 😀 My big concern is that, in all the PHP literature (ex, ex), type hinting is advertised as an optional feature that allows the programmer to enforce some level of type safety. I don't think that a typical PHP programmer would expect that turning a
This is a really good point but there are other non-reflection ways to ensure backwards compatibility: a third parameter to I agree that we must not ship anything that breaks backwards compatibility.
This is also a really good point but, again, there are alternative approaches that don't involve deprecating
It's certainly not more convenient to write If it were 2018 and we knew what we know now I think we would probably choose My preference is:
|
@noisysocks These are all great arguments. Reflecting on this some more, I think the way I've tried using reflection here is as a sort of function overloading in the traditional sense, which does not exist in PHP (or at least doesn't mean the same thing). I do feel more now that it's probably inappropriate to try to force this, especially when type declaration already has a purpose, which is definitely not one intended to be used in this way of changing the interpreted behavior of the function. We still need some solution by today. Right now I'm leaning toward the |
There's an interesting argument to be made here toward passing
|
Personally, I would prefer (Notably, using just the attributes would be easier in the future once WordPress raises its minimum PHP version to one that supports destructuring associative arrays.) |
I opened #21868 to introduce the global. I subsequently renamed it as |
I think that given all the concerns raised here. The third parameter to As @aduth pointed out:
|
I merged #21868, which should give a temporary fix for the issues here by restoring |
This is a nice way of framing it 🙂 |
An additional question which arises from this is whether we should keep the I like a lot of what the class brings, and I especially like using it for a public API offering of the block object, notably with the consistency it brings through its property names. But these concerns do trouble me. A few thoughts:
|
There was another issue raised in Slack regarding the implementation of #21467. I proposed more a more thorough revert of the PHP implementation at #21921. |
Separately, I opened #21925 as a temporary pull request to experiment with a few of the ideas and issues discussed: Around possible resolutions for the |
We should move forward with #21925, but leverage getters to avoid looping over inner blocks twice, and we should also make sure the filters run on inner blocks when rendering. |
Previously: #21467
Related: Automattic/jetpack#15515
As part of the implementation of block context in #21467, the function signature of
render_callback
was revised in such a way that was intended to be fully backward-compatible. It did so by creating a custom block class which implemented the PHPArrayAccess
interface, where attempting to access array members of the first argument would be proxied automatically to block attribute members, to simulate the same effect of the previous signature wherein an array of block attributes was passed. The intention was to seamlessly allow the argument to be used either as an instance of the block class, or as an array of a block's attributes.Problem:
While implementing
ArrayAccess
is expected to satisfy a majority of common usage, it has become obvious that it does not faithfully uphold full backward compatibility. Some of these are rare and extreme edge cases, while others may be more common to anticipate.Examples:
extract
andjson_encode
on the argument value. The latter can be accommodated by further implementing the PHPJsonSerializable
interface, but the former cannot be supported.empty( $block_attributes['foo'] )
andisset( $block_attributes['foo'] )
would work, but notablyarray_key_exists( 'foo', $block_attributes )
would not work after the changes in Block API: Add Block Context support #21467.Possible Solutions:
Some options to consider include:
ArrayObject
in implementingIteratorAggregate
,ArrayAccess
,Serializable
,JsonSerializable
,Countable
render_callback_with_block( $block )
(qualified variant of existing name)render( $block )
(new name)'render_callback_receives_block' => true
render_callback
callable to consider if it specifies a type hint in its parameter signature.render_callback( WP_Block $block )
vs.render_callback( $block_attributes )
$block
instance available as a global contextualized to therender_callback
, but don't otherwise change the function signature.$block
available as a third argument ofrender_callback
Personal preference: I'm most keen to see if there are options around method reflection, in order to avoid the addition of a new settings property while giving the developers the choice to explicitly opt in to the behavior of receiving the block instance. It is not clear to me yet if this is a viable option.
Action Plan:
If a decision amongst the above (or additional) options cannot be reached and implemented before this Friday, April 24, then #21467 should be reverted to allow more time to consider the decision, or at least parts which affect the public API of
render_callback
.The text was updated successfully, but these errors were encountered: