Skip to main content
added functionallity for theme_position and menu (slug)
Source Link
fischi
  • 7.6k
  • 2
  • 29
  • 44

Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered.

Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling wp_nav_menu directly.

function get_cached_menu( $menuargs ) {

    if ( !isset( $menuargs['menu'] ) ) {
    
        $theme_locations = get_nav_menu_locations();
        $nav_menu_selected_id = $theme_locations[$menuargs['theme_location']];
        $termslug = get_term_by( 'id', $nav_menu_selected_id, 'nav_menu' );
        $transient = 'menu_' . $menuargs['menu_id']$termslug->slug . '_transient';
        
    } else {
    
        $transient = 'menu_' . $menuargs['menu'] . '_transient';
    
    }


    if ( !get_transient( $transient ) ) { // check if the menu is already cached

        $menuargs['echo'] = '0'; // set the output to return
        $this_menu = wp_nav_menu( $menuargs ); // build the menu with the given $menuargs
        
        echo $this_menu; // output the menu for this run
        set_transient( $transient, $this_menu ); // set the transient, where the build HTML is saved
    
    } else {
    
        echo get_transient( $transient ); // just output the cached version
    
    }
    
}

In your theme, replace the wp_nav_menus with get_cached_menu. Now, everytime the menu is called, you have one Databasequery instead of the whole Menubuilding.

Menus don't change often - but you also have to hook into the wp_update_nav_menu action to delete the old transients.

Do it like this:

add_action('wp_update_nav_menu', 'my_delete_menu_transients');

function my_delete_menu_transients($nav_menu_selected_id) {

    $termslug = get_term_by( 'id', $nav_menu_selected_id, 'nav_menu' );

    $transient = 'menu_' . $nav_menu_selected_id$termslug->slug . '_transient';

    delete_transient( $transient ); 

}

The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again.

Updated Version

Thanks @helgatheviking for pointing out a mistake between slugs and IDs. I updated the functions so it works both with theme_position and menu (for a direct call of the menu).

The menus are always saved with the name of the Menu, not the position in the Theme.

Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered.

Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling wp_nav_menu directly.

function get_cached_menu( $menuargs ) {

    $transient = 'menu_' . $menuargs['menu_id'] . '_transient';

    if ( !get_transient( $transient ) ) { // check if the menu is already cached

        $menuargs['echo'] = '0'; // set the output to return
        $this_menu = wp_nav_menu( $menuargs ); // build the menu with the given $menuargs
        
        echo $this_menu; // output the menu for this run
        set_transient( $transient, $this_menu ); // set the transient, where the build HTML is saved
    
    } else {
    
        echo get_transient( $transient ); // just output the cached version
    
    }
    
}

In your theme, replace the wp_nav_menus with get_cached_menu. Now, everytime the menu is called, you have one Databasequery instead of the whole Menubuilding.

Menus don't change often - but you also have to hook into the wp_update_nav_menu action to delete the old transients.

Do it like this:

add_action('wp_update_nav_menu', 'my_delete_menu_transients');

function my_delete_menu_transients($nav_menu_selected_id) {

    $transient = 'menu_' . $nav_menu_selected_id . '_transient';

    delete_transient( $transient ); 

}

The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again.

Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered.

Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling wp_nav_menu directly.

function get_cached_menu( $menuargs ) {

    if ( !isset( $menuargs['menu'] ) ) {
    
        $theme_locations = get_nav_menu_locations();
        $nav_menu_selected_id = $theme_locations[$menuargs['theme_location']];
        $termslug = get_term_by( 'id', $nav_menu_selected_id, 'nav_menu' );
        $transient = 'menu_' . $termslug->slug . '_transient';
        
    } else {
    
        $transient = 'menu_' . $menuargs['menu'] . '_transient';
    
    }


    if ( !get_transient( $transient ) ) { // check if the menu is already cached

        $menuargs['echo'] = '0'; // set the output to return
        $this_menu = wp_nav_menu( $menuargs ); // build the menu with the given $menuargs
        echo $this_menu; // output the menu for this run
        set_transient( $transient, $this_menu ); // set the transient, where the build HTML is saved
    
    } else {
    
        echo get_transient( $transient ); // just output the cached version
    
    }
    
}

In your theme, replace the wp_nav_menus with get_cached_menu. Now, everytime the menu is called, you have one Databasequery instead of the whole Menubuilding.

Menus don't change often - but you also have to hook into the wp_update_nav_menu action to delete the old transients.

Do it like this:

add_action('wp_update_nav_menu', 'my_delete_menu_transients');

function my_delete_menu_transients($nav_menu_selected_id) {

    $termslug = get_term_by( 'id', $nav_menu_selected_id, 'nav_menu' );

    $transient = 'menu_' . $termslug->slug . '_transient';

    delete_transient( $transient ); 

}

The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again.

Updated Version

Thanks @helgatheviking for pointing out a mistake between slugs and IDs. I updated the functions so it works both with theme_position and menu (for a direct call of the menu).

The menus are always saved with the name of the Menu, not the position in the Theme.

corrected output buffer to ['echo'] = '0'
Source Link
fischi
  • 7.6k
  • 2
  • 29
  • 44

Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered.

Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling wp_nav_menu directly.

