Arrange Combined List of Pages and Categories

I’m using the code below to display both top-level pages and categories in my menu. (If this is the incorrect way to do so, please let me know). I would like to arrange the items alphabetically. The problem being that if I add the argument to each set of parentheses, I end up with two separate lists arranged alphabetically – I would like to combine the items in each list and arrange alphabetically from there. I’m not sure where I go from here and would appreciate any help!

<?php wp_list_pages('title_li&depth=1'); wp_list_categories('title_li&depth=1'); ?>

Related posts

1 comment

  1. Problem is that functions you are using output html as string, so it’s hard to order them. Is possible, maybe using an html parser, but there are some simpler alternatives.

    First is surely using the core menu features, but I know that is not possible using it from code if a menu is not created in the backend, and if you are looking a function that run without any configuration, that can’t be the solution.

    Another approach is to use functions that retrieves pages and category, merge them, order alphabetically and finally generate the html output.

    It’s easiers than it can seems, you need only a function:

    function page_cat_menu( $echo = 1 ) {
      // get an array of both top level pages and categories
      $items = array_merge( get_pages('parent=0'), get_categories('parent=0') );
      if ( ! empty($items) ) {
        $format = '<li><a href="%s">%s</a></li>'; // the format for item html
        $menu = array();
        // loop trought items to get html and set a key fo later ordering
        foreach ( $items as $item ) {
          if ( isset($item->term_id) ) { // is a category
            $key = esc_html($item->name);
            $li = sprintf( $format, esc_url( get_category_link( $item->term_id ) ), $key );
          } else { // is a page
            $key = esc_html( apply_filters('the_title', $item->post_title) );
            $li = sprintf( $format, esc_url( get_permalink( $item->ID ) ), $key );
          }
          // populate menu array using page title or category name as key
          $menu[$key] = $li;
        }
        // sorting array menu
        ksort($menu);
        $out = implode('', $menu);
        // echo or return menu based on function argument
        if ($echo) echo $out; else return $out;
      }
    }
    

    To use it just put

    <?php page_cat_menu(); ?>
    

    to replace your actual

    <?php wp_list_pages('title_li&depth=1'); wp_list_categories('title_li&depth=1'); ?>
    

    Further reading:

Comments are closed.