0

I've been working for a couple of days with automatic creation of menu upon theme activation in wordpress. I've achieved the creation of menu and it's working as expected, except i want to add sub items to some of menu items. For that moment i have

  • Home
  • Menu item 1
  • Menu item 2

What I'm trying to achieve is:

  • Home
  • Menu item 1 - Sub item 1, - Sub item 2
  • Menu item 2

I've been searching for the whole day without result. Could anybody help?

Here is my code so far:

add_action('after_switch_theme', 'my_after_switch_theme');
add_action('after_setup_theme', 'my_after_setup_theme');

function my_after_setup_theme()
{
    register_nav_menus(array(
        'primary' => __('Main Menu', ''),
    ));
}

function my_after_switch_theme()
{

    $menu_check = get_option('menu_check');
    if (!$menu_check)
    {
        $primary_menu_items = array(
            'Home' => '/',
            'Menu item 2' => '/',
            'Menu item 3' => '/',
        );
        generate_nav_menu('Primary Menu', $primary_menu_items, 'primary');

    }
}

function generate_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'
        ));
        }

function generate_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_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);

}
1

Looking at the code for wp_update_nav_menu_item() the third parameter is an array of data about the menu item you are trying to update/create. One of the accepted items in that array is menu-item-parent-id. If you pass that key with the value of the ID of the parent menu item as part of the menu item data array then your problem should be solved.

EDIT: I haven't tested this, but in theory, and assuming everything you had before was correct, this will work for you

add_action('after_switch_theme', 'my_after_switch_theme');
add_action('after_setup_theme', 'my_after_setup_theme');

function my_after_setup_theme()
{
    register_nav_menus(array(
                           'primary' => __('Main Menu', ''),
                       ));
}

function my_after_switch_theme()
{

    $menu_check = get_option('menu_check');
    if (!$menu_check) {
        $primary_menu_items = array(
            'Home'        => array('url' => '/'),
            'Menu item 2' => array(
                'url' => '/',
                'sub-items' => array(
                    'Sub item 1' => array('url' => '/'),
                    'Sub item 2' => array('url' => '/')
                )),
            'Menu item 3' => array('url' => '/'),
        );
        generate_nav_menu('Primary Menu', $primary_menu_items, 'primary');

    }
}

function generate_nav_menu_item($term_id, $title, $data, $parent = false)
{
    if (!$data['url']) {
        return;
    }

    $args = array(
        'menu-item-title'  => sprintf(__('%s', 'text_domain'), $title),
        'menu-item-url'    => home_url('/' . $data['url']),
        'menu-item-status' => 'publish'
    );
    if ($parent) {
        $args['menu-item-parent-id'] = $parent;
    }

    $item_id = wp_update_nav_menu_item($term_id, 0, $args );
    if (!empty($data['sub-items']) && !is_wp_error($item_id)) {
        foreach ($data['sub-items'] as $sub_item_title => $item) {
            generate_nav_menu_item($term_id, $sub_item_title, $item, $item_id);
        }
    }
}

function generate_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_data) {
        generate_nav_menu_item($menu_primary_obj->term_id, $page_name, $page_data);
    }

    $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);

}
| improve this answer | |
  • You've saved my life! Thanks a lot. It's working :) – AnTrakS Mar 15 '19 at 7:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.