function get_cached_menu( $menuargs ) {

    $transient = 'menu_' . $menuargs['menu_id'] . '_transient';

    if ( !get_transient( $transient ) ) { // check if the menu is already cached
   
  
       $menuargs['echo'] = ob_start();'0'; // do notset directlythe output theto menureturn
        $this_menu = wp_nav_menu( $menuargs ); // build the menu with the given $menuargs
        $this_menu = ob_get_contents(); // get the HTML-code for the menu
        ob_end_clean();
        echo $this_menu; // output the menu for this run
        set_transient( $transient, $this_menu ); // set the transient, where the build HTML is saved
    
    } else {
    
        echo get_transient( $transient ); // just output the cached version
    
    }
    
}

In your theme, replace the wp_nav_menus with get_cached_menu. Now, everytime the menu is called, you have one Databasequery instead of the whole Menubuilding.

Menus don't change often - but you also have to hook into the wp_update_nav_menu action to delete the old transients.

Do it like this:

add_action('wp_update_nav_menu', 'my_delete_menu_transients');

function my_delete_menu_transients($nav_menu_selected_id) {

    $transient = 'menu_' . $nav_menu_selected_id . '_transient';

    delete_transient( $transient ); 

}

The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again.

Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered.

Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling wp_nav_menu directly.

function get_cached_menu( $menuargs ) {

    $transient = 'menu_' . $menuargs['menu_id'] . '_transient';

    if ( !get_transient( $transient ) ) { // check if the menu is already cached
    
         ob_start(); // do not directly output the menu
        wp_nav_menu( $menuargs ); // build the menu with the given $menuargs
        $this_menu = ob_get_contents(); // get the HTML-code for the menu
        ob_end_clean();
        echo $this_menu; // output the menu for this run
        set_transient( $transient, $this_menu ); // set the transient, where the build HTML is saved
    
    } else {
    
        echo get_transient( $transient ); // just output the cached version
    
    }
    
}

In your theme, replace the wp_nav_menus with get_cached_menu. Now, everytime the menu is called, you have one Databasequery instead of the whole Menubuilding.

Menus don't change often - but you also have to hook into the wp_update_nav_menu action to delete the old transients.

Do it like this:

add_action('wp_update_nav_menu', 'my_delete_menu_transients');

function my_delete_menu_transients($nav_menu_selected_id) {

    $transient = 'menu_' . $nav_menu_selected_id . '_transient';

    delete_transient( $transient ); 

}

The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again.

Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered.

Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling wp_nav_menu directly.

function get_cached_menu( $menuargs ) {

    $transient = 'menu_' . $menuargs['menu_id'] . '_transient';

    if ( !get_transient( $transient ) ) { // check if the menu is already cached
 
        $menuargs['echo'] = '0'; // set the output to return
        $this_menu = wp_nav_menu( $menuargs ); // build the menu with the given $menuargs
        
        echo $this_menu; // output the menu for this run
        set_transient( $transient, $this_menu ); // set the transient, where the build HTML is saved
    
    } else {
    
        echo get_transient( $transient ); // just output the cached version
    
    }
    
}

In your theme, replace the wp_nav_menus with get_cached_menu. Now, everytime the menu is called, you have one Databasequery instead of the whole Menubuilding.

Menus don't change often - but you also have to hook into the wp_update_nav_menu action to delete the old transients.

Do it like this:

add_action('wp_update_nav_menu', 'my_delete_menu_transients');

function my_delete_menu_transients($nav_menu_selected_id) {

    $transient = 'menu_' . $nav_menu_selected_id . '_transient';

    delete_transient( $transient ); 

}

The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again.

Source Link
fischi
  • 7.6k
  • 2
  • 29
  • 44

Caching the WordPress Menu also gives you a performance boost. Especially if you have a lot of Pages or a giant Menu Structure, this should be considered.

Do it in 2 easy steps. At first, create a function that gets or creates the menu, instead of calling wp_nav_menu directly.

function get_cached_menu( $menuargs ) {

    $transient = 'menu_' . $menuargs['menu_id'] . '_transient';

    if ( !get_transient( $transient ) ) { // check if the menu is already cached
    
        ob_start(); // do not directly output the menu
        wp_nav_menu( $menuargs ); // build the menu with the given $menuargs
        $this_menu = ob_get_contents(); // get the HTML-code for the menu
        ob_end_clean();
        echo $this_menu; // output the menu for this run
        set_transient( $transient, $this_menu ); // set the transient, where the build HTML is saved
    
    } else {
    
        echo get_transient( $transient ); // just output the cached version
    
    }
    
}

In your theme, replace the wp_nav_menus with get_cached_menu. Now, everytime the menu is called, you have one Databasequery instead of the whole Menubuilding.

Menus don't change often - but you also have to hook into the wp_update_nav_menu action to delete the old transients.

Do it like this:

add_action('wp_update_nav_menu', 'my_delete_menu_transients');

function my_delete_menu_transients($nav_menu_selected_id) {

    $transient = 'menu_' . $nav_menu_selected_id . '_transient';

    delete_transient( $transient ); 

}

The Menu will be generated the next time the page is called - and use the cached version until someone updates the menu again.