1

I'm using a function in a custom theme which auto-populates the navigation with all the child pages of each parent. I found the code on this site

This works well but the only thing this function doesn't do for me is order the pages with the order set in the Pages section in Wordpress. I think I need to use something like 'sort_column=menu_order&title_li=&child_of=' somewhere in the following code, but can't for the life of me work out where?

/**
* auto_child_page_menu
* 
* class to add top level page menu items all child pages on the fly
* @author Ohad Raz <[email protected]>
*/
class auto_child_page_menu
{
    /**
     * class constructor
     * @author Ohad Raz <[email protected]>
     * @param   array $args 
     * @return  void
     */
    function __construct($args = array()){
        add_filter('wp_nav_menu_objects',array($this,'on_the_fly'));
    }
    /**
     * the magic function that adds the child pages
     * @author Ohad Raz <[email protected]>
     * @param  array $items 
     * @return array 
     */
    function on_the_fly($items) {
        global $post;
        $tmp = array();
        foreach ($items as $key => $i) {
            $tmp[] = $i;
            //if not page move on
            if ($i->object != 'page'){
                continue;
            }
            $page = get_post($i->object_id);
            //if not parent page move on
            if (!isset($page->post_parent) || $page->post_parent != 0) {
                continue;
            }
            $children = get_pages( array('child_of' => $i->object_id) );
            foreach ((array)$children as $c) {
                //set parent menu
                $c->menu_item_parent      = $i->ID;
                $c->object_id             = $c->ID;
                $c->object                = 'page';
                $c->type                  = 'post_type';
                $c->type_label            = 'Page';
                $c->url                   = get_permalink( $c->ID);
                $c->title                 = $c->post_title;
                $c->target                = '';
                $c->attr_title            = '';
                $c->description           = '';
                $c->classes               = array('','menu-item','menu-item-type-post_type','menu-item-object-page');
                $c->xfn                   = '';
                $c->current               = ($post->ID == $c->ID)? true: false;
                $c->current_item_ancestor = ($post->ID == $c->post_parent)? true: false; //probbably not right
                $c->current_item_parent   = ($post->ID == $c->post_parent)? true: false;
                $tmp[] = $c;
            }
        }
        return $tmp;
    }
}
new auto_child_page_menu();

2 Answers 2

1

I eventually found the fix for anyone who has the same issue:

  /**
  * auto_child_page_menu
  * 
  * class to add top level page menu items all child pages on the fly
  * @author Ohad Raz <[email protected]>
  */
  class auto_child_page_menu
  {
      /**
       * class constructor
       * @author Ohad Raz <[email protected]>
       * @param   array $args 
       * @return  void
       */
      function __construct($args = array()){
          add_filter('wp_nav_menu_objects',array($this,'on_the_fly'));
      }
      /**
       * the magic function that adds the child pages
       * @author Ohad Raz <[email protected]>
       * @param  array $items 
       * @return array 
       */
      function on_the_fly($items) {
          global $post;
          $tmp = array();
          foreach ($items as $key => $i) {
              $tmp[] = $i;
              //if not page move on
              if ($i->object != 'page'){
                  continue;
              }
              $page = get_post($i->object_id);
              //if not parent page move on
              if (!isset($page->post_parent) || $page->post_parent != 0) {
                  continue;
              }
              $children = get_pages( array('child_of' => $i->object_id, 'sort_column' => 'menu_order') );
              foreach ((array)$children as $c) {
                  //set parent menu           
                  $c->menu_item_parent      = $i->ID;
                  $c->object_id             = $c->ID;
                  $c->object                = 'page';
                  $c->type                  = 'post_type';
                  $c->type_label            = 'Page';
                  $c->url                   = get_permalink( $c->ID);
                  $c->title                 = $c->post_title;
                  $c->target                = '';
                  $c->attr_title            = '';
                  $c->description           = '';
                  $c->classes               = array('','menu-item','menu-item-type-post_type','menu-item-object-page');
                  $c->xfn                   = '';
                  $c->current               = ($post->ID == $c->ID)? true: false;
                  $c->current_item_ancestor = ($post->ID == $c->post_parent)? true: false; //probbably not right
                  $c->current_item_parent   = ($post->ID == $c->post_parent)? true: false;
                  $tmp[] = $c;
              }

          }
          return $tmp;
      }
  }
  new auto_child_page_menu();
1
  • This is exactly what I was looking for, thanks @Acevandermeer
    – Ben
    Mar 8, 2018 at 0:32
0

$items which are passed to this function are already sorted (see here). So you have to order them once again, by yourself, before return $tmp;

1
  • That's the bit I am struggling with Aug 4, 2016 at 12:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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