Menü öğeleri açıklaması? Wp_nav_menu () için özel Walker


104

Normal WordPress Menüsü şuna benzer:

Ana Sayfa | Blog | Hakkımızda | İletişim

Ancak bu bağlantıların altında açıklamaları olan birçok sayfa gördüm:

Ana Sayfa | Bloglarımız | Hakkımızda | İletişim
.... bizimle tanışın ... | daha fazla oku | temel bilgi | İletişim Formu

Bu nasıl başarılır?

(Tüm temalarım için temel işlevi olmasını istiyorum, bu yüzden lütfen eklenti yok, sadece nasıl yapıldığını bilmek istiyorum)

Yanıtlar:


115

Nav menüsü için özel bir yürüteç gerekir.

Temel olarak, bir parametre eklemek 'walker'için wp_nav_menu()seçenekler ve gelişmiş bir sınıfının bir örneğini çağırır:

wp_nav_menu(
    array (
        'menu'            => 'main-menu',
        'container'       => FALSE,
        'container_id'    => FALSE,
        'menu_class'      => '',
        'menu_id'         => FALSE,
        'depth'           => 1,
        'walker'          => new Description_Walker
    )
);

Sınıf Description_Walkeruzanır Walker_Nav_Menuve fonksiyonunu değiştirir start_el( &$output, $item, $depth, $args )aramaya $item->description.

Temel bir örnek:

/**
 * Create HTML list of nav menu items.
 * Replacement for the native Walker, using the description.
 *
 * @see    https://wordpress.stackexchange.com/q/14037/
 * @author fuxia
 */
class Description_Walker extends Walker_Nav_Menu
{
    /**
     * Start the element output.
     *
     * @param  string $output Passed by reference. Used to append additional content.
     * @param  object $item   Menu item data object.
     * @param  int $depth     Depth of menu item. May be used for padding.
     * @param  array|object $args    Additional strings. Actually always an 
                                     instance of stdClass. But this is WordPress.
     * @return void
     */
    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 )
    {
        $classes     = empty ( $item->classes ) ? array () : (array) $item->classes;

        $class_names = join(
            ' '
        ,   apply_filters(
                'nav_menu_css_class'
            ,   array_filter( $classes ), $item
            )
        );

        ! empty ( $class_names )
            and $class_names = ' class="'. esc_attr( $class_names ) . '"';

        $output .= "<li id='menu-item-$item->ID' $class_names>";

        $attributes  = '';

        ! empty( $item->attr_title )
            and $attributes .= ' title="'  . esc_attr( $item->attr_title ) .'"';
        ! empty( $item->target )
            and $attributes .= ' target="' . esc_attr( $item->target     ) .'"';
        ! empty( $item->xfn )
            and $attributes .= ' rel="'    . esc_attr( $item->xfn        ) .'"';
        ! empty( $item->url )
            and $attributes .= ' href="'   . esc_attr( $item->url        ) .'"';

        // insert description for top level elements only
        // you may change this
        $description = ( ! empty ( $item->description ) and 0 == $depth )
            ? '<small class="nav_desc">' . esc_attr( $item->description ) . '</small>' : '';

        $title = apply_filters( 'the_title', $item->title, $item->ID );

        $item_output = $args->before
            . "<a $attributes>"
            . $args->link_before
            . $title
            . '</a> '
            . $args->link_after
            . $description
            . $args->after;

        // Since $output is called by reference we don't need to return anything.
        $output .= apply_filters(
            'walker_nav_menu_start_el'
        ,   $item_output
        ,   $item
        ,   $depth
        ,   $args
        );
    }
}

Ya da, alternatif olarak @nevvermind yorumladı olarak , sen verebilir miras ebeveynin tüm işlevselliklerini start_elfonksiyonu ve sadece eklemek için açıklama $output:

function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) 
{
    parent::start_el( $output, $item, $depth, $args );
    $output .= sprintf( 
        '<i>%s</i>', 
        esc_html( $item->description ) 
    );
}

Örnek çıktı:

