Overriding wp_nav_menu default arguments

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:

Read More
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.

Related posts

1 comment

  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' );
    

Comments are closed.