-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Add/render layout support updates #3976
Add/render layout support updates #3976
Conversation
function wp_get_classnames_from_last_tag( $html ) { | ||
$tags = new WP_HTML_Tag_Processor( $html ); | ||
$last_classnames = ''; | ||
|
||
while ( $tags->next_tag() ) { | ||
$last_classnames = $tags->get_attribute( 'class' ); | ||
} | ||
|
||
return (string) $last_classnames; | ||
} |
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.
Suggestion: I only see a single use of this method. Maybe we should avoid introducing a public method and use WP_HTML_Tag_Processor
directly.
The functions are always public in PHP, and we can only deprecate them after the release.
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.
@Mamaduka Agreed. Can we instead inline this logic in the wp_render_layout_support_flag()
function please? This means we can avoid introducing this function.
If there is eventually another change that needs something like this, we can always introduce a new function, but right now it seems unnecessary.
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.
Besides @Mamaduka 's comment about the new function vs inlining, I tested and this looks good to me. Thanks!
I've also tested the layout
changes on the packages update PR and also tested the stack
setting(having the updated packages) with this markup:
<!-- wp:group {"style":{"dimensions":{"minHeight":"400px"}},"layout":{"type":"flex","orientation":"vertical"}} -->
<div class="wp-block-group" style="min-height:400px"><!-- wp:heading {"style":{"layout":{"selfStretch":"fill","flexSize":null}},"backgroundColor":"light-green-cyan"} -->
<h2 class="wp-block-heading has-light-green-cyan-background-color has-background">1</h2>
<!-- /wp:heading -->
<!-- wp:paragraph {"style":{"layout":{"selfStretch":"fixed","flexSize":"123px"}},"backgroundColor":"luminous-vivid-orange"} -->
<p class="has-luminous-vivid-orange-background-color has-background">2</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->
*/ | ||
public function test_layout_support_flag_renders_classnames_on_wrapper( $args, $expected_output ) { | ||
$actual_output = wp_render_layout_support_flag( $args['block_content'], $args['block'] ); | ||
$this->assertEquals( $expected_output, $actual_output ); |
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.
$this->assertEquals( $expected_output, $actual_output ); | |
$this->assertSame( $expected_output, $actual_output ); |
$outer_class_names = array(); | ||
|
||
if ( $has_child_layout && ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] || 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) ) { | ||
|
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.
if ( ! $support_layout | ||
&& ! $has_child_layout ) { |
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.
if ( ! $support_layout | |
&& ! $has_child_layout ) { | |
if ( ! $support_layout && ! $has_child_layout ) { |
); | ||
|
||
$outer_class_names[] = $container_content_class; | ||
|
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.
|
||
/** | ||
* The first chunk of innerContent contains the block markup up until the inner blocks start. | ||
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk. |
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.
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk. | |
* This targets the opening tag of the inner blocks wrapper, which is the last tag in that chunk. |
* @param string $html markup to be processed. | ||
* @return string String of inner wrapper classnames. | ||
*/ | ||
function wp_get_classnames_from_last_tag( $html ) { |
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.
Obligatory "Naming things is hard", but I wonder if more context in this function name is needed.
Why?
"Tag" could mean one of at least two things when it comes to WordPress: a taxonomy type or a HTML element.
@hellofromtonya @felixarntz Any thoughts on the naming here?
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.
I think the name is okay (WordPress core already uses the word "tag" for both of the two meanings in various function names), but more importantly I think this conversation shouldn't really be relevant given @Mamaduka's feedback that we should not need to introduce this function in the first place.
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.
@tellthemachines Looks almost good to go from my perspective, though I agree with @Mamaduka that we should not unnecessarily introduce a new function here when its logic is rather specific and only needed in a single place.
function wp_get_classnames_from_last_tag( $html ) { | ||
$tags = new WP_HTML_Tag_Processor( $html ); | ||
$last_classnames = ''; | ||
|
||
while ( $tags->next_tag() ) { | ||
$last_classnames = $tags->get_attribute( 'class' ); | ||
} | ||
|
||
return (string) $last_classnames; | ||
} |
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.
@Mamaduka Agreed. Can we instead inline this logic in the wp_render_layout_support_flag()
function please? This means we can avoid introducing this function.
If there is eventually another change that needs something like this, we can always introduce a new function, but right now it seems unnecessary.
* @param string $html markup to be processed. | ||
* @return string String of inner wrapper classnames. | ||
*/ | ||
function wp_get_classnames_from_last_tag( $html ) { |
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.
I think the name is okay (WordPress core already uses the word "tag" for both of the two meanings in various function names), but more importantly I think this conversation shouldn't really be relevant given @Mamaduka's feedback that we should not need to introduce this function in the first place.
* The first chunk of innerContent contains the block markup up until the inner blocks start. | ||
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk. | ||
*/ | ||
$inner_content_classnames = isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) ? wp_get_classnames_from_last_tag( $block['innerContent'][0] ) : ''; |
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.
See above, can we inline that logic here in a dedicated if ( isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) )
block?
Thanks for the feedback folks! I've made all the requested changes, so this should be ready for another round. |
@tellthemachines I tried to fix the merge conflict in the fixtures with latest If there are test failures, I'll check and can hopefully fix it. Apologies, not really familiar with the fixtures. |
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.
Seems all feedback was addressed. Looks good to merge.
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.
Thanks @tellthemachines!
Noting that the test failures here are unrelated and intermittent, fixed via https://core.trac.wordpress.org/changeset/55280. |
Committed in https://core.trac.wordpress.org/changeset/55282. |
…lasses. In #45364 (WordPress/wordpress-develop#3976) the Block Supports was extended to add layout class names using the HTML API, new in WordPress 6.2. The initial patch opened up two opportunities to refine the code, however: - There are multiple instances of the `WP_HTML_Tag_Processor` created when a single one suffices. (There is an exception in that a second processor is necessary in order to find an inner block wrapper). - The code relies on the incidental fact that searching by a whitespace-separated list of class names works if the class names in the target tag are in the same order. In this patch the use of the HTML API is refactored to address these opportunities and clean up a few places where there could be stronger consistency with other use patterns of the HTML API: - Multiple instances of the Tag Processor have been combined to remove overhead, extra variables, and code confusion. The new flow is more linear throughout the function instead of branching. - Updated HTML is returned via `get_updated_html()` instead of casting to a string. - The matching logic to find the inner block wrapper has been commented and the condition uses the null-coalescing operator now that WordPress requires PHP 7.0+. - When attempting to find the inner block wrapper at the end, a custom comparison is made against the `class` attribute instead of relying on `next_tag()` to find a tag with the given set of class names. The last refactor is important as a preliminary step to WordPress/wordpress-develop#5096 where `has_class()` and `class_list()` methods are being introduced to the Tag Processor. In that patch the implicit functionality of matching `'class_name' => 'more than one class'` is removed since that's not a single class name, but many.
…lasses. In #45364 (WordPress/wordpress-develop#3976) the Block Supports was extended to add layout class names using the HTML API, new in WordPress 6.2. The initial patch opened up two opportunities to refine the code, however: - There are multiple instances of the `WP_HTML_Tag_Processor` created when a single one suffices. (There is an exception in that a second processor is necessary in order to find an inner block wrapper). - The code relies on the incidental fact that searching by a whitespace-separated list of class names works if the class names in the target tag are in the same order. In this patch the use of the HTML API is refactored to address these opportunities and clean up a few places where there could be stronger consistency with other use patterns of the HTML API: - Multiple instances of the Tag Processor have been combined to remove overhead, extra variables, and code confusion. The new flow is more linear throughout the function instead of branching. - Updated HTML is returned via `get_updated_html()` instead of casting to a string. - The matching logic to find the inner block wrapper has been commented and the condition uses the null-coalescing operator now that WordPress requires PHP 7.0+. - When attempting to find the inner block wrapper at the end, a custom comparison is made against the `class` attribute instead of relying on `next_tag()` to find a tag with the given set of class names. The last refactor is important as a preliminary step to WordPress/wordpress-develop#5096 where `has_class()` and `class_list()` methods are being introduced to the Tag Processor. In that patch the implicit functionality of matching `'class_name' => 'more than one class'` is removed since that's not a single class name, but many.
…lasses. In #45364 (WordPress/wordpress-develop#3976) the Block Supports was extended to add layout class names using the HTML API, new in WordPress 6.2. The initial patch opened up two opportunities to refine the code, however: - There are multiple instances of the `WP_HTML_Tag_Processor` created when a single one suffices. (There is an exception in that a second processor is necessary in order to find an inner block wrapper). - The code relies on the incidental fact that searching by a whitespace-separated list of class names works if the class names in the target tag are in the same order. In this patch the use of the HTML API is refactored to address these opportunities and clean up a few places where there could be stronger consistency with other use patterns of the HTML API: - Multiple instances of the Tag Processor have been combined to remove overhead, extra variables, and code confusion. The new flow is more linear throughout the function instead of branching. - Updated HTML is returned via `get_updated_html()` instead of casting to a string. - The matching logic to find the inner block wrapper has been commented and the condition uses the null-coalescing operator now that WordPress requires PHP 7.0+. - When attempting to find the inner block wrapper at the end, a custom comparison is made against the `class` attribute instead of relying on `next_tag()` to find a tag with the given set of class names. The last refactor is important as a preliminary step to WordPress/wordpress-develop#5096 where `has_class()` and `class_list()` methods are being introduced to the Tag Processor. In that patch the implicit functionality of matching `'class_name' => 'more than one class'` is removed since that's not a single class name, but many.
Trac ticket: https://core.trac.wordpress.org/ticket/57584
Includes changes from:
which change the layout render filter to add layout classes to the inner block wrapper, instead of the outer, and
which change the layout render filter to allow inner blocks to receive layout classes and styles. This builds on the former changeset, which is why I thought it simpler to backport both pieces together.
I also added some tests for
wp_render_layout_support_flag
(from WordPress/gutenberg#47719) and updated some of the server block fixtures because the change to add classnames to the inner block wrapper caused the order in which layout classes are added to switch.To test the child layout changes, add the following markup in the editor, save and check that child block 1 occupies all the leftover width of its container:
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.