ajouter par programme un menu de navigation et des éléments de menu

37

À travers les fonctions de l'API, je souhaite définir un nouveau menu de navigation , le sélectionner dans le thème actuel, puis en insérer quelques-uns. Pages en tant qu'éléments de menu. Cela doit être fait par exemple lors d’une activation de thème.

Grâce à un processus (moyennement pénible) de reverse engineering des insertions et des mises à jour de la base de données après la configuration manuelle du menu et des éléments de navigation, j'ai reconstitué les étapes suivantes, où 'footer-nav' est l'identifiant du slug de Navigation menu que je crée:

if (!term_exists('footer-nav', 'nav_menu')) {

    $menu = wp_insert_term('Footer nav', 'nav_menu', array('slug' => 'footer-nav'));

    // Select this menu in the current theme
    update_option('theme_mods_'.get_current_theme(), array("nav_menu_locations" => array("primary" => $menu['term_id'])));

    // Insert new page
    $page = wp_insert_post(array('post_title' => 'Blog',
                                 'post_content' => '',
                                 'post_status' => 'publish',
                                 'post_type' => 'page'));

    // Insert new nav_menu_item
    $nav_item = wp_insert_post(array('post_title' => 'News',
                                     'post_content' => '',
                                     'post_status' => 'publish',
                                     'post_type' => 'nav_menu_item'));


    add_post_meta($nav_item, '_menu_item_type', 'post_type');
    add_post_meta($nav_item, '_menu_item_menu_item_parent', '0');
    add_post_meta($nav_item, '_menu_item_object_id', $page);
    add_post_meta($nav_item, '_menu_item_object', 'page');
    add_post_meta($nav_item, '_menu_item_target', '');
    add_post_meta($nav_item, '_menu_item_classes', 'a:1:{i:0;s:0:"";}');
    add_post_meta($nav_item, '_menu_item_xfn', '');
    add_post_meta($nav_item, '_menu_item_url', '');

    wp_set_object_terms($nav_item, 'footer-nav', 'nav_menu');
}

Cela semble fonctionner, mais:

  • est-ce une manière robuste et élégante de le faire?
  • me manque quelque chose de tout à fait évident qui ferait tout cela dans une ligne de code?
posée julien_c 07.03.2012 - 14:43

4 réponses

39

Je vous ai peut-être mal compris, mais pourquoi ne pas utiliser wp_create_nav_menu() ?

Par exemple, voici ce que je fais pour créer un menu BuddyPress personnalisé lorsque je détecte un tiers actif:

    $menuname = $lblg_themename . ' BuddyPress Menu';
$bpmenulocation = 'lblgbpmenu';
// Does the menu exist already?
$menu_exists = wp_get_nav_menu_object( $menuname );

// If it doesn't exist, let's create it.
if( !$menu_exists){
    $menu_id = wp_create_nav_menu($menuname);

    // Set up default BuddyPress links and add them to the menu.
    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Home'),
        'menu-item-classes' => 'home',
        'menu-item-url' => home_url( '/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Activity'),
        'menu-item-classes' => 'activity',
        'menu-item-url' => home_url( '/activity/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Members'),
        'menu-item-classes' => 'members',
        'menu-item-url' => home_url( '/members/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Groups'),
        'menu-item-classes' => 'groups',
        'menu-item-url' => home_url( '/groups/' ), 
        'menu-item-status' => 'publish'));

    wp_update_nav_menu_item($menu_id, 0, array(
        'menu-item-title' =>  __('Forums'),
        'menu-item-classes' => 'forums',
        'menu-item-url' => home_url( '/forums/' ), 
        'menu-item-status' => 'publish'));

    // Grab the theme locations and assign our newly-created menu
    // to the BuddyPress menu location.
    if( !has_nav_menu( $bpmenulocation ) ){
        $locations = get_theme_mod('nav_menu_locations');
        $locations[$bpmenulocation] = $menu_id;
        set_theme_mod( 'nav_menu_locations', $locations );
    }
    
réponse donnée ZaMoose 07.03.2012 - 15:03
12

En complément de la réponse de ZaMoose, voici comment créer un élément de menu de type " Page " (et non un élément de menu " Personnalisé "):

wp_update_nav_menu_item($menu_id, 0, array('menu-item-title' => 'About',
                                           'menu-item-object' => 'page',
                                           'menu-item-object-id' => get_page_by_path('about')->ID,
                                           'menu-item-type' => 'post_type',
                                           'menu-item-status' => 'publish'));

En supposant que vous ne connaissiez que le slug de page, par exemple.

    
réponse donnée julien_c 15.05.2012 - 13:04
9

J'ai quelques problèmes avec la réponse acceptée - cela ne le rend pas faux, mais je posterai ci-dessous mon propre code qui, à mon avis, pourrait donner de meilleurs résultats pour certaines personnes puisque j'avais la même question mais que je voulais faire la même chose avec moins de code.

