Skip to content
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

Audit Navigation Screen third-party extensibility #23739

Closed
talldan opened this issue Jul 7, 2020 · 3 comments
Closed

Audit Navigation Screen third-party extensibility #23739

talldan opened this issue Jul 7, 2020 · 3 comments
Assignees
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Type] Tracking Issue Tactical breakdown of efforts across the codebase and/or tied to Overview issues.

Comments

@talldan
Copy link
Contributor

talldan commented Jul 7, 2020

As part of progressing the block-based navigation screen, we should look at the third-party extensibility that is currently available in customizer menu screens and decide what should/could be replicated in the block-based screen.

@talldan talldan added [Feature] Extensibility The ability to extend blocks or the editing experience [Type] Tracking Issue Tactical breakdown of efforts across the codebase and/or tied to Overview issues. labels Jul 7, 2020
@annezazu
Copy link
Contributor

I chatted with the author of this Nav Menu Roles plugin (@helgatheviking) to start to explore what might be desired for third party extensibility. She mentioned that generally being able to add and save custom fields will be a big help.

@draganescu draganescu self-assigned this Aug 19, 2020
@draganescu
Copy link
Contributor

Audit Navigation Screen third-party extensibility

I looked at three files implementing the current Menus screen in WP Admin:

  • wp-admin/nav-menus.php
  • wp-includes/nav-menu.php
  • wp-admin/includes/nav-menu.php

I found, as expected a list of checks, filters and actions. Then I ran through the menus endpoint to check which of them are already fired by the REST API and so are already supported, and which depend on server side rendering. They're marked with:

  • 🟩 if the REST API calls or the editor's code in "lib" already fire these filters and actions when building the responses or results
  • 🟥 if these filters and actions depend on things we don't do anymore in the new editor
  • 🟧 if these filters and actions can be supported and are not
  • ⬜ if these filters and actions are not relevant for the Navigation editor (searched how the functions that fire them are used)

Theme supports and permissions

  • 🟧 both supports menus and supports widgets are required
  • 🟧 user needs edit_theme_options permission

As far as I could find these are all the checks for being allowed to do things on that screen.

Filters

Actions

  • 🟥 after_menu_locations_table
  • 🟩 wp_delete_nav_menu
  • 🟩 wp_create_nav_menu
  • 🟩 wp_update_nav_menu (from wp_update_nav_menu_object)
  • 🟩 wp_add_nav_menu_item
  • 🟩 wp_update_nav_menu_item
  • 🟧 wp_update_nav_menu (from wp_nav_menu_update_menu_items)
Here are the items listed above with code context

Theme supports and permissions

Before we render anything on the current Menus screen in WP Admin we check for:

// wp-admin/nav-menus.php
if ( ! current_theme_supports( 'menus' ) && ! current_theme_supports( 'widgets' ) ) {
	wp_die( __( 'Your theme does not support navigation menus or widgets.' ) );
}
if ( ! current_user_can( 'edit_theme_options' ) ) {
	wp_die(
		'<h1>' . __( 'You need a higher level of permission.' ) . '</h1>' .
		'<p>' . __( 'Sorry, you are not allowed to edit theme options on this site.' ) . '</p>',
		403
	);
}

Filters

Here is a list of filters I found in these files:

//wp-admin/nav-menus.php
add_filter( 'screen_options_show_screen', '__return_false' );
add_filter( 'admin_body_class', 'wp_nav_menu_max_depth' );
//wp-admin/nav-menus.php
/*Filters the number of locations listed per menu in the drop-down select.*/
$locations_listed_per_menu = absint( apply_filters( 'wp_nav_locations_listed_per_menu', 3 ) );
//has_nav_menu
	/**
	 * Filters whether a nav menu is assigned to the specified location.
	 *
	 * @since 4.3.0
	 *
	 * @param bool   $has_nav_menu Whether there is a menu assigned to a location.
	 * @param string $location     Menu location.
	 */
	 return apply_filters( 'has_nav_menu', $has_nav_menu, $location );
//wp_get_nav_menu_name
	/**
	 * Filters the navigation menu name being returned.
	 *
	 * @since 4.9.0
	 *
	 * @param string $menu_name Menu name.
	 * @param string $location  Menu location identifier.
	 */
	 return apply_filters( 'wp_get_nav_menu_name', $menu_name, $location );
//wp_get_nav_menus
     /**
	 * Filters the navigation menu objects being returned.
	 *
	 * @since 3.0.0
	 *
	 * @see get_terms()
	 *
	 * @param WP_Term[] $menus An array of menu objects.
	 * @param array     $args  An array of arguments used to retrieve menu objects.
	 */
	 return apply_filters( 'wp_get_nav_menus', get_terms( $args ), $args );
//wp_get_nav_menu_items
	/**
	 * Filters the navigation menu items being returned.
	 *
	 * @since 3.0.0
	 *
	 * @param array  $items An array of menu item post objects.
	 * @param object $menu  The menu object.
	 * @param array  $args  An array of arguments used to retrieve menu item objects.
	 */
	 return apply_filters( 'wp_get_nav_menu_items', $items, $menu, $args );
//wp_setup_nav_menu_item
	$original_title = apply_filters( 'the_title', $original_object->post_title, $original_object->ID );
	
	$menu_item->attr_title = ! isset( $menu_item->attr_title ) ? apply_filters( 'nav_menu_attr_title', $menu_item->post_excerpt ) : $menu_item->attr_title;
	$menu_item->description = apply_filters( 'nav_menu_description', wp_trim_words( $menu_item->post_content, 200 ) );
	$menu_item->attr_title = apply_filters( 'nav_menu_attr_title', '' );
	$menu_item->description = apply_filters( 'nav_menu_description', '' );
	
	/**
	 * Filters a navigation menu item object.
	 *
	 * @since 3.0.0
	 *
	 * @param object $menu_item The menu item object.
	 */
	 return apply_filters( 'wp_setup_nav_menu_item', $menu_item );
wp_get_nav_menu_object
	/**
	 * Filters the nav_menu term retrieved for wp_get_nav_menu_object().
	 *
	 * @since 4.3.0
	 *
	 * @param WP_Term|false      $menu_obj Term from nav_menu taxonomy, or false if nothing had been found.
	 * @param int|string|WP_Term $menu     The menu ID, slug, name, or object passed to wp_get_nav_menu_object().
	 */
	 return apply_filters( 'wp_get_nav_menu_object', $menu_obj, $menu );
//wp_nav_menu_post_type_meta_boxes
	$post_type = apply_filters( 'nav_menu_meta_box_object', $post_type );
//wp_nav_menu_taxonomy_meta_boxes
	$tax = apply_filters( 'nav_menu_meta_box_object', $tax );
//wp_nav_menu_item_post_type_meta_box
	$most_recent = apply_filters( "nav_menu_items_{$post_type_name}_recent", $most_recent, $args, $box, $recent_args );
	echo walk_nav_menu_tree( array_map( 'wp_setup_nav_menu_item', $most_recent ), 0, (object) $args );
	$posts = apply_filters( "nav_menu_items_{$post_type_name}", $posts, $args, $post_type );
//wp_get_nav_menu_to_edit
	$walker_class_name = apply_filters( 'wp_edit_nav_menu_walker', 'Walker_Nav_Menu_Edit', $menu_id );

Actions

Here is a list of actions I found in these files:

//wp-admin/nav-menus.php
/**
 * Fires after the menu locations table is displayed.
 *
 * @since 3.6.0
 */
do_action( 'after_menu_locations_table' );
//wp_delete_nav_menu
	do_action( 'wp_delete_nav_menu', $menu->term_id );
//wp_update_nav_menu_object
	do_action( 'wp_create_nav_menu', $_menu['term_id'], $menu_data );
	do_action( 'wp_update_nav_menu', $menu_id, $menu_data );
//wp_update_nav_menu_item
	do_action( 'wp_add_nav_menu_item', $menu_id, $menu_item_db_id, $args );
	do_action( 'wp_update_nav_menu_item', $menu_id, $menu_item_db_id, $args );
//wp_nav_menu_update_menu_items
	/** This action is documented in wp-includes/nav-menu.php */
	do_action( 'wp_update_nav_menu', $nav_menu_selected_id );

@draganescu
Copy link
Contributor

Based on the audit above we need to figure out what to do about the red items and open issues about adding support for the orange ones 😸

Most of the red items are things that depended on the markup generation done server side for the Menus screen, which now gets replaced with a client side react app, so some of these filters cannot be identically supported, eventually replaced with similar extensibility.

The most glaring one is the use of a Walker to render the nested structure of the menu in admin which I can't see how it can be supported in our current Navigation editor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Type] Tracking Issue Tactical breakdown of efforts across the codebase and/or tied to Overview issues.
Projects
None yet
Development

No branches or pull requests

3 participants