Background
As you already know, wp_nav_menu()
function takes an array $args
as argument & menu
is one of the keys to that $args
array.
The key menu
for the argument $args
is defined as:
(int|string|WP_Term) Desired menu. Accepts (matching in order) id, slug, name, menu object.
Now, if you look deep into the implementation of wp_nav_menu()
function, you’ll see that, no matter what value you provide, whether it is an int
id, a string
name, a string
slug or an object
WP_Term
, it’ll always retrieve the WP_Term
object
for the corresponding menu id | name | slug before creating the menu.
For example: if you have a menu with id 3
, name My Menu
and slug my-menu
; you can add that menu using any of the following CODE:
// with id: 3
wp_nav_menu( array(
'menu' => 3
) );
// with name: My Menu
wp_nav_menu( array(
'menu' => "My Menu"
) );
// with slug: my-menu
wp_nav_menu( array(
'menu' => "my-menu"
) );
Even if you don’t provide the menu
argument, it’ll try to get the WP_Term
object from other arguments like theme_location
.
For example: say the menu location top
was registered using register_nav_menus()
function in your theme’s functions.php
file & the menu named My Menu
was asigned to the top
location from your WP admin panel. In that case, you can get the same menu using:
wp_nav_menu( array(
'theme_location' => 'top'
) );
In each of the above cases, wp_nav_menu()
function retrieves the WP_Term
object before generating the menu. It uses the wp_get_nav_menu_object()
function to do so.
Implementation
So instead of theme_location
argument, or menu
argument as int
id or string
name | slug, you can directly provide the corresponding WP_Term object.
One way get the WP_Term
object is by using the WP_Term::get_instance()
method:
// get the WP_Term object using menu id 3
$menu_obj = WP_Term::get_instance( 3, 'nav_menu' );
You can also get the WP_Term
object with menu name | slug using get_term_by()
function:
// by menu slug
$menu_obj = get_term_by( 'slug', 'my-menu', 'nav_menu' );
// or, by menu name
$menu_obj = get_term_by( 'name', 'My Menu', 'nav_menu' );
Now that you’ve got the WP_Term
object $menu_obj
, you can use that to generate the menu:
wp_nav_menu( array(
'menu' => $menu_obj
) );
Use case:
So you know how to generate a menu using WP_Term
object as an argument to wp_nav_menu()
function. Now the question is: why will you want to use it? Apart from the fact that it’s just another option, you may want to use it because it may be a slightly faster option.
For example, if you want to use the same menu twice, once in the header & then in the footer, in that case, instead of using menu id | slug | name, you may create WP_Term
object in your template for header menu:
global $menu_obj;
$menu_obj = WP_Term::get_instance( 3, 'nav_menu' );
wp_nav_menu( array(
'menu' => $menu_obj,
'menu_id' => 'header_menu'
) );
and then simply use $menu_obj
in the footer template as well:
// global declaration is needed to access the global variable from another template
global $menu_obj;
wp_nav_menu( array(
'menu' => $menu_obj,
'menu_id' => 'footer_menu'
) );
If you look into the implementation of wp_nav_menu()
function, you’ll see that by doing it this way, you will avoid a few extra function calls in WordPress core, thus the total execution will be slightly faster.
However, please remember that using theme_location
argument or other options may be more convenient & better for maintenance. So whether or not you should use it totally depends on your own particular scenario. I just explained that you can & how, nothing more.