it-swarm.com.de

Programmgesteuertes Hinzufügen eines Navigationsmenüs und von Menüelementen

Über API-Funktionen möchte ich ein neues Navigationsmenü definieren, es im aktuellen Thema auswählen und dann einige Seiten als Menüelemente einfügen. Dies soll zum Beispiel bei einer Themenaktivierung geschehen.

Durch einen (mäßig schmerzhaften) Prozess des Reverse Engineerings, bei dem die Datenbank nach dem manuellen Einrichten des Navigationsmenüs und der Elemente eingefügt und aktualisiert wird, habe ich die folgenden Schritte zusammengesetzt, wobei 'footer-nav' die Slug-ID des Navigationsmenüs I 'ist. Ich erstelle:

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

Dies scheint zu funktionieren, aber:

  • ist es eine robuste und elegante Art, es zu tun?
  • fehlt mir etwas völlig Offensichtliches, das all dies in einer Codezeile tun würde?
39
julien_c

Ich könnte Sie missverstehen, aber warum nicht wp_create_nav_menu() verwenden?

Zum Beispiel ist dies das, was ich mache, um ein benutzerdefiniertes BuddyPress-Menü zu erstellen, wenn ich BP als aktiv erkenne:

    $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

Als Ergänzung zu ZaMooses Antwort erstellen Sie wie folgt einen Menüeintrag " Seite - Typ" (kein " Benutzerdefinierter "):

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

Angenommen, Sie kennen nur den Page Slug.

12
julien_c

Ich habe ein paar Probleme mit der akzeptierten Antwort - das macht es nicht falsch, aber ich werde meinen eigenen Code veröffentlichen, unter dem ich glaube, dass einige Leute ein besseres Ergebnis erzielen, da ich die gleiche Frage hatte, aber das gleiche tun wollte etwas mit weniger Code.

Erstens erstellt der obige Code Navigationselemente vom Typ "URL", was für einige Leute in Ordnung ist, aber ich möchte auf SEITEN verlinken, nicht auf URLs, da dies eine wichtige Funktion von WordPress-Navigationen ist und Clients unvermeidlich Dinge verschieben, sodass ich die URL niemals verwende Navigationselementtyp.

Außerdem wird nur ein flaches Array von untergeordneten Elementen von der Postleitzahl verarbeitet. Ich habe eine Funktion zum rekursiven Deklarieren der neuen Navigationselemente, Speichern der zurückgegebenen Metadaten (hauptsächlich der ID nach dem Erstellen in der Schleife) und einen Parameter zum Akzeptieren von untergeordneten Elementen erstellt.

Bearbeiten Sie einfach $nav_items_to_add und der Rest wird rekursiv behandelt. In jedem Array sind 3 Schlüssel erforderlich. Erstens ist der Array-Schlüssel der Slug, also ist 'shop' => array( ... ) das, was Sie für eine Seite mit dem Slug shop wollen. ['title'] ist die Art und Weise, wie das Navigationselement am Frontend beschriftet wird. path ist der Pfad zur Seite innerhalb der WordPress-Seitenhierarchie. Dies ist also identisch mit dem Slug, wenn die Seite ein übergeordnetes Element auf oberster Ebene ist und shop ein untergeordnetes Element von home ist, dann wäre es 'path' => 'home/shop'.

Der letzte optionale Array-Schlüssel ist ['parent']. Hier können Sie einen anderen Schlüssel im Array als übergeordneten Schlüssel des aktuellen Schlüssels deklarieren. Es ist wichtig zu beachten, dass die Elemente rekursiv hinzugefügt werden, sodass das übergeordnete Element vorhanden sein muss, bevor Sie versuchen, ein untergeordnetes Element zu erstellen. Dies bedeutet, dass die Deklaration für das übergeordnete Navigationselement erfolgen sollte, bevor es untergeordnet ist.

    $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

So fügen Sie programmgesteuert einen Menüpunkt hinzu Sie können sich mit dem wp_nav_menu_items-Filter verbinden. Platzieren Sie den folgenden Code in der Datei functions.php, um den Menüpunkt Anmelden/Abmelden im Hauptmenü hinzuzufügen. 'Primär' ist der Name/die ID des registrierten Menüs.

/**
 * 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