Skip to content

Customizer: Remove Menus panel when a theme does not support menus#2217

Closed
noisysocks wants to merge 6 commits intoWordPress:trunkfrom
noisysocks:fix/hide-menus-panel-on-block-themes
Closed

Customizer: Remove Menus panel when a theme does not support menus#2217
noisysocks wants to merge 6 commits intoWordPress:trunkfrom
noisysocks:fix/hide-menus-panel-on-block-themes

Conversation

@noisysocks
Copy link
Copy Markdown
Member

By having WP_Customize_Panel::check_capabilities(), we can ensure that the Menus panel is removed if a theme does not have support for 'menus' nor 'widgets'. (We show the Menus panel when there is support for 'widgets' so that one can use the Menu widget.)

This ensures that the Menus panel does not appear when using a block theme, which is pretty confusing, as the Navigation block is intended to be the sole place for editing a site's navigation when using a block theme.

Trac ticket: https://core.trac.wordpress.org/ticket/54888


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.

By overriding check_capabilities(), we can ensure that the Menus panel
is removed if a theme does not have support for 'menus' nor 'widgets'.

This ensures that the Menus panel does not appear when using a block
theme, which is confusing to users.
'priority' => 110,
'active_callback' => array( $this, 'is_panel_active' ),
'auto_expand_sole_section' => true,
'theme_supports' => 'widgets',
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hides the Widgets panel if the theme doesn't support 'widgets'. It isn't necessary as it will be hidden anyway because there won't be any registered sidebars. But I thought it would be nice to explicitly add this for consistency with the Menus panel.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend against this if it's not needed. Avoids unneded code for either 5.9 or 5.9.1.

Copy link
Copy Markdown
Contributor

@costdev costdev Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency makes sense here. The Core commit should reference menus and widgets per the PR's description, making code archaeology easier.

Edit: Timing. Defer to you and Peter to discuss unneeded code vs consistency.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, cool. I was on the fence. I've removed the change.

* @return bool False if theme doesn't support the panel or the user doesn't have the capability.
*/
final public function check_capabilities() {
public function check_capabilities() {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to mark this as non final which I think makes sense to do anyway.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense too. It allows panels to manage their own capabilities checks without needing something like this every time:

if ( current_theme_supports( 'some_feature' ) ) {
    // Add my custom panel.
}

if ( current_theme_supports( 'some_other_feature' ) ) {
    // Add my other custom panel.
}

This might need a dev note to let extenders know that this is now available to them. What do you think?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to mark this as non final which I think makes sense to do anyway.

@westonruter Do you recall if there was an essential reason WP_Customize_Panel::check_capabilities() was marked final?

Copy link
Copy Markdown
Member Author

@noisysocks noisysocks Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any discussion about final in the original tickets that added this code, which makes me think it was just done in an attempt to avoid backwards compatibility issues while this new API was being iterated on. It's a stable API now (committed 7 years ago) so I don't think we need to worry about that anymore.

https://core.trac.wordpress.org/ticket/29197

An alternative is that we could add a $theme_supports_callback property which would work similarly to the existing $active_callback that is used by active() which is marked final. I'm not such a fan of this though because then it isn't clear what should happen when both $theme_supports and $theme_supports_callback is set. Allowing check_capabilities() to be overridden feels simpler and more in line with the Customizer's OOP design to me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might need a dev note to let extenders know that this is now available to them. What do you think?

I think it's okay because there was already $theme_supports which allows just this. Overriding check_capabilities() is for more complex use-cases.

Maybe at most a little note in the "miscellaneous API changes" dev note is okay.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I went looking for a hint in Slack and IRC but couldn't find anything either.

An alternative may be to allow this->capability to be string|string[] and looping through.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little more on the history of the final keyword here:

The final keyword was added to WP_Customize_Section and WP_Customize_Setting in changeset 20248.

The only direct reference to check_capabilities() is:

prepare_controls() now removes any settings and sections that return false for check_capabilities().

Then, in changeset 29487, WP_Customize_Panel was separated to its own file. Having previously extended WP_Customize_Section, the change included copying the check_capabilities() method into WP_Customize_Panel.

This was likely just a copy-paste for consistency.

Copy link
Copy Markdown
Member Author

@noisysocks noisysocks Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative may be to allow this->capability to be string|string[] and looping through.

Unfortunately we're already using string[] for additional arguments that should be passed into current_theme_supports().

Copy link
Copy Markdown
Contributor

@peterwilsoncc peterwilsoncc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM with a CS nit.

I see @costdev has testing notes so haven't pulled it down.

'priority' => 110,
'active_callback' => array( $this, 'is_panel_active' ),
'auto_expand_sole_section' => true,
'theme_supports' => 'widgets',
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd recommend against this if it's not needed. Avoids unneded code for either 5.9 or 5.9.1.

Copy link
Copy Markdown
Contributor

@costdev costdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good and tests well. 👍

Just a change to @since and question about a possible dev note.

* @return bool False if theme doesn't support the panel or the user doesn't have the capability.
*/
final public function check_capabilities() {
public function check_capabilities() {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this makes sense too. It allows panels to manage their own capabilities checks without needing something like this every time:

if ( current_theme_supports( 'some_feature' ) ) {
    // Add my custom panel.
}

if ( current_theme_supports( 'some_other_feature' ) ) {
    // Add my other custom panel.
}

This might need a dev note to let extenders know that this is now available to them. What do you think?

'priority' => 110,
'active_callback' => array( $this, 'is_panel_active' ),
'auto_expand_sole_section' => true,
'theme_supports' => 'widgets',
Copy link
Copy Markdown
Contributor

@costdev costdev Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistency makes sense here. The Core commit should reference menus and widgets per the PR's description, making code archaeology easier.

Edit: Timing. Defer to you and Peter to discuss unneeded code vs consistency.

noisysocks and others added 3 commits January 24, 2022 14:24
Co-authored-by: Peter Wilson <519727+peterwilsoncc@users.noreply.github.com>
Co-authored-by: Colin Stewart <79332690+costdev@users.noreply.github.com>
@noisysocks
Copy link
Copy Markdown
Member Author

Edit: Timing. Defer to you and Peter to discuss unneeded code vs consistency.

😅 I want the consistency but, yeah, safest to not fix what isn't broken while in RC. I'll open a seperate patch which adds it and we can commit that to trunk only.

@noisysocks
Copy link
Copy Markdown
Member Author

Thanks for reviewing and testing. Feedback addressed. I can commit to both branches today if two devs approve 😀

Copy link
Copy Markdown
Contributor

@peterwilsoncc peterwilsoncc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see an alternative to removing the final, so let's do that.

@noisysocks
Copy link
Copy Markdown
Member Author

@noisysocks noisysocks closed this Jan 24, 2022
@noisysocks noisysocks deleted the fix/hide-menus-panel-on-block-themes branch January 24, 2022 05:39
*
* @return bool False if theme doesn't support the panel or the user doesn't have the capability.
*/
public function check_capabilities() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way to do this would have been to implement an active_callback which would return the result of current_theme_supports( 'menus' ) || current_theme_supports( 'widgets' ). The constructor could have:

$this->active_callback = function () {
    return current_theme_supports( 'menus' ) || current_theme_supports( 'widgets' );
};

The end result would be largely the same, however.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out that the way this was implemented doesn't work as intended. A PHP notice is triggered. See https://core.trac.wordpress.org/ticket/54905#comment:36

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants