-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Register Navigation Link block variations based on menu item types added in customizer filters #31584
Register Navigation Link block variations based on menu item types added in customizer filters #31584
Changes from all commits
bbd7144
98ddf30
4bfdc36
87af6d8
9490e72
89aa722
08da210
5c34f3b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
<?php | ||
/** | ||
* WP_REST_Menu_Custom_Items_Controller class. | ||
* | ||
* @package gutenberg | ||
*/ | ||
|
||
/** | ||
* Class that returns the menu items added via the | ||
* `customize_nav_menu_available_items` filter. | ||
*/ | ||
class WP_REST_Menu_Custom_Items_Controller extends WP_REST_Controller { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You'll want to tag in someone from the REST API team such as @TimothyBJacobs to take a look at this one. They have a regular Core team office hours in WP Core Slack if you need to get some traction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @getdave Can you provide context on what this endpoint does and why it is needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, although I would defer to @Aljullu who is the PR author. The endpoint is introduced purely to retrieve any custom nav menu items that have been added by the developer via the The items are then displayed in the Nav Editor in the @Aljullu also left a good explanation of the context behind this in the PR description and in the accompanying Issue. As I mentioned in my review of this PR, I would hope that we will not actually need to introduce a new endpoint but rather the functionality proposed can be introduced to the main Menu Items REST API endpoint. I will however, defer to your greater experience working on these endpoints. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Aljullu @getdave I think this code should live in the menu items endpoint. The fields map pretty well. Maybe something along the line of.
@TimothyBJacobs WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is the direction we are going, I think the REST API should be created in a new PR, with unit tests etc. Once it is merged, this PR can be rebased. |
||
/** | ||
* Constructor. | ||
*/ | ||
public function __construct() { | ||
$this->namespace = '__experimental'; | ||
$this->rest_base = 'menu-custom-items'; | ||
} | ||
|
||
/** | ||
* Registers the necessary REST API routes. | ||
* | ||
* @access public | ||
*/ | ||
public function register_routes() { | ||
register_rest_route( | ||
$this->namespace, | ||
'/' . $this->rest_base, | ||
array( | ||
array( | ||
'methods' => WP_REST_Server::READABLE, | ||
'callback' => array( $this, 'get_menu_custom_items' ), | ||
'permission_callback' => array( $this, 'permissions_check' ), | ||
'args' => $this->get_collection_params(), | ||
), | ||
'schema' => array( $this, 'get_public_item_schema' ), | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* Checks if a given request has access to read menu items if they have access to edit them. | ||
* | ||
* @return true|WP_Error True if the request has read access, WP_Error object otherwise. | ||
*/ | ||
public function permissions_check() { | ||
$post_type = get_post_type_object( 'nav_menu_item' ); | ||
if ( ! current_user_can( $post_type->cap->edit_posts ) ) { | ||
return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to view menu items.', 'gutenberg' ), array( 'status' => rest_authorization_required_code() ) ); | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Retrieves the menu custom items' schema, conforming to JSON Schema. | ||
* | ||
* @return array Item schema data. | ||
*/ | ||
public function get_item_schema() { | ||
$this->schema = array( | ||
'$schema' => 'http://json-schema.org/draft-04/schema#', | ||
'title' => 'menu-custom-items', | ||
'type' => 'object', | ||
'properties' => array( | ||
|
||
'id' => array( | ||
'description' => __( 'Unique identifier for the menu item.', 'gutenberg' ), | ||
'type' => 'string', | ||
'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), | ||
), | ||
'title' => array( | ||
'description' => __( 'Human-readable name identifying the menu item.', 'gutenberg' ), | ||
'type' => 'string', | ||
'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), | ||
), | ||
'type_label' => array( | ||
'description' => __( 'Type of link.', 'gutenberg' ), | ||
'type' => 'string', | ||
'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), | ||
), | ||
'url' => array( | ||
'description' => __( 'URL of the link.', 'gutenberg' ), | ||
'type' => 'string', | ||
'context' => array( 'post-editor', 'site-editor', 'widgets-editor' ), | ||
), | ||
), | ||
); | ||
|
||
return $this->add_additional_fields_schema( $this->schema ); | ||
} | ||
|
||
/** | ||
* Returns the menu items added via the | ||
* `customize_nav_menu_available_item_types` filter. | ||
* | ||
* @param WP_REST_Request $request Full details about the request. | ||
* @return WP_REST_Response|WP_Error Menu custom items, or WP_Error if type could not be found. | ||
*/ | ||
public function get_menu_custom_items( $request ) { | ||
$requested_type = $request->get_param( 'type' ); | ||
$item_types = apply_filters( 'customize_nav_menu_available_item_types', array() ); | ||
|
||
if ( is_array( $item_types ) ) { | ||
foreach ( $item_types as $item_type ) { | ||
if ( $item_type['type'] === $requested_type ) { | ||
return $this->prepare_item_for_response( $item_type, $request ); | ||
} | ||
} | ||
} | ||
|
||
return new WP_Error( 'rest_invalid_menu_item_type', __( 'This item type could not be found.', 'gutenberg' ), array( 'status' => 404 ) ); | ||
} | ||
|
||
/** | ||
* Prepares a menu list of items for serialization. | ||
* | ||
* @param stdClass $item_type Item type data. | ||
* @param WP_REST_Request $request Full details about the request. | ||
* | ||
* @return WP_REST_Response List of menu items. | ||
*/ | ||
public function prepare_item_for_response( $item_type, $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable | ||
return rest_ensure_response( | ||
apply_filters( 'customize_nav_menu_available_items', array(), $item_type['type'], $item_type['object'], 0 ) | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -382,7 +382,7 @@ public function update_item( $request ) { | |
|
||
$prepared_term = $this->prepare_item_for_database( $request ); | ||
|
||
// Only update the term if we haz something to update. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😆 |
||
// Only update the term if we have something to update. | ||
if ( ! empty( $prepared_term ) ) { | ||
$update = wp_update_nav_menu_object( $term->term_id, wp_slash( (array) $prepared_term ) ); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -105,6 +105,13 @@ Whether to present suggestions when typing the URL. | |
|
||
Whether to present initial suggestions immediately. | ||
|
||
### noDirectEntry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this used? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, that's unrelated to the other changes in that PR. It's a prop that was undocumented. I thought all props had to be in the docs, but happy to remove it from here if not. |
||
|
||
- Type: `boolean` | ||
- Required: No | ||
|
||
Whether to allow turning a URL-like search query directly into a link. | ||
|
||
### forceIsEditingLink | ||
|
||
- Type: `boolean` | ||
|
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 can't think be part of the existing menu items controller?
Also why does this have to part of the REST API at all. Can't be loaded in via localize script or similar?
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 results are shown in the search results within
<LinkControl>
are retrieved on demand from the REST API using this API within Gutenberg.It feels like the custom items should also be retrieved using the same mechanism.
From the discussion in the PR thread it looks like there are a number of options being proposed so this may change direction.