-
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
Navigation: Refactor the PHP render function to make it easier to make changes in the future #55605
Conversation
/** | ||
* Returns whether or not a navigation has a submenu. | ||
*/ | ||
private static function does_navigation_have_submenus( $inner_blocks ) { |
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.
My main concern is that this function is now called several times so its probably slightly less performant.
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 could exit the loop early and return from the method if a submenu is found. I think continue
will do that 🤔
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.
now called several times
Why is this different than before?
probably slightly less performant.
Also this is likely to be marginal. Is it a big concern?
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.
Let's create an instance variable to cache the result of the function. Then we can check if the instance variable has already been assigned and exit early with that result.
Actually it's a static class so doing this makes no sense. The class doesn't not represent a block instance.
I'm now wondering if the class should not be static. The instance represents a Navigation and the class is a blue print for hanlding that Nav
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.
Why is this different than before?
Before it was called in the render function and saved in a variable.
Also this is likely to be marginal. Is it a big concern?
No
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.
Good PR 👍
Initial thoughts...
/** | ||
* Returns whether or not a navigation has a submenu. | ||
*/ | ||
private static function does_navigation_have_submenus( $inner_blocks ) { |
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 could exit the loop early and return from the method if a submenu is found. I think continue
will do that 🤔
/** | ||
* Returns whether or not a navigation has a submenu. | ||
*/ | ||
private static function does_navigation_have_submenus( $inner_blocks ) { |
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.
now called several times
Why is this different than before?
probably slightly less performant.
Also this is likely to be marginal. Is it a big concern?
/** | ||
* Returns whether or not a navigation has a submenu. | ||
*/ | ||
private static function does_navigation_have_submenus( $inner_blocks ) { |
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.
Let's create an instance variable to cache the result of the function. Then we can check if the instance variable has already been assigned and exit early with that result.
Actually it's a static class so doing this makes no sense. The class doesn't not represent a block instance.
I'm now wondering if the class should not be static. The instance represents a Navigation and the class is a blue print for hanlding that Nav
$responsive_container_markup, | ||
$nav_element_directives | ||
); | ||
return WP_Navigation_Block::render( $attributes, $content, $block ); |
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.
So clean 🏅
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.
More comments..
/** | ||
* Returns the markup for the navigation block. | ||
*/ |
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'm looking at this thinking...
How is this different from
render
?
😕 Is there a better name?
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 thing I dislike about the PR is that we're refactoring without any test coverage. So the only way we will know if refactoring broke something is when a bug is found 😬
But given the lack of existing tests I don't see much option.
I think we should add unit tests for a select few methods at least,
Flaky tests detected in 0e63a3a. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6785723162
|
…e changes in the future
Co-authored-by: Dave Smith <[email protected]>
Co-authored-by: Dave Smith <[email protected]>
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 the unit tests that we included on this PR, I've tested this comparing the markup generated for a navigation block that has:
- a submenu
- a site title block
- a logo block
- social icons
The markup generated on trunk and with this PR is exactly the same except for the is-fallback
class that has been removed. I think this is good to go!
I decided to merge this so that we don't end up with messy rebases when changes get made to the navigation render function. I expect there are still opportunities to improve this code though, so please leave more reviews and I'll follow up with more improvements. I'll also submit a core patch now so that we can get reviews from core committers. |
I opened a patch in core for this here: https://core.trac.wordpress.org/ticket/59867 |
What's the strategy for patching bugs or making enhancements for this class after it ships in the core? I'm asking because we started discouraging |
What we've done previously with e.g. the theme json class is make a copy of the whole class in Gutenberg, namespaced so it doesn't conflict with the core one, and use it in the plugin instead of the core class. If we're using the class directly in the block library PHP files that makes things a little more complicated 😅 but I'm sure we can come up with some auto-renaming script that will switch the core class with the gutenberg one at build time. |
…e changes in the future (#55605) * Navigation: Refactor the PHP render function to make it easier to make changes in the future * move code to get_inner_blocks_html * remove is-fallback class * allow multiple menus * add some comments * refactor directives to a different function * fix submenus * refactor responseive navigation function * remove a passed param * create a function for get_styles * dont pass the container_attributes as a param * handle view script loading * reorder code * simplify the return * tidy up the wrapper attributes * remove one dependence on has_submenu * remove the should load view script variable * more simplification * Update packages/block-library/src/navigation/index.php Co-authored-by: Dave Smith <[email protected]> * rename class * remname is_responsive_navigation * rename does_navigation_have_submenus * rename get_inner_blocks_for_navigation * rename get_layout_class_for_navigation * Update packages/block-library/src/navigation/index.php Co-authored-by: Dave Smith <[email protected]> * Update packages/block-library/src/navigation/index.php Co-authored-by: Dave Smith <[email protected]> * change name of get_nav_markup * split get_inner_blocks into smaller functions * add comment * remove unnecessary spaces * update docs * reverse parameter order * reverse parameter order * reverse parameter order * move the class to a new file * add docs * rename to * move function that's only used by the plugin into that section of the code * fix linter * reference the class internally using static * move variable to static variables * Update lib/compat/wordpress-6.5/class-wp-navigation-block-renderer.php Co-authored-by: Dave Smith <[email protected]> * Update lib/compat/wordpress-6.5/class-wp-navigation-block-renderer.php Co-authored-by: Dave Smith <[email protected]> * move the logic for inner block rendering to a separate function * test for navigation link markup * test for site title markup * removed comments, changed assertSame to assertEquals * format php * hide the condition in a function * hide the condition in a function * return early from has_submenus * comments for the tests * create a function to get the name * rename variable to nav_blocks_wrapped_in_list_item * phpcs * phpcs * Update phpunit/class-wp-navigation-block-renderer-test.php Co-authored-by: Dave Smith <[email protected]> * Update phpunit/class-wp-navigation-block-renderer-test.php * Update phpunit/class-wp-navigation-block-renderer-test.php * Apply suggestions from code review Co-authored-by: Dave Smith <[email protected]> * dynamic url for links on test --------- Co-authored-by: Dave Smith <[email protected]> Co-authored-by: MaggieCabrera <[email protected]>
} | ||
|
||
$menu_items_by_parent_id = block_core_navigation_sort_menu_items_by_parent_id( $menu_items ); | ||
$parsed_blocks = block_core_navigation_parse_blocks_from_menu_items( $menu_items_by_parent_id[0], $menu_items_by_parent_id ); |
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'm seeing a warning Deprecated: Function gutenberg_block_core_navigation_parse_blocks_from_menu_items is deprecated since version 6.3.0! Use WP_Navigation_Fallback::parse_blocks_from_menu_items instead. in /var/www/html/wp-includes/functions.php on line 6031
on trunk when using a hybrid theme with some legacy Navigation blocks in it. Would it be possible to use WP_Navigation_Fallback::parse_blocks_from_menu_items
here?
* @package Gutenberg | ||
*/ | ||
|
||
class WP_Navigation_Block_Renderer_Test extends WP_UnitTestCase { |
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.
@scruffian I think we should move this test into the phpunit/blocks
directory. It is specific to a specific block and thus should be managed within the Gutenberg repo.
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.
Done in #58247
Noting that the renderer file code was moved into the block-library package in #57979 and thus should be automatically handled by the packages sync process. However, the phpunit test should be moved into |
👋 We need a follow-up to address some performance issues. I've prepared #58506 to demonstrate. |
What?
This refactors the PHP render function for the navigation block.
Why?
The aims are:
How?
Creates a new class called WP_Navigation_Block so that the new functions can be kept private.
Testing Instructions
Check that the navigation block continues to behave as before.
Note
This removed the
.is-fallback
CSS class from the navigation block when it's in a fallback state. We don't use this class in core and I can't see a value to it for themes or users.