WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] wp_nav_menu to $string (7 posts)

  1. Peter_L
    Member
    Posted 1 year ago #

    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.

  2. Shaun Scovil
    Member
    Posted 1 year ago #

    The performance boost you would get from this seems minimal. That said, you could add something like this to your functions.php file:

    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.

  3. Shaun Scovil
    Member
    Posted 1 year ago #

    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 in footer.php, it would have worked.

    But don't do that. :-)

  4. Peter_L
    Member
    Posted 1 year ago #

    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.

  5. Shaun Scovil
    Member
    Posted 1 year ago #

    There are many reasons not to use a global (here are a few), but in particular:

    1. Defining a global from within a template like menu.php and then using it in footer.php creates an unnecessary dependency;
    2. Any WordPress plugin could potentially overwrite the value of your global variable, if it used the same one;
    3. 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.php file and, instead of calling wp_nav_menu() in your templates, call get_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.

  6. Shaun Scovil
    Member
    Posted 1 year ago #

    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.

  7. Peter_L
    Member
    Posted 1 year ago #

    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.

Topic Closed

This topic has been closed to new replies.

About this Topic