1

I am trying to export the essence of my wordpress site's menu in json notation.

I want to extract some details like id, type, name, sub-item and want to construct a Json object like below.

Item -

{
  id: 'wp entity id',
  name: 'name of the category|taxonomy|post|page',
  type: 'post|category|page',
  children: [array of Items]
}

where,

  • 'children': here represents sub-items
  • 'type': this represents type of item, ie., either a post link, page link, category link, custom link.
  • 'id': if item is a category link, id will be category id.
  • 'name': name of the category, post, page.

I have spent hours, but couldn't figure out a way to achieve this, kindly shed some light. Thanks.

Edit: Example of what I am trying to achieve, Suppose I have a menu like below,

-0-------1--------2-------3+- level/depth
 |
 |\___ Lobby
 |
 |\___ Projects
 |       |\___ Project A
 |       |       |\___ Review
 |       |       |\___ Comments
 |       |       \____ Download
 |       \____ Project B
 |               |\___ Review
 |               |\___ Comments
 |               \____ Download
 |\___ Blog
 |
 \____ About
         |\___ Legal
         \____ Contact

I want to represent this menu as an object.

{
    {
      id: '1',
      name: 'lobby',
      type: 'page',
      children: []
    },
    {
      id: '12',
      name: 'Projects',
      type: 'category',
      children: [{
                   id: '12',
                   name: 'Project A',
                   type: 'category',
                   children: [ ... ]
                }]
    },
  ...
  ...
    {
      id: '15',
      name: 'blog',
      type: 'page',
      children: []
    },

  ...

}
5
  • 1
    I'm sorry, I still do not understand what you're trying to achieve in the context of WordPress. Are you trying to create a menu that generates children? Does Menus in the Admin panel not suffice or a WP_Nav_Walker?
    – Howdy_McGee
    Oct 16, 2014 at 20:41
  • @Howdy_McGee I am trying to export the essence of my wordpress site's menu in json notation. Oct 16, 2014 at 20:48
  • Ok, that's a pretty important portion of this question. You may want to add this toward the top so responders know what to aim for.
    – Howdy_McGee
    Oct 16, 2014 at 20:49
  • How can I go though each of the wordpress menu item and take what I want and construct my object? Oct 16, 2014 at 20:49
  • 1
    I don't have the time to cook up the code but I'd consider using a custom walker to spit out your code-- something like this one: wordpress.stackexchange.com/a/72777/21376
    – s_ha_dum
    Oct 16, 2014 at 21:41

1 Answer 1

2

Found a solution, modified it to suit my needs,

Menu Item class:

class Menu_Item{
    private $object;
    private $object_id;
    private $link_name;
    private $link_value;

    public function __construct($object, $object_id, $linkname, $linkvalue){
      $this->object_id = $object_id;
      $this->object = $object;
      $this->link_name = $linkname;
      $this->link_value = $linkvalue;
    }

    public function get_link_name(){
      return $this->link_name;
    }

    public function get_object_id(){
      return $this->object_id;
    }

    public function get_link_value(){
      return $this->link_value;
    }

    public function get_object(){
      return $this->object;
    }
}

JSON generator:

$menu_name = 'main-menu'; //menu name slug
$menu_json_data_string = '{';

if ($menu_name) {
  $menu = wp_get_nav_menu_object( $menu_name );

  $menu_items = wp_get_nav_menu_items($menu->term_id);

  //initialize two menu item arrays
  $main_menu_item_array = array();
  $sub_menu_item_array = array();//defined as 2d array
  //define two menu item arrays first
  for($i=0;$i<count($menu_items);$i+=1){
    $current_menu_item_obj = $menu_items[$i];

    if($current_menu_item_obj->menu_item_parent == "0"){ //main menu item found
      //define a new menu_item object
      $menu_item_obj = new Menu_Item($current_menu_item_obj->object, $current_menu_item_obj->object_id, $current_menu_item_obj->title, $current_menu_item_obj->url);
      $main_menu_item_array[$current_menu_item_obj->ID] = $menu_item_obj;
    }else{ //sub menu found
      $menu_item_obj = new Menu_Item($current_menu_item_obj->object, $current_menu_item_obj->object_id, $current_menu_item_obj->title, $current_menu_item_obj->url);
      $sub_menu_item_array[$current_menu_item_obj->menu_item_parent][] = $menu_item_obj;
    }
  }

  $menu_item_json_array = array();
  foreach($main_menu_item_array as $each_main_menu_key=>$each_main_menu_item){
    $each_menu_item_link_name = $each_main_menu_item->get_link_name();
    $each_menu_item_link_value = $each_main_menu_item->get_link_value();
    $each_menu_item_object_id = $each_main_menu_item->get_object_id();
    $each_menu_item_slug = strtolower(str_replace(" ", "_", $each_menu_item_link_name));
    $obj = $each_main_menu_item->get_object();
    $type = ($obj=='meta_category')?'meta':'main';
    $each_menu_item_string = '"'.$each_menu_item_slug.'":{"id": "'.$each_menu_item_object_id.'", "type": "'.$type.'", "url":"'.$each_menu_item_link_value.'","name":"'.$each_menu_item_link_name.'"';

    if(array_key_exists($each_main_menu_key, $sub_menu_item_array)){ //has sub menu item
      //count submenu items
      $count_sub_menu_item = count($sub_menu_item_array[$each_main_menu_key]);
      //put each sub menu item into an array
      $submenu_item_list_main_string = ',"children": [';
      $submenu_item_list_array = array();
      foreach($sub_menu_item_array[$each_main_menu_key] as $each_sub_menu_item){
        $obj = $each_sub_menu_item->get_object();
        $type = ($obj=='meta_category')?'meta':'main';
        $each_sub_menu_item_string = '{"id": "'.$each_sub_menu_item->get_object_id().'", "type": "'.$type.'", "url":"'.$each_sub_menu_item->get_link_value().'", "name":"'.$each_sub_menu_item->get_link_name().'"}';
        $submenu_item_list_array[] = $each_sub_menu_item_string;
      }
      $submenu_item_list_string = implode(",", $submenu_item_list_array);
      $submenu_item_list_main_string .= $submenu_item_list_string;
      $submenu_item_list_main_string .= ']';
      $each_menu_item_string .= $submenu_item_list_main_string;
    }
    $each_menu_item_string .= '}';
    $menu_item_json_array[] = $each_menu_item_string;
  }
  $menu_item_json_string = implode(",", $menu_item_json_array);
}

$menu_json_data_string .= $menu_item_json_string;
$menu_json_data_string .= '}';

echo $menu_json_data_string;

Ref: http://simple2kx.com/wordpress-create-json-data-page-to-load-menu-items/

2
  • How could you get one more level? Grandchildren? Dec 6, 2016 at 5:06
  • @TJSherrill Now there is a plugin which does this, wordpress.org/plugins/wp-api-menus If you want to modify the above code itself, try accessing the grandchildren inside nested foreach. Dec 6, 2016 at 8:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.