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

Add route to return rendered html of a single menu #27

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
90 changes: 90 additions & 0 deletions includes/wp-api-menus-v1.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ public function register_routes( $routes ) {
$routes['/menus/(?P<id>\d+)'] = array(
array( array( $this, 'get_menu' ), WP_JSON_Server::READABLE ),
);
// a specific menu rendered in html
$routes['/menu-html/(?P<id>[a-zA-Z0-9_-]+)'] = array(
array( array( $this, 'get_menu_html' ), WP_JSON_Server::READABLE ),
);
// all registered menu locations
$routes['/menu-locations'] = array(
array( array( $this, 'get_menu_locations' ), WP_JSON_Server::READABLE ),
Expand All @@ -48,6 +52,10 @@ public function register_routes( $routes ) {
$routes['/menu-locations/(?P<location>[a-zA-Z0-9_-]+)'] = array(
array( array( $this, 'get_menu_location' ), WP_JSON_Server::READABLE ),
);
// menu for given location rendered in html
$routes['/menu-html-location/(?P<location>[a-zA-Z0-9_-]+)'] = array(
array( array( $this, 'get_menu_html_location' ), WP_JSON_Server::READABLE ),
);

return $routes;
}
Expand All @@ -62,6 +70,7 @@ public function register_routes( $routes ) {
public static function get_menus() {

$json_url = get_json_url() . '/menus/';
$json_url_base = get_json_url();
$wp_menus = wp_get_nav_menus();

$i = 0;
Expand All @@ -79,6 +88,7 @@ public static function get_menus() {

$json_menus[ $i ]['meta']['links']['collection'] = $json_url;
$json_menus[ $i ]['meta']['links']['self'] = $json_url . $menu['term_id'];
$json_menus[ $i ]['meta']['links']['self'] = $json_url_base . '/menu-html/' . $menu['term_id'];

$i ++;
endforeach;
Expand Down Expand Up @@ -126,6 +136,43 @@ public function get_menu( $id ) {
}


/**
* Get a menu rendered in html.
*
* @since 1.0.0
* @param int $id ID of the menu
* @return array Menu data
*/
public function get_menu_html( $menu_id ) {

$json_url_base = get_json_url();
$wp_menu_object = $menu_id ? wp_get_nav_menu_object( $menu_id ) : array();
$wp_menu_items = $menu_id ? wp_get_nav_menu_items( $menu_id ) : array();

$json_menu = array();

if ( $wp_menu_object ) :

$menu = (array) $wp_menu_object;
$json_menu['ID'] = abs( $menu['term_id'] );
$json_menu['name'] = $menu['name'];
$json_menu['slug'] = $menu['slug'];
$json_menu['description'] = $menu['description'];
$json_menu['count'] = abs( $menu['count'] );

ob_start();
wp_nav_menu( array( 'menu' => $menu_id ) );
$json_menu['html']=ob_get_clean();

$json_menu['meta']['links']['collection'] = $json_url_base . '/menus/';
$json_menu['meta']['links']['self'] = $json_url_base . '/menu-html/' . $menu_id;

endif;

return $json_menu;
}


/**
* Get menu locations.
*
Expand All @@ -137,6 +184,7 @@ public static function get_menu_locations() {
$locations = get_nav_menu_locations();
$registered_menus = get_registered_nav_menus();
$json_url = get_json_url() . '/menu-locations/';
$json_url_base = get_json_url();
$json_menus = array();

if ( $locations && $registered_menus ) :
Expand All @@ -152,6 +200,7 @@ public static function get_menu_locations() {
$json_menus[ $slug ]['label'] = $label;
$json_menus[ $slug ]['meta']['links']['collection'] = $json_url;
$json_menus[ $slug ]['meta']['links']['self'] = $json_url . $slug;
$json_menus[ $slug ]['meta']['links']['html'] = $json_url_base . '/menu-html-location/' . $slug;

endforeach;

Expand Down Expand Up @@ -214,6 +263,47 @@ public function get_menu_location( $location ) {
return $menu;
}

/**
* Get menu rendered in html for location.
*
* @since 1.x.0
* @param string $location The theme location menu name
* @return array The menu for the corresponding location
*/
public static function get_menu_html_location( $location ) {

$locations = get_nav_menu_locations();
if ( ! isset( $locations[ $location ] ) ) {
return array();
}

$wp_menu_object = get_term( $locations[$location], 'nav_menu' );
$json_url_base = get_json_url();

$json_menu = array();

if ( $wp_menu_object ) :

$menu = (array) $wp_menu_object;
$json_menu['ID'] = abs( $menu['term_id'] );
$json_menu['name'] = $menu['name'];
$json_menu['slug'] = $menu['slug'];
$json_menu['location_slug'] = $location;
$json_menu['description'] = $menu['description'];
$json_menu['count'] = abs( $menu['count'] );

ob_start();
wp_nav_menu( array( 'menu' => $location ) );
$json_menu['html']=ob_get_clean();

$json_menu['meta']['links']['collection'] = $json_url_base . '/menu-locations/';
$json_menu['meta']['links']['self'] = $json_url_base . '/menu-html-location/' . $location;

endif;

return $json_menu;
}


/**
* Returns all child nav_menu_items under a specific parent.
Expand Down
115 changes: 111 additions & 4 deletions includes/wp-api-menus-v2.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ public function register_routes() {
)
) );


register_rest_route( self::get_plugin_namespace(), '/menu-html/(?P<menu_id>[a-zA-Z0-9_-]+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_menu_html' ),
'args' => array(
'context' => array(
'default' => 'view',
),
),
)
) );

register_rest_route( self::get_plugin_namespace(), '/menu-locations', array(
array(
'methods' => WP_REST_Server::READABLE,
Expand All @@ -86,6 +99,13 @@ public function register_routes() {
)
) );

register_rest_route( self::get_plugin_namespace(), '/menu-html-location/(?P<location>[a-zA-Z0-9_-]+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_menu_html_location' ),
)
) );

}


Expand All @@ -98,6 +118,7 @@ public function register_routes() {
public static function get_menus() {

$rest_url = trailingslashit( get_rest_url() . self::get_plugin_namespace() . '/menus/' );
$rest_url_base = get_rest_url() . self::get_plugin_namespace();
$wp_menus = wp_get_nav_menus();

$i = 0;
Expand All @@ -115,6 +136,7 @@ public static function get_menus() {

$rest_menus[ $i ]['meta']['links']['collection'] = $rest_url;
$rest_menus[ $i ]['meta']['links']['self'] = $rest_url . $menu['term_id'];
$rest_menus[ $i ]['meta']['links']['html'] = $rest_url_base . '/menu-html/' . $menu['term_id'];

$i ++;
endforeach;
Expand All @@ -133,7 +155,7 @@ public static function get_menus() {
public function get_menu( $request ) {

$id = (int) $request['id'];
$rest_url = get_rest_url() . self::get_api_namespace() . '/menus/';
$rest_url = get_rest_url() . self::get_plugin_namespace() . '/menus/';
$wp_menu_object = $id ? wp_get_nav_menu_object( $id ) : array();
$wp_menu_items = $id ? wp_get_nav_menu_items( $id ) : array();

Expand Down Expand Up @@ -164,6 +186,44 @@ public function get_menu( $request ) {
return apply_filters( 'rest_menus_format_menu', $rest_menu );
}

/**
* Get a menu rendered in html.
*
* @since 1.x.0
* @param $request
* @return array Menu data
*/
public function get_menu_html( $request ) {

$menu_id = $request['menu_id'];
$rest_url_base = get_rest_url() . self::get_plugin_namespace();
$wp_menu_object = $menu_id ? wp_get_nav_menu_object( $menu_id) : array();
$wp_menu_items = $menu_id ? wp_get_nav_menu_items( $menu_id ) : array();

$rest_menu = array();

if ( $wp_menu_object ) :

$menu = (array) $wp_menu_object;
$rest_menu['ID'] = abs( $menu['term_id'] );
$rest_menu['name'] = $menu['name'];
$rest_menu['slug'] = $menu['slug'];
$rest_menu['description'] = $menu['description'];
$rest_menu['count'] = abs( $menu['count'] );

ob_start();
wp_nav_menu( array( 'menu' => $menu_id ) );
$rest_menu['html']=ob_get_clean();

$rest_menu['meta']['links']['collection'] = $rest_url_base . '/menus/';
$rest_menu['meta']['links']['self'] = $rest_url_base . '/menu-html/' . $menu_id;

endif;

return apply_filters( 'rest_menus_format_menu', $rest_menu );
}



/**
* Handle nested menu items.
Expand Down Expand Up @@ -227,7 +287,8 @@ public static function get_menu_locations( $request ) {

$locations = get_nav_menu_locations();
$registered_menus = get_registered_nav_menus();
$rest_url = get_rest_url() . self::get_api_namespace() . '/menu-locations/';
$rest_url = get_rest_url() . self::get_plugin_namespace() . '/menu-locations/';
$rest_url_base = get_rest_url() . self::get_plugin_namespace();
$rest_menus = array();

if ( $locations && $registered_menus ) :
Expand All @@ -243,6 +304,7 @@ public static function get_menu_locations( $request ) {
$rest_menus[ $slug ]['label'] = $label;
$rest_menus[ $slug ]['meta']['links']['collection'] = $rest_url;
$rest_menus[ $slug ]['meta']['links']['self'] = $rest_url . $slug;
$rest_menus[ $slug ]['meta']['links']['html'] = $rest_url_base . '/menu-html-location/' . $slug;

endforeach;

Expand Down Expand Up @@ -302,9 +364,9 @@ public function get_menu_location( $request ) {
if ( array_key_exists ( $item->ID , $cache ) ) {
$formatted['children'] = array_reverse ( $cache[ $item->ID ] );
}

$formatted = apply_filters( 'rest_menus_format_menu_item', $formatted );

if ( $item->menu_item_parent != 0 ) {
// Wait for parent to pick me up
if ( array_key_exists ( $item->menu_item_parent , $cache ) ) {
Expand All @@ -320,6 +382,51 @@ public function get_menu_location( $request ) {
}


/**
* Get menu rendered in html for location.
*
* @since 1.x.0
* @param $request
* @return array The menu for the corresponding location
*/
public function get_menu_html_location( $request ) {

$params = $request->get_params();
$location = $params['location'];
$locations = get_nav_menu_locations();

//Check if location exists and return empty array if it doesn't
if ( ! isset( $locations[ $location ] ) ) {
return array();
}

$rest_url_base = get_rest_url() . self::get_plugin_namespace();
$wp_menu_object = get_term( $locations[$location], 'nav_menu' );
$rest_menu = array();

if ( $wp_menu_object ) :

$menu = (array) $wp_menu_object;
$rest_menu['ID'] = abs( $menu['term_id'] );
$rest_menu['name'] = $menu['name'];
$rest_menu['slug'] = $menu['slug'];
$rest_menu['location_slug'] = $location;
$rest_menu['description'] = $menu['description'];
$rest_menu['count'] = abs( $menu['count'] );

ob_start();
wp_nav_menu( array( 'theme_location' => $location ) );
$rest_menu['html']=ob_get_clean();

$rest_menu['meta']['links']['collection'] = $rest_url_base . '/menu-locations/';
$rest_menu['meta']['links']['self'] = $rest_url_base . '/menu-html-location/' . $location;

endif;

return $rest_menu;
}


/**
* Returns all child nav_menu_items under a specific parent.
*
Expand Down
4 changes: 3 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ The new routes available will be:

* `/menus` list of every registered menu.
* `/menus/<id>` data for a specific menu.
* `/menu-html/<menu_identifier>` menu rendered in html for a specificed menu by id or slug.
* `/menu-locations` list of all registered theme locations.
* `/menu-locations/<location>` data for menu in specified menu in theme location.
* `/menu-html-location/<location>` menu rendered in html for a specified menu in theme location.

Currently, the `menu-locations/<location>` 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/<id>` 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.

Expand Down Expand Up @@ -99,4 +101,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.
API V2 only: mind lowercase `id` instead of uppercase `ID` in API responses, to match the standard for `id` used across WP REST API.