Custom WordPress Menu

Preface

The following discussion assumes you like to build blank WordPress themes. If you’re using a child theme then this discussion may not be your cup of tea; unless you like to customize stuff and if so, please read on.

In the beginning…

I’d like to take a stroll with you down wp_nav_menu lane. What’s wp_nav_menu? Well, in a nutshell it’s a way to trigger WordPress’ custom menu functionality. You can see this option from your WordPress admin dashboard under Appearance > Menus.

The Menu

The custom menu screen accessed from your WordPress Dashboard. You’ll also notice I inserted some HTML in there just for good measure.
View the larger image in another window

By definition this functionality allows WordPress themes to have customized navigation. Easy peezy right? Let’s take a look under the bonnet now, shall we?

functions.php

In order to trigger the custom menu functionality we’ll need to setup register_nav_menus() from within your theme’s functions.php file.

/*-----------------------------------------------------------------------[ theme setup function ] */
//if ! wpflex_setup
if ( ! function_exists( 'wpflex_setup' ) ) :

//wpflex_setup
function wpflex_setup() {

    /*-----------------------------------[ register the custom nav menus ] */

    register_nav_menus( array(
        'primary' => 'Primary Menu'
    ));

}

endif;
Using our WP–Flex
functions.php file. register_nav_menus() used in our example above activates WordPress’ custom menu option

Authors are also allowed to setup additional custom menus using another associative array value depicted in the example below.

/*-----------------------------------[ register the custom nav menus ] */
register_nav_menus( array(
    'primary'   => 'Primary Menu',
    'secondary' => 'Secondary Menu'
));

header.php

<!-- http://codex.wordpress.org/Function_Reference/wp_nav_menu -->
    <!-- http://codex.wordpress.org/Navigation_Menus -->
    <nav role="navigation">
        <?php
            // Custom Nav Call
            function custom_nav() {
                if ( function_exists( 'wp_nav_menu' ) ) :
                    wp_nav_menu( array(
                        'theme_location'  => 'primary',
                        'menu'            => '',
                        'container'       => 'menu-container',
                        'container_class' => 'menu-{menu slug}-container',
                        'container_id'    => '',
                        'menu_class'      => 'menu',
                        'menu_id'         => '',
                        'echo'            => true,
                        'fallback_cb'     => 'wp_nav_fallback',
                        'before'          => '',
                        'after'           => '',
                        'link_before'     => '',
                        'link_after'      => '',
                        'items_wrap'      => '<ul id="%1$s" class="%2$s">%3$s</ul>',
                        'depth'           => 0,
                        'walker'          => ''
                    ));
                else :
                    nav_fallback();
                endif;
            }

            // Navigation Fallback Call
            function wp_nav_fallback() {
                //wp_list_pages arguments as an array
                $nav_wpflex = array(
                    'depth'         => 2,
                    'show_date'     => '',
                    'date_format'   => get_option( 'date_format' ),
                    'child_of'      => 0,
                    'exclude'       => '',
                    'include'       => '',
                    'title_li'      => '',
                    'echo'          => 1,
                    'authors'       => '',
                    'sort_column'   => 'menu_order',
                    'link_before'   => '',
                    'link_after'    => '',
                    'walker'        => ''
                );?>

                <ol>
                    <?php
                        //begin wp_list_pages loop
                        if( wp_list_pages( $nav_wpflex ) ) : while ( wp_list_pages( $nav_wpflex ) ) :
                            //list items from the array above
                            wp_list_pages( $nav_wpflex );
                        endwhile;
                        endif;
                    ?>
                </ol>
        <?php } // end wp_nav_fallback

            // custom_nav call
            custom_nav();
        ?>
    </nav>
The WordPress header.php file found as part of its core functionality.

So…What’s going on here? Let’s start from the beginning. First, we’re setting up the custom navigation function which we’ve properly titled “custom_nav().” Inside custom_nav() we’re also checking to make sure the function exists and if so, run the code inside wp_nav_menu(). From within wp_nav_menu() we can do all kinds of goodies like replacing the values provided for the wp-nav_menu() array. If we use the custom menu functionality then the following classes are generated on your navigation container and list items. Using the example from above and the live demo of WP–Flex we’ll get the following output.

<nav role="navigation">
    <ul id="menu-primary" class="menu">
        <li id="menu-item-765" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-765"><a href="http://grayghostvisuals.com/wpflex/about-2/">About The Tests</a>
            <ul class="sub-menu">
                <li id="menu-item-766" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-766"><a href="http://grayghostvisuals.com/wpflex/level-1-2/">Level 1</a>
                    <ul class="sub-menu">
                        <li id="menu-item-767" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-767"><a href="http://grayghostvisuals.com/wpflex/level-1-2/level-2/">Level 2</a>
                            <ul class="sub-menu">
                                <li id="menu-item-768" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-768"><a href="http://grayghostvisuals.com/wpflex/level-1-2/level-2/level-3/">Level 3</a></li>
                            </ul>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>

        <li id="menu-item-769" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-769">
            <a href="http://grayghostvisuals.com/wpflex/page-with-comments-disabled-2/">Page with comments disabled</a>
        </li>

        <li id="menu-item-770" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-770">
            <a href="http://grayghostvisuals.com/wpflex/page-with-comments-2/">Page with comments</a>
        </li>

        <li id="menu-item-771" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-771">
            <a href="http://grayghostvisuals.com/wpflex/lorem-ipsum-2/">Lorem Ipsum</a>
        </li>

        <li id="menu-item-772" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-772"><a href="http://grayghostvisuals.com/wpflex/parent-page-2/">Parent page</a>
            <ul class="sub-menu">
                <li id="menu-item-773" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-773"><a href="http://grayghostvisuals.com/wpflex/parent-page-2/child-page-2/">Child page 2</a>
                    <ul class="sub-menu">
                        <li id="menu-item-774" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-774"><a href="http://grayghostvisuals.com/wpflex/parent-page-2/child-page-1/">Child page 1</a></li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>
</nav>

That output is crazy right? You should also note that the name you give the menu from your dashboard is the ID of the navigation’s ul. WordPress also gives us something more amazing like sub–menu classes on nested page links just for you deep navigation lovers.

Fallback

Some of you smarty pants may have noticed that we’re providing a fallback in case the custom menu is not desired by the author. As per our example, our fallback uses wp_list_pages() to catch our graceful tumble from the edge.

<nav role="navigation">
    <ol>
        <li class="page_item page-item-675"><a href="http://grayghostvisuals.com/wpflex/?page_id=675">About The Tests</a></li>
        <li class="page_item page-item-501"><a href="http://grayghostvisuals.com/wpflex/?page_id=501">Clearing Floats</a></li>
        <li class="page_item page-item-174"><a href="http://grayghostvisuals.com/wpflex/?page_id=174">Level 1</a>
            <ul class="children">
            <li class="page_item page-item-173"><a href="http://grayghostvisuals.com/wpflex/?page_id=173">Level 2</a>
                <ul class="children">
                <li class="page_item page-item-172"><a href="http://grayghostvisuals.com/wpflex/?page_id=172">Level 3</a></li>
                </ul>
                </li>
            </ul>
        </li>
        <li class="page_item page-item-146"><a href="http://grayghostvisuals.com/wpflex/?page_id=146">Lorem Ipsum</a></li>
        <li class="page_item page-item-155"><a href="http://grayghostvisuals.com/wpflex/?page_id=155">Page with comments</a></li>
        <li class="page_item page-item-156"><a href="http://grayghostvisuals.com/wpflex/?page_id=156">Page with comments disabled</a></li>
        <li class="page_item page-item-143"><a href="http://grayghostvisuals.com/wpflex/?page_id=143">Parent page</a>
            <ul class="children">
            <li class="page_item page-item-144"><a href="http://grayghostvisuals.com/wpflex/?page_id=144">Child page 1</a></li>
            <li class="page_item page-item-145"><a href="http://grayghostvisuals.com/wpflex/?page_id=145">Child page 2</a></li>
            </ul>
        </li>
        <li class="page_item page-item-2"><a href="http://grayghostvisuals.com/wpflex/?page_id=2">Sample Page</a></li>
    </ol>
</nav>

In Conclusion

If you have questions or are unsure about any of the examples from above please feel free to leave a comment so that others may benefit from your question(s). Now go forth and be WordPress-y.

Hold it right there links!

GrayGhost

Web Development & Design, Technical Writing, Interaction Design, Open Source Maker & Contributor. Helping Create A Better Web. http://grayghostvisuals.com.
  1. Hello World!

    I need to handle menu items one-by-one, so please give me advice about how to get menu items by id or anything else one-by-one.

    I am looking forward to Your reply.

    Bye,
    András

    1. I’m a bit confused with your scenario still. Are you trying to use a custom menu?

Leave a Reply

Your email address will not be published. Required fields are marked *

show formatting examples
<pre class="language-[markup | sass | css | php | javascript | ruby | clike | bash]"><code>
…code example goes here…
</code></pre>

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Comment Preview

  1. John Doe shouted this comment preview:
    2012/09/09