-
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
WP_HTML_Tag_Processor: Add get_attributes_by_prefix()
method
#46672
Conversation
This docstring makes me more hesitant about this API: $p = new WP_HTML_Tag_Processor( '<div data-enabled class="test" data-test-id="14">Test</div>' );
$p->next_tag( [ 'class_name' => 'test' ] ) === true;
$p->get_attributes_by_prefix( 'data-' ) === array( 'data-enabled' => true, 'data-test-id' => '14' );
In other words, even after calling $attrs = $p->get_attributes_by_prefix( 'data-' );
if( array_key_exists( $attr, 'data-show' ) ) { /* ... */ } What is the added value over $attrs = $p->get_attributes_names();
if( in_array( 'data-show', $attr, true ) ) { /* ... */ } |
Case in point: We want to allow "binding" an arbitrary attribute to the value of an expression, e.g. <!-- Written by the developer -->
<img wp-bind:src="myblock.imageSource" />
<div wp-class:red="myblock.someValue" class="blue"></div>
<div wp-style:color="myblock.someValue" style="background: blue;"></div>
<!-- After processing -->
<img wp-bind:src="myblock.imageSource" src="Value of myblock.imageSource" />
<div wp-class:red="myblock.truthyValue" class="blue red"></div>
<div
wp-style:color="myblock.greenValue"
style="background: blue; color: green;"
></div> (from WordPress/block-interactivity-experiments#118 (comment); cf. Alpine's So I don't think we'll do much filtering of allowed attributes there (since we basically want to allow binding to pretty much any arbitrary attribute) 🤔 Instead, if we have
Mostly that it aligns nicely with the concept of prefixes for custom attributes and the like, I'd say. (I don't feel too strongly about this, though.) |
Update: I've experimented a bit more over at WordPress/block-interactivity-experiments#118 and implemented a basic It seems like |
|
8aa8204
to
e06c326
Compare
* @covers WP_HTML_Tag_Processor::get_attributes_by_prefix | ||
*/ | ||
public function test_get_attributes_by_prefix_returns_set_of_prefixed_attributes() { | ||
$p = new WP_HTML_Tag_Processor( '<div data-enabled class="test" data-test-id="14">Test</div>' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What should happen in these cases?
<div DATA-enabled class="test" data-test-id="14">Test</div>
and$p->get_attributes_by_prefix( 'data-' );
<div DATA-enabled class="test" data-test-id="14">Test</div>
and$p->get_attributes_by_prefix( 'DATA-' );
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, nice one! 😄
Well, I'd say it should align with get_attribute()
's behavior. The "invariant" should be that if I do something like $attrs = $p->get_attributes_by_prefix( $prefix );
and then call $p->get_attribute()
for each of $attrs
' keys, it shouldn't return null
for any of them.
- Let's assume
get_attribute()
is case-sensitive, i.e.
$p = new WP_HTML_Tag_Processor( '<div DATA-enabled class="test" data-test-id="14">Test</div>' );
$p->get_attribute( 'DATA-enabled' ) === true;
$p->get_attribute( 'DATA-test-id' ) === null;
$p->get_attribute( 'data-enabled' ) === null;
$p->get_attribute( 'data-test-id' ) === '14';
$p->get_attribute( 'DATA-ENABLED' ) === null;
$p->get_attribute( 'DATA-TEST-ID' ) === null;
Then, IMO,
get_attributes_by_prefix( 'data-' )
should returnarray( 'data-test-id' => '14')
get_attributes_by_prefix( 'DATA-' )
should returnarray( 'DATA-enabled' => true)
- Assuming
get_attribute()
is case-insensitive, i.e.
$p = new WP_HTML_Tag_Processor( '<div DATA-enabled class="test" data-test-id="14">Test</div>' );
$p->get_attribute( 'DATA-enabled' ) === true;
$p->get_attribute( 'DATA-test-id' ) === '14';
$p->get_attribute( 'data-enabled' ) === true;
$p->get_attribute( 'data-test-id' ) === '14';
$p->get_attribute( 'DATA-ENABLED' ) === true;
$p->get_attribute( 'DATA-TEST-ID' ) === '14';
Then, IMO,
get_attributes_by_prefix( 'data-' )
should returnarray( 'DATA-enabled' => true, 'data-test-id' => '14' )
get_attributes_by_prefix( 'DATA-' )
should returnarray( 'DATA-enabled' => true, 'data-test-id' => '14' )
Does that make sense?
Reality-checking the behavior of get_attribute()
is fun 😬
$p = new WP_HTML_Tag_Processor( '<div DATA-enabled class="test" data-test-id="14">Test</div>' );
$p->next_tag();
$p->get_attribute( 'data-enabled' ) === null; // Okay, I guess we're case-sensitive.
$p->get_attribute( 'DATA-ENABLED' ) === null; // Yep, looks like.
$p->get_attribute( 'DATA-enabled' ) === null; // ???
Is this expected? 😬
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh golly, that's a bug. Attributes should be case-insensitive. Here's a fix: #46748
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for the fix! I just merged it 😄
e06c326
to
b7cac44
Compare
Rebased (to include #46748). |
Closing if favor of #46840. |
What?
Add a
get_attributes_by_prefix()
method toWP_HTML_Tag_Processor
, which returns the set of attribute name/value pairs of all attributes whose name starts with a given prefix.Why?
Getting all attributes with a given prefix is handy for
data-
attributes, and custom namesepaces (e.g.ng-
orx-
).Furthermore, it helps with syntax like
<img wp-bind:src="myblock.imageSource" />
, which is a requirement for the Block Interactivity API (see).More background: WordPress/block-interactivity-experiments#118 (comment).
How?
It filters the current tag's
$attributes
for all attribute names that start with$prefix
, and then callsget_attribute
for each of them.Testing Instructions
See included unit test.