From 6b03a18fe3360ab0c11fd29ef4b237ab3b7e22a7 Mon Sep 17 00:00:00 2001 From: Fahrradflucht Date: Wed, 18 May 2016 17:12:26 +0200 Subject: [PATCH 1/4] Add items argument to /menus. In some cases the cost of fetching the menus first and then only fetching the childs for the menus that are needed by id are higher then fetching them all at once. It's now possible to specify an `items` argument to indicate whether to fetch the menu items aswell or not. This could be also helpfull in cases like [this](https://wordpress.org/support/topic/get-menu-data-by-name-not-id) to filter on the client, although a `slug` argument to filter the menus array in addition would be need. Note that this change is currently V2 only. --- README.md | 9 +++++---- includes/wp-api-menus-v2.php | 21 ++++++++++++++++++++- readme.txt | 5 +++-- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 8a7a7de..f175133 100644 --- a/README.md +++ b/README.md @@ -11,20 +11,21 @@ #### New routes available: - `/menus` list of every registered menu. + - (V2 only:) `item` argument whether to fetch the menu items. Default: `false` - `/menus/` data for a specific menu. - `/menu-locations` list of all registered theme locations. -- `/menu-locations/` data for menu in specified menu in theme location. +- `/menu-locations/` data for menu in specified menu in theme location. Currently, the `menu-locations/` route for individual menus will return a tree with full menu hierarchy, with correct menu item order and listing children for each menu item. The `menus/` route will output menu details and a flat array of menu items. Item order or if each item has a parent will be indicated in each item attributes, but this route won't output items as a tree. - + You can alter the data arrangement of each individual menu items and children using the filter hook `json_menus_format_menu_item`. #### WP API V2 In V1 of the REST API the routes are located by default at `wp-json/menus/` etc. -In V2 the routes by default are at `wp-json/wp-api-menus/v2/` (e.g. `wp-json/wp-api-menus/v2/menus/`, etc.) since V2 encourages prefixing and version namespacing. +In V2 the routes by default are at `wp-json/wp-api-menus/v2/` (e.g. `wp-json/wp-api-menus/v2/menus/`, etc.) since V2 encourages prefixing and version namespacing. #### Contributing -* Submit a pull request or open a ticket here on GitHub. \ No newline at end of file +* Submit a pull request or open a ticket here on GitHub. diff --git a/includes/wp-api-menus-v2.php b/includes/wp-api-menus-v2.php index 2db70bc..75ab4f5 100644 --- a/includes/wp-api-menus-v2.php +++ b/includes/wp-api-menus-v2.php @@ -57,6 +57,12 @@ public function register_routes() { array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_menus' ), + 'args' => array( + 'items' => array( + 'description' => __( 'Whether to fetch the menu items.' ), + 'default' => false, + ), + ), ) ) ); @@ -93,10 +99,12 @@ public function register_routes() { * Get menus. * * @since 1.2.0 + * @param $request * @return array All registered menus */ - public static function get_menus() { + public function get_menus( $request ) { + $items = (bool) $request['items']; $rest_url = trailingslashit( get_rest_url() . self::get_plugin_namespace() . '/menus/' ); $wp_menus = wp_get_nav_menus(); @@ -113,6 +121,17 @@ public static function get_menus() { $rest_menus[ $i ]['description'] = $menu['description']; $rest_menus[ $i ]['count'] = $menu['count']; + if ($items) { + $wp_menu_items = wp_get_nav_menu_items( $menu['term_id'] ); + $rest_menu_items = array(); + foreach ( $wp_menu_items as $item_object ) { + $rest_menu_items[] = $this->format_menu_item( $item_object ); + } + $rest_menu_items = $this->nested_menu_items($rest_menu_items, 0); + + $rest_menus[ $i ]['items'] = $rest_menu_items; + } + $rest_menus[ $i ]['meta']['links']['collection'] = $rest_url; $rest_menus[ $i ]['meta']['links']['self'] = $rest_url . $menu['term_id']; diff --git a/readme.txt b/readme.txt index 0fbc452..bdddefd 100644 --- a/readme.txt +++ b/readme.txt @@ -17,6 +17,7 @@ This plugin extends the [WordPress JSON REST API](https://wordpress.org/plugins/ The new routes available will be: * `/menus` list of every registered menu. + * (V2 only:) `item` argument whether to fetch the menu items. Default: `false` * `/menus/` data for a specific menu. * `/menu-locations` list of all registered theme locations. * `/menu-locations/` data for menu in specified menu in theme location. @@ -90,7 +91,7 @@ Nothing to show really, this plugin has no settings or frontend, it just extends = 1.1.0 = * Enhancement: Routes for menus in theme locations now include complete tree with item order and nested children * Tweak: `description` attribute for individual items is now included in results -* Fix: Fixed typo confusing `parent` with `collection` in meta +* Fix: Fixed typo confusing `parent` with `collection` in meta = 1.0.0 = * First public release @@ -99,4 +100,4 @@ Nothing to show really, this plugin has no settings or frontend, it just extends = 1.2.1 = -API V2 only: mind lowercase `id` instead of uppercase `ID` in API responses, to match the standard for `id` used across WP REST API. \ No newline at end of file +API V2 only: mind lowercase `id` instead of uppercase `ID` in API responses, to match the standard for `id` used across WP REST API. From 479e74c670097eea4d4a17c1270cd18eb628b1a1 Mon Sep 17 00:00:00 2001 From: Fahrradflucht Date: Wed, 18 May 2016 18:48:06 +0200 Subject: [PATCH 2/4] Change /menus/ to take ids names and slugs. Changed /menus/ to /menus/ to take all supported param types of [wp_get_nav_menu_object](https://developer.wordpress.org/reference/functions/wp_get_nav_menu_object/) and [wp_get_nav_menu_items](https://developer.wordpress.org/reference/functions/wp_get_nav_menu_object/). This makes the slug filter argument suggested in 6b03a18 obsolete. Note that this is currently V2 only. --- README.md | 2 +- includes/wp-api-menus-v2.php | 8 ++++---- readme.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f175133..2804054 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - `/menus` list of every registered menu. - (V2 only:) `item` argument whether to fetch the menu items. Default: `false` -- `/menus/` data for a specific menu. +- `/menus/` data for a specific menu. Takes either an id, a name or a slug. Note that v1 only supports ids. - `/menu-locations` list of all registered theme locations. - `/menu-locations/` data for menu in specified menu in theme location. diff --git a/includes/wp-api-menus-v2.php b/includes/wp-api-menus-v2.php index 75ab4f5..77ccc60 100644 --- a/includes/wp-api-menus-v2.php +++ b/includes/wp-api-menus-v2.php @@ -66,7 +66,7 @@ public function register_routes() { ) ) ); - register_rest_route( self::get_plugin_namespace(), '/menus/(?P\d+)', array( + register_rest_route( self::get_plugin_namespace(), '/menus/(?P[a-zA-Z0-9_-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_menu' ), @@ -151,10 +151,10 @@ public function get_menus( $request ) { */ public function get_menu( $request ) { - $id = (int) $request['id']; + $menu = (string) $request['menu']; $rest_url = get_rest_url() . self::get_api_namespace() . '/menus/'; - $wp_menu_object = $id ? wp_get_nav_menu_object( $id ) : array(); - $wp_menu_items = $id ? wp_get_nav_menu_items( $id ) : array(); + $wp_menu_object = $menu ? wp_get_nav_menu_object( $menu ) : array(); + $wp_menu_items = $menu ? wp_get_nav_menu_items( $menu ) : array(); $rest_menu = array(); diff --git a/readme.txt b/readme.txt index bdddefd..aaf9e88 100644 --- a/readme.txt +++ b/readme.txt @@ -18,7 +18,7 @@ The new routes available will be: * `/menus` list of every registered menu. * (V2 only:) `item` argument whether to fetch the menu items. Default: `false` -* `/menus/` data for a specific menu. +* `/menus/` data for a specific menu. Takes either an id, a name or a slug. Note that v1 only supports ids. * `/menu-locations` list of all registered theme locations. * `/menu-locations/` data for menu in specified menu in theme location. From 442428b656cc34f22b818c1ec30d80c17c61d04b Mon Sep 17 00:00:00 2001 From: Fahrradflucht Date: Wed, 18 May 2016 19:40:52 +0200 Subject: [PATCH 3/4] Rename missed id variable to menu to fix self-link --- includes/wp-api-menus-v2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wp-api-menus-v2.php b/includes/wp-api-menus-v2.php index 77ccc60..ef282ee 100644 --- a/includes/wp-api-menus-v2.php +++ b/includes/wp-api-menus-v2.php @@ -176,7 +176,7 @@ public function get_menu( $request ) { $rest_menu['items'] = $rest_menu_items; $rest_menu['meta']['links']['collection'] = $rest_url; - $rest_menu['meta']['links']['self'] = $rest_url . $id; + $rest_menu['meta']['links']['self'] = $rest_url . $menu; endif; From 44259df41fd21e80f971156cb0b792bb16c75ab3 Mon Sep 17 00:00:00 2001 From: Fahrradflucht Date: Wed, 18 May 2016 19:44:32 +0200 Subject: [PATCH 4/4] Fix self-link for real -.- --- includes/wp-api-menus-v2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wp-api-menus-v2.php b/includes/wp-api-menus-v2.php index ef282ee..6b6b6d0 100644 --- a/includes/wp-api-menus-v2.php +++ b/includes/wp-api-menus-v2.php @@ -176,7 +176,7 @@ public function get_menu( $request ) { $rest_menu['items'] = $rest_menu_items; $rest_menu['meta']['links']['collection'] = $rest_url; - $rest_menu['meta']['links']['self'] = $rest_url . $menu; + $rest_menu['meta']['links']['self'] = $rest_url . abs( $menu['term_id'] ); endif;