Tout d’abord, le code ci-dessus crée des éléments de navigation de type "URL", ce qui convient à certaines personnes, mais je souhaite créer un lien vers PAGES, et non avec des URL, car il s’agit d’une caractéristique importante des navigations WordPress. utilisez le type d'élément de navigation d'URL.

De plus, seul un tableau plat d'enfants est traité par le code envoyé. J'ai créé une fonction permettant de déclarer récursivement les nouveaux éléments de navigation, de stocker leurs métadonnées renvoyées (principalement un identifiant après avoir été créé dans la boucle) et un paramètre permettant d'accepter des enfants.

Éditez simplement $nav_items_to_add et le reste est traité de manière récursive. Il y a 3 clés requises dans chaque tableau. Premièrement, la clé de tableau est le slug, donc 'shop' => array( ... ) est ce que vous voulez pour une page avec le slug shop . ['title'] est la façon dont l'élément de navigation sera étiqueté sur le frontal. path est le chemin d'accès à la page dans la hiérarchie des pages WordPress. Il est donc identique au slug si la page est un parent de niveau supérieur et si shop était un enfant de home , il s'agirait de 'path' => 'home/shop' .

La dernière clé de tableau facultative est ['parent'] , où vous pouvez déclarer une autre clé du tableau en tant que parent de la clé actuelle. Il est important de noter que les éléments sont ajoutés de manière récursive. Le parent doit donc exister avant de tenter de créer un enfant. Cela signifie que la déclaration doit avoir lieu pour l'élément de navigation parent avant ses enfants.

    $locations = get_nav_menu_locations();

    if (isset($locations['primary_navigation'])) {
        $menu_id = $locations['primary_navigation'];

        $new_menu_obj = array();

        $nav_items_to_add = array(
                'shop' => array(
                    'title' => 'Shop',
                    'path' => 'shop',
                    ),
                'shop_l2' => array(
                    'title' => 'Shop',
                    'path' => 'shop',
                    'parent' => 'shop',
                    ),
                'cart' => array(
                    'title' => 'Cart',
                    'path' => 'shop/cart',
                    'parent' => 'shop',
                    ),
                'checkout' => array(
                    'title' => 'Checkout',
                    'path' => 'shop/checkout',
                    'parent' => 'shop',
                    ),
                'my-account' => array(
                    'title' => 'My Account',
                    'path' => 'shop/my-account',
                    'parent' => 'shop',
                    ),
                'lost-password' => array(
                    'title' => 'Lost Password',
                    'path' => 'shop/my-account/lost-password',
                    'parent' => 'my-account',
                    ),
                'edit-address' => array(
                    'title' => 'Edit My Address',
                    'path' => 'shop/my-account/edit-address',
                    'parent' => 'my-account',
                    ),
            );

    foreach ( $nav_items_to_add as $slug => $nav_item ) {
        $new_menu_obj[$slug] = array();
        if ( array_key_exists( 'parent', $nav_item ) )
            $new_menu_obj[$slug]['parent'] = $nav_item['parent'];
        $new_menu_obj[$slug]['id'] = wp_update_nav_menu_item($menu_id, 0,  array(
                'menu-item-title' => $nav_item['title'],
                'menu-item-object' => 'page',
                'menu-item-parent-id' => $new_menu_obj[ $nav_item['parent'] ]['id'],
                'menu-item-object-id' => get_page_by_path( $nav_item['path'] )->ID,
                'menu-item-type' => 'post_type',
                'menu-item-status' => 'publish')
        );
    }

    }
    
réponse donnée Brian 02.05.2013 - 01:04
2

Pour ajouter un élément de menu par programme. vous pouvez vous connecter au filtre wp_nav_menu_items . Placez le code ci-dessous dans le thème functions.php pour ajouter un élément de menu de connexion / déconnexion dans le menu principal. "Principal" est le nom / id du menu enregistré.

/**
 * Add login logout menu item in the main menu.
 * ===========================================
 */

add_filter( 'wp_nav_menu_items', 'lunchbox_add_loginout_link', 10, 2 );
function lunchbox_add_loginout_link( $items, $args ) {
    /**
     * If menu primary menu is set & user is logged in.
     */
    if ( is_user_logged_in() && $args->theme_location == 'primary' ) {
        $items .= '<li><a href="'. wp_logout_url() .'">Log Out</a></li>';
    }
    /**
     * Else display login menu item.
     */
    elseif ( !is_user_logged_in() && $args->theme_location == 'primary' ) {
        $items .= '<li><a href="'. site_url('wp-login.php') .'">Log In</a></li>';
    }
    return $items;
}
    
réponse donnée Aamer Shahzad 08.03.2016 - 19:49

Lire d'autres questions sur les étiquettes