If you are building a theme in WordPress and you want to automatically generate nav menus on theme activation, here is how you can do it:
We need two functions to make it easier for us to auto generate nav menus and menu items:
Menu Item Generator Function:
The function above will automatically generate a “Custom Link” that points to the page we specify on the $url parameter.
Menu Generator Function:
Register 2 Navigations: primary and secondary
Register your menu and menu items:
In your header.php, use the following code to output the menus for logged-in users or visitors only:
If you notice we added a fallback, which is the function that will be called if our menu (primary / secondary) is not existing. Add this fallback function to your functions.php:
The function above will output only 5 menu items. – To change this, set “number” to the number of menu items you want to output.
We need two functions to make it easier for us to auto generate nav menus and menu items:
Menu Item Generator Function:
function generate_site_nav_menu_item( $term_id, $title, $url ) {
wp_update_nav_menu_item($term_id, 0, array(
'menu-item-title' => sprintf( __('%s', 'text_domain'), $title ),
'menu-item-url' => home_url( '/' . $url ),
'menu-item-status' => 'publish'
) );
}
The function above will automatically generate a “Custom Link” that points to the page we specify on the $url parameter.
Menu Generator Function:
function generate_site_nav_menu( $menu_name, $menu_items_array, $location_target ) {
$menu_primary = $menu_name;
wp_create_nav_menu( $menu_primary );
$menu_primary_obj = get_term_by( 'name', $menu_primary, 'nav_menu' );
foreach( $menu_items_array as $page_name => $page_location ){
generate_site_nav_menu_item( $menu_primary_obj->term_id, $page_name, $page_location );
}
$locations_primary_arr = get_theme_mod( 'nav_menu_locations' );
$locations_primary_arr[$location_target] = $menu_primary_obj->term_id;
set_theme_mod( 'nav_menu_locations', $locations_primary_arr );
update_option( 'menu_check', true );
}
Usage
Example let’s create two Header menus, menu 1 will be shown to Logged in users and menu 2 will be shown to visitors onlyRegister 2 Navigations: primary and secondary
function my_after_setup_theme() {
/**
* Register Navigations
*/
register_nav_menus( array(
'primary' => __('Primary Navigation', 'text_domain'),
'secondary' => __('Secondary Navigation', 'text_domain')
) );
}
add_action( 'after_setup_theme', 'my_after_setup_theme') );
Register your menu and menu items:
/**
* Runs when user switches to your custom theme
*
*/
function my_after_switch_theme() {
/**
* Setup the site navigation
*/
$run_menu_maker_once = get_option('menu_check');
if ( ! $run_menu_maker_once ){
/**
* Setup Navigation for : Header Menu - Logged In
*/
$primary_menu_items = array(
'Listings' => 'listings',
'Submit Ad' => 'submit-ad',
'Messages' => 'messages',
'Account' => 'account',
'Logout' => 'account?action=logout' // You need to setup your logout url using wp_logout()
);
cvf_generate_site_nav_menu( 'Header Menu - Logged In', $primary_menu_items, 'primary' );
/**
* Setup Navigation for : Header Menu - Logged Out
*/
$secondary_menu_items = array(
'Listings' => 'listings',
'Submit Ad' => 'submit-ad',
'Register' => 'register',
'Login' => 'login'
);
cvf_generate_site_nav_menu( 'Header Menu - Logged Out', $secondary_menu_items, 'secondary' );
}
}
add_action( 'after_switch_theme', 'my_after_switch_theme') );
- Function above will execute when you switch / activate your theme.
- Will be executed only when option “menu_check” is not equal to 1.
In your header.php, use the following code to output the menus for logged-in users or visitors only:
<?php if( is_user_logged_in() ): ?>
<?php wp_nav_menu( array('theme_location' => 'primary', 'fallback_cb' => 'fallback_menu_pages' ) ); ?>
<?php else: ?>
<?php wp_nav_menu( array('theme_location' => 'secondary', 'fallback_cb' => 'fallback_menu_pages' ) ); ?>
<?php endif; ?>
If you notice we added a fallback, which is the function that will be called if our menu (primary / secondary) is not existing. Add this fallback function to your functions.php:
function fallback_menu_pages() {
$list_pages = '';
$args = array(
'sort_order' => 'asc',
'sort_column' => 'post_title',
'hierarchical' => 1,
'child_of' => 0,
'parent' => -1,
'offset' => 0,
'number' => 5,
'post_type' => 'page',
'post_status' => 'publish'
);
$pages = get_pages( $args );
foreach( $pages as $key => $page ){
$list_pages .= '<li><a href = "' . get_permalink( $page->ID ) . '">' . $page->post_title . '</a></li>';
}
echo $list_pages;
}
The function above will output only 5 menu items. – To change this, set “number” to the number of menu items you want to output.