web-dev-qa-db-fra.com

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

Grâce aux fonctions de l’API, je souhaite définir un nouveau menu de navigation , le sélectionner dans le thème actuel, puis insérer quelques pages en tant qu’éléments de menu. Cela doit être fait par exemple sur 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 avoir configuré manuellement le menu de navigation et les éléments, j'ai regroupé les étapes suivantes, où 'footer-nav' est l'identifiant du slug du menu de navigation I ' m créant:

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?
  • est-ce que je manque quelque chose de tout à fait évident qui ferait tout cela dans une seule ligne de code?
39
julien_c

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 que BP est 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 );
    }
39
ZaMoose

En complément de la réponse de ZaMoose, voici comment créer un élément de menu " Page - type" (et non un " 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 la page, par exemple.

12
julien_c

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

Premièrement, le code ci-dessus crée des éléments de navigation de type "URL", ce qui convient parfaitement à certaines personnes, mais je souhaite créer un lien vers PAGES, et non des URL, car il s'agit d'une fonctionnalité importante de la navigation WordPress et du fait que les clients déplacent inévitablement les choses. type d'élément de navigation.

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 leur identifiant après leur création 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 le libellé de l'élément de navigation au début. path est le chemin d'accès à la page dans la hiérarchie de la page 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é facultative de tableau 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')
        );
    }

    }
9
Brian

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. "Primaire" 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;
}
2
Aamer Shahzad