Tambahkan kelas 'has_children' ke induk li saat memodifikasi Walker_Nav_Menu


22

Saya sedang menulis kelas walker yang disesuaikan untuk wp_nav_menu dan ingin dapat menentukan apakah li berisi submenu. Jadi saya ingin markup saya menjadi:

<li class="has_children [other-wordpress-classes]">
    <a class="parent-link">Some item</a>
    <ul class="sub-menu">

Saya tahu cara menambah dan menghapus kelas dengan baik, saya tidak bisa menemukan apa pun untuk memberi tahu saya jika item saat ini memiliki item anak-anak.

Ada ide?

Terima kasih sebelumnya.

Jawaban:


23

start_el()harus mendapatkan informasi ini dalam $argsparameternya, tetapi tampaknya WordPress hanya mengisinya jika $argsarray , sedangkan untuk menu navigasi khusus, itu adalah objek. Ini dilaporkan dalam tiket Trac . Tapi tidak masalah, Anda bisa mengisinya sendiri, jika Anda juga mengganti display_element()metode di custom walker Anda (karena ini adalah tempat termudah untuk mengakses larik elemen anak):

class WPSE16818_Walker extends Walker_Nav_Menu
{
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output )
    {
        $id_field = $this->db_fields['id'];
        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
        }
        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el( &$output, $item, $depth, $args ) {
        if ( $args->has_children ) {
            // ...
        }
    }

Halo Jan, bisakah Anda membantu saya dengan pertanyaan ini ? Saya mencoba kode Anda tetapi saya tidak bisa membuatnya berfungsi. Bisakah Anda memberi saya lebih banyak kode sampel?
Giri

Lihat contoh implementasi lengkap lebih lanjut di halaman ini.
rjb

Terima kasih banyak @ Jan Fabry .. Saya ditahan dengan walker khusus saya .. Atlast cuplikan Anda membantu saya.
Harish Chinju

7

Pembaruan: Pada WordPress 3.7 (Oktober 2013), kelas-kelas CSS telah ditambahkan untuk menunjukkan item menu anak dan halaman dalam menu tema - tidak perlu menggunakan custom walker seperti yang dijaga di inti WordPress.

Kelas CSS diberi nama menu-item-has-childrendan page_item_has_children.


Untuk solusi lengkap bagi siapa saja yang sedang terburu-buru (memuji jawaban Jan Fabry sebelumnya), lihat implementasi lengkap di bawah ini.

Keluarkan navigasi dalam templat tema Anda:

wp_nav_menu( array(
    'theme_location' => 'navigation-primary',
    'container' => false,
    'container_class' => '',
    'container_id' => '',
    'menu_class' => '',
    'menu_id' => '',
    'walker' => new Selective_Walker(),
    'depth' => 2
    )
);

Kemudian, masukkan hal-hal berikut dalam tema Anda functions.php:

class Selective_Walker extends Walker_Nav_Menu {
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
        $id_field = $this->db_fields['id'];

        if ( is_object( $args[0] ) ) {
            $args[0]->has_children = !empty( $children_elements[$element->$id_field] );
        }

        return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el( &$output, $item, $depth, $args ) {
        if ( $args->has_children ) {
            $item->classes[] = 'has_children';
        }

        parent::start_el(&$output, $item, $depth, $args);
    }
}

Output HTML yang dihasilkan akan menyerupai berikut ini:

<ul>
    <li><a href="#">Home</a></li>
    <li class="has_children"><a href="#">About</a>
        <ul class="sub-menu">
            <li><a href="#">Our Mission</a></li>
        </ul>
    </li>
    <li><a href="#">Services</a></li>
    <li class="has_children"><a href="#">Products</a>
        <ul class="sub-menu">
            <li><a href="#">Lorem Ipsum</a></li>
            <li><a href="#">Lorem Ipsum</a></li>                
        </ul>
    </li>
    <li><a href="#">Contact Us</a></li>
</ul>

Untuk informasi lebih lanjut tentang penggunaan kelas walker WordPress, lihat Memahami Kelas Walker .

Nikmati!


Kesalahan fatal: Referensi pass-by-waktu panggilan telah dihapus di D: \ www \ wordpress \ wp-content \ themes \ wpt_theme \ functions.php on line 44
Tahir Yasin

Baris # 44 adalah parent :: start_el (& $ output, $ item, $ depth, $ args);
Tahir Yasin

2

Fungsi ini persis apa yang Anda inginkan. Ini juga menunjukkan Anda cara yang cukup efektif untuk memodifikasi item menu nav. Selain itu, Anda dapat membukanya untuk fungsi yang lebih lanjut (mis. Tema anak) melalui filter item:

/**
 * Classes for a navigation named "Topnav" in the nav location "top".
 * Shows examples on how to modify the current nav menu item
 * 
 * @param (object) $items
 * @param (object) $menu
 * @param (object) $args
 */
function wpse16818_nav_menu_items( $items, $menu, $args )
{
    # >>>> start editing

    // examples for possible targets
    $target['name'] = 'Topnav';
    // The targeted menu item/s
    $target['items'] = array( (int) 6 );

    # <<<< stop editing

    // filter for child themes: "config_nav_menu_topnav"
    $target = apply_filters( 'config_nav_menu_'.strtolower( $target['name'] ), $target );

    // Abort if we're not with the named menu
    if ( $menu->name !== $target['name'] ) 
        return;

    foreach ( $items as $item )
    {
        // Check what $item contains
        echo '<pre>'; print_r($item); echo '</pre>';

        // First real world example:
        $item->classes = 'span-4';

        // Second real world example:
        // Append this class if we are in one of the targeted items
        if ( in_array( (int) $item->menu_order, $target['items'] ) )
            $item->classes .= ' last';
    }

    return $items;
}
add_filter( 'wp_get_nav_menu_items', 'wpse16818_nav_menu_items', 10, 3 );

Dan ya, hampir setiap kasus - tidak perlu walker khusus.


Terima kasih, saya perlu alat bantu jalan untuk saat ini tetapi akan melihat ini untuk putaran waktu berikutnya!
patnz

1

jika Anda ingin membuat drop down, Anda dapat melakukannya dengan css saja. membuat kustom nav di WP dengan anak-anak, WordPress secara otomatis menetapkan kelas .sub-menu ke child ul. Coba CSS ini

    nav li {position:relative;}
   .sub-menu {display:none; position:absolute; width:300px;}
    nav ul li:hover ul {display:block;}

Anda mungkin ingin menambahkan beberapa jQuery untuk membuatnya sedikit, tetapi ini akan memberi Anda menu drop down yang berfungsi.


Terima kasih, ini untuk menu pohon bertingkat multilevel yang saya masukkan elemen kontrol ke dalam juga, tapi pasti baik untuk melakukan sebanyak mungkin dengan css!
patnz

-1
if ( $this->has_children ) {
    $item_output .= 'has_children';
}

3
Tolong, jelaskan apa yang kode ini lakukan dan bagaimana menjawab pertanyaan itu.
cybmeta

Dan tolong kirim kode dalam konteks yang lebih banyak. Seperti kebanyakan orang yang berkunjung tidak akan tahu ke mana harus mencoba menempelkannya dan akan salah.
s_ha_dum
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.