wp_nav_menu to $string
-
I am developing a site which has the same menu inside the header and the footer. The menu gets built by Appearance → Menus and then called using wp_nav_menu.
However, since I just need the exact same html in both the header and footer I wanted to store the wp_nav_menu inside a variable and then echo it out. ( I thought this would make my site run faster ) So I took a template part: menu.php and put this code inside it:$primary_menu_defaults = array( 'theme_location' => 'primair', 'container' => false, 'menu_class' => false, 'echo' => 0 ); $primary_menu = wp_nav_menu( $primary_menu_defaults );Then, in both menu.php and footer.php I just do this:
<?php echo $primary_menu; ?>
This works in the menu.php but not in the footer.php. So here’s my question, how can I get echo $primary_menu to actually echo inside the footer.php?
To be clear, the front end part that’s controlled by footer.php doesn’t do anything. No code gets echoed but no error is thrown either.
-
The performance boost you would get from this seems minimal. That said, you could add something like this to your
functions.phpfile:function get_primary_menu() { $menu = get_transient( 'sms06202013_primary_menu' ); if ( false === $menu ) { $primary_menu_defaults = array( 'theme_location' => 'primair', 'container' => false, 'menu_class' => false, 'echo' => 0 ); $menu = wp_nav_menu( $primary_menu_defaults ); // Store the menu in a transient for 24 hours set_transient( 'sms06202013_primary_menu', $menu, 60 * 60 * 24 ); } return $menu; }That stores the menu string in the database as a transient. Then you can just call
get_primary_menu()from your page templates.Btw, the problem was with the scope of your variable. If you called
global $primary_menu;before the original code you posted AND before you tried to use it infooter.php, it would have worked.But don’t do that. 🙂
Thank you for the answer.
I suspected it was the scope. But why shouldn’t I use a global?
I’m not going to use the transient, seems overly complex. I’ll just call wp_nav_menu twice, if it won’t affect performance. It just bugged me to do the same thing twice.
There are many reasons not to use a global (here are a few), but in particular:
- Defining a global from within a template like
menu.phpand then using it infooter.phpcreates an unnecessary dependency; - Any WordPress plugin could potentially overwrite the value of your global variable, if it used the same one;
- It can make troubleshooting problems more difficult later on.
That’s not to say that globals are all bad. In fact, WordPress uses several global variables in core. But it is bad practice to define a global in a page template.
All that aside, the function I gave you above will work as is without any fuss. Just pop it into your
functions.phpfile and, instead of callingwp_nav_menu()in your templates, callget_primary_menu().The nice thing about this is that it will store the menu for up to 24 hours, apposed to a global variable that would get redefined on every page load.
The only drawback to using the transient method is that, if you change your menu, you would need to clear the transient that has been cached (or wait 24 hours!).
To handle that situation, you could add this to your
functions.php:delete_transient( 'sms06202013_primary_menu' );That command would simply delete the transient data on the next page load. Then you could comment it out (or remove it) and you would see your updated menu.
Or, you could change the line:
set_transient( 'sms06202013_primary_menu', $menu, 60 * 60 * 24 );…to a shorter duration, like:
set_transient( 'sms06202013_primary_menu', $menu, 60 * 5 );…which would only store the menu for up to 5 minutes, instead of 24 hours.
Thanks for taking your time to answer. Still not going to use the transient here but it’s in the back of my head in case I need it.
- Defining a global from within a template like
The topic ‘wp_nav_menu to $string’ is closed to new replies.