I'm trying to override WordPress' default arguments for the wp_nav_menu function, while still allowing programmers the ability to pass their own arguments. The wp_nav_menu_args filter seems like the perfect solution, but their is a catch. The function would look like this:

function my_nav_menu_args( $args = '' ) {
    // my code here
    return $args;
add_filter( 'wp_nav_menu_args', 'my_nav_menu_args' );

The catch is that $args contains the function call's arguments or WordPress' default arguments. Therefore, if wp_nav_menu is call without any arguments $args looks like this:

    'menu' => '',
    'container' => 'div',
    'container_class' => '',
    'container_id' => '',
    'menu_class' => 'menu',
    'menu_id' => '',
    'echo' => true,
    'fallback_cb' => 'wp_page_menu',
    'before' => '',
    'after' => '',
    'link_before' => '',
    'link_after' => '',
    'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
    'depth' => 0,
    'walker' => '',
    'theme_location' => ''

This means I can't simply check if a particular argument is empty in order to know where or not to apply my own defaults. There is also the wp_parse_args function which is used to merge arguments with your own defaults. However, this doesn't work in this case:

$defaults = array(
    'container' => false

$args = wp_parse_args( $args, $defaults );

$args['container'] will still be WordPress' default 'div' and not false.

I know that $args['container'] = false will set the argument properly, but then any function calls that set the container argument will be ignored.

The only solution I can think over is to check each argument against WordPress' defaults arguments hard coded in. Checking the container argument would look like this:

function my_nav_menu_args( $args = '' ) {
    if ( $args['container'] == 'div' ) {
        $args['container'] = false;
    return $args;
add_filter( 'wp_nav_menu_args', 'my_nav_menu_args' );

It would work, but I'm thinking there has to be a simpler solution that won't require the defaults hard coded in.

  • Side note: wp_nav_menu() should never be called without any arguments. At a minimum, it should always be passed at least the 'theme_location' parameter. Commented Oct 18, 2013 at 21:57

1 Answer 1


If you want the options to be extensible by developers, just add a custom filter to the output:

wp_nav_menu( apply_filters( 'wpse119371_nav_menu_args', array(
    'theme_location' => 'primary',
    'container' => false,
    // etc.
) ) );

Then, a developer merely has to add a filter callback:

function wpse119371_filter_nav_menu_args( $args ) {
    // Modify $args
    $args['container'] => 'div';
    // etc.

    // Return
    return $args;
add_filter( 'wpse119371_nav_menu_args', 'wpse119371_filter_nav_menu_args' );

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.