Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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:

array(
    '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.

share|improve this question
    
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. –  Chip Bennett Oct 18 '13 at 21:57
add comment

1 Answer

up vote 0 down vote accepted

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' );
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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