görüntü tanımını buraya girin

Şimdi wp-admin/nav-menus.phpbu alanı düzenleyebilmek için açıklama alanını etkinleştirin . WP yapmazsanız, tüm gönderi içeriğinizi içine atmanız yeterlidir.

görüntü tanımını buraya girin

Daha fazla okuma:

Ve bu kadar.


11
Eğer için ise ! Veraset = bütün yöntemi yeniden, sadece aynı adı tutmak , şunu deneyin:public function start_el(&$output, $item, $depth, $args) { parent::start_el($output, $item, $depth, $args); $output .= sprintf('<i>%s</i>', esc_html($item->description)); }
nevvermind

2
@ nevvermind En azından açıklamanın içeriğe sahip olup olmadığını kontrol etmelisiniz. ;) Örnek kodumda açıklamanın konumu çözümü göstermenin en basit yoludur. Eğer çapa içine açıklamayı almak gerekiyorsa, sahip bütün fonksiyonunu yeniden inşa etmek.
fuxia

1
evet, tüm metodu yazmanız gerekecek, bunun hakkında hiç şüpheniz yok, ama eklemesi gereken (söyleyeceğiniz…) insanlar için, onları bir sürü baş ağrısından kurtarabilir. Ve hepsi bu WP'nin suçu. Arrrgh!
nevvermind

Güzel olanı ve bu cevabı biraz değiştirerek kullandım , eğer bir şeyi kaçırırsam daha iyisini yapabilirsin, teşekkürler.
Alfa,

Ne Aslında gerekli olan wp_nav_menu , ama ben bazı koşuluyla başka biri için ana menüyü takas benim özel kullanım durumunda, için çalışmak, 'container_class' parametresini değiştirmek için gereken, ancak css için tutarlı olması sınıfları gerekli.
D. Dan

33

Yana WordPress 3.0 , sen yok artık özel bir yürüteç gerekiyor!

Orada walker_nav_menu_start_elfiltre, bkz https://developer.wordpress.org/reference/hooks/walker_nav_menu_start_el/

Örnek:

function add_description_to_menu($item_output, $item, $depth, $args) {
    if (strlen($item->description) > 0 ) {
        // append description after link
        $item_output .= sprintf('<span class="description">%s</span>', esc_html($item->description));

        // insert description as last item *in* link ($input_output ends with "</a>{$args->after}")
        //$item_output = substr($item_output, 0, -strlen("</a>{$args->after}")) . sprintf('<span class="description">%s</span >', esc_html($item->description)) . "</a>{$args->after}";
    }

    return $item_output;
}
add_filter('walker_nav_menu_start_el', 'add_description_to_menu', 10, 4);

1
Güzel! @Toscho tarafından nav walker çözümünü kullanıyordum, ancak bu çok daha temiz ve bakımı daha kolay. Bu kabul edilen cevap olmalı, çok daha iyi bir uygulama.
Neejoh

8

Bu, diğer önerilerden daha iyi veya daha kötü değil; bu sadece farklı. Çok kısa ve tatlı.

@Toscho'nun önerdiği gibi açıklama alanını kullanmak yerine , her menü öğesindeki "Başlık" alanını istediğiniz metinle doldurabilir ve ardından bu CSS'yi kullanabilirsiniz:

.menu-item a:after { content: attr(title); }

Ayrıca, jQuery'yi eklemek için kullanımı da kolay olacaktır , ancak metin, CSS'nin uygun görünmesine yetecek kadar süslenmiştir.


2

Ayrıca <span>, menülerde gezinti etiketinden sonra bir öğe yazabilir ve displayayarını değiştirmek için aşağıdaki CSS kuralını kullanabilirsiniz ( inlinevarsayılan olarak):

span {display:block}

2
Peki basit ve kolay bir çözüm ama neden spanyine de engellerseniz neden kullanıyorsunuz ? xhtml / html4, linkler içindeki blok elemanlarına izin vermez, html5 ise sadece kullanır divve herhangi bir css'e gerek duymaz!
James Mitch,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.