Adăugarea dinamică a elementelor de meniu folosind wp_nav_menu_objects

4 mar. 2014, 18:59:36
Vizualizări: 15.5K
Voturi: 2

În meniul meu principal, doresc ca fiecare pagină de nivel superior să afișeze o listă cu subpaginile sale. Am creat un cod care adaugă dinamic elemente de meniu în navigația principală. Acesta funcționează doar pentru primul nivel de subpagini. Puteți observa că am comentat codul care merge până la al doilea nivel, deoarece afișa acele linkuri pe nivelul principal. Nu înțeleg de ce nu funcționează pentru al doilea nivel. Este posibil să nu putem atribui un element de meniu unui element părinte generat dinamic?

Iată cum arată codul:

add_filter( 'wp_nav_menu_objects', 'epc_wp_nav_menu_items', 10, 2 );
function epc_wp_nav_menu_items($items, $args) {
    if ($args->theme_location == 'primary') {
        $menu_order = 10000;
        $menu_order2 = 20000;
        global $wpdb;
        global $post;
        $post_id = 0;       
        if($post){
            $post_id = $post->ID;
        }

        foreach($items as $item){
            $pageChildren = $wpdb->get_results("SELECT post_title, ID FROM wp_posts WHERE post_parent = ".$item->object_id." AND post_status = 'publish' AND post_type='page' ORDER BY menu_order", 'OBJECT' );
            foreach($pageChildren as $child){
                $menu_order++;
                $new_item = epc_add_menu_item($post_id, $menu_order, $item, $child);
                $items[] = (object)$new_item;
                /*
                $pageChildrenSecondLevel = $wpdb->get_results("SELECT post_title, ID FROM wp_posts WHERE post_parent = ".$child->ID." AND post_status = 'publish' AND post_type='page' ORDER BY menu_order", 'OBJECT' );
                foreach($pageChildrenSecondLevel as $child2){
                    $menu_order2++;
                    $new_item2 = epc_add_menu_item($post_id, $menu_order2, $new_item, $child2);
                    $items[] = (object)$new_item2;
                }
                */
            }
        }
    }
    return $items;
}

function epc_add_menu_item($post_id, $menu_order, $item, $child){
                $new_item = new stdClass;
                $new_item->ID = $menu_order;
                $new_item->menu_item_parent = $item->ID;
                $new_item->url = get_permalink( $child->ID );
                $new_item->title = $child->post_title;
                $new_item->menu_order = $menu_order;
                $new_item->object_id = $child->ID;
                $new_item->post_parent = $item->object_id;
                $classes = 'menu-item';
                $classes .= ' menu-item-parent-' . $item->ID;
                $classes .= ' menu-item-type-post_type';
                $classes .= ' menu-item-object-page';
                if($post_id == $child->ID){
                    $classes .= ' current-menu-item';
                    $classes .= ' page-item';
                    $classes .= ' page-item-' . $child->ID ;
                    $classes .= ' current_page_item';
                }   
                $new_item->classes = $classes;
                return $new_item;
}
1
Comentarii

Ceea ce descrii sună foarte complicat pentru un simplu filtru. Cred că aș lua în serios în considerare utilizarea unui Walker personalizat. Vezi: http://wordpress.stackexchange.com/search?q=user%3A21376+extends+Walker_Nav_Menu

s_ha_dum s_ha_dum
5 mar. 2014 04:01:51
Toate răspunsurile la întrebare 3
0

De asemenea, ar trebui să specifici câmpul db_id pentru elementul de meniu părinte:

function epc_add_menu_item( $post_id, $menu_order, $item, $child ) {
    ...
    $new_item->db_id = $menu_order;
    ...
}

Ca o observație suplimentară, un element de meniu care are elemente descendente ar trebui să aibă și clasa menu-item-has-children.

14 apr. 2016 19:38:02
0

Folosește această clasă personalizată pentru a afișa submeniul:

class Wp_Sublevel_Walker extends Walker_Nav_Menu {

    function start_lvl(&$output, $depth = 0, $args = array()) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class='submenu'>\n";
    }

    function end_lvl(&$output, $depth = 0, $args = array()) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul>\n";
    }

}
5 aug. 2016 13:07:18
0

Dacă intrările personalizate din meniu sunt bazate pe postări, categorii sau alte obiecte WordPress, poți folosi funcția wp_setup_nav_menu_item(WP_object) pentru a obține un obiect de tip element de meniu.

$item=wp_setup_nav_menu_item(get_post());

Acest obiect va avea majoritatea informațiilor setate corect, dar nu toate. Încă mai trebuie să setăm manual unele proprietăți ale elementului. Trebuie să setăm elementul părinte din meniu. Dacă dorești să-l faci la nivelul superior, dă-i valoarea 0.

$item->menu_item_parent = $parentitem->ID;

Pentru ca un element să poată avea copii, trebuie să-i atribui un db_id, dar acesta TREBUIE să fie ID-ul obiectului WordPress. Nu va funcționa (sau cel puțin eu nu am reușit) cu orice altă valoare. Așa că trebuie să setăm asta:

$item->db_id = get_the_ID();

Dacă intrarea curentă va avea copii, adaugi clasa menu-has-children la variabila classes. De remarcat că eu adaug și alte clase (css) necesare pentru tema mea.

$item->classes = array("menu-item", "menu-item-type-post_type", "menu-item-object-page", "menu-item-has-children");

Poți crea propriul tău element personalizat creând elementul așa cum am descris mai sus și apoi modificând $item->title și $item->url dar păstrând ID-urile. Asigură-te doar că ID-ul este unic la nivelul meniului (nu am verificat dacă trebuie să fie unic în întregul meniu).

(Pentru alții ca mine care au dat peste acest thread încercând să creeze un meniu personalizat: Ordinea din meniu trebuie să fie astfel încât părintele să fie urmat direct de copiii săi.)

15 ian. 2021 23:32:22