Menü öğelerini dinamik olarak wp_nav_menu dışında tut


17

Özel menülerden nav menü öğelerini nasıl hariç tutacağım / kaldıracağım hakkında bilgi aramaya çalıştım ve bulduğum tek iş parçacığı benim için yararlı olan herhangi bir cevabı yoktu.

1. Arkaplan:

Sitemde WP özel menüleri (wp_nav_menu) ve jqDock kullanarak bir Dock menüsü bir araya getirdim . JqDock büyüsünü çalıştırmak için sürekli görüntülere veya görüntü bağlantılarına ihtiyaç duyduğundan, özel bir yürüteç kullanıyorum, böylece nav menüsü HTML çıktısı şunun gibi görünüyor:

<div id="menu-first" class="nav">
<a><img src="http://path/to/image-1.png"/></a>
<a><img src="http://path/to/image-2.png"/></a>
<a><img src="http://path/to/image-3.png"/></a>
etc...
</div>

Benim özel yürüteç kod:

class custom_nav_walker extends Walker_Nav_Menu 
{
    var $tree_type = array( 'post_type', 'taxonomy', 'custom' );
    var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

    function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }

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

    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

        //$output .= $indent . '<li' . $id . $value . $class_names .'>';

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

        $description  = ! empty( $item->description ) ? esc_attr( strtolower( $item->description )) : '';
        $item_title   = ! empty( $item->attr_title )  ? esc_attr( $item->attr_title ) : '';

        if ( strpos($description, ';') !== false ) {
        $description_array = explode (';', $description);
            $image_name = $description_array[0];
            $image_alt = $description_array[1];
        } else {
            $image_name = $description;
            $image_alt = $item_title;
        }

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before .'<img src="'.get_bloginfo('template_url').'/images/skin1/'.$image_name.'" alt="'.$image_alt.'" title="'.$item_title.'" />'.$args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }

    function end_el(&$output, $item, $depth) {
        $output .= "";
    }

}

Daha sonra jqDock betiği menü kimliğini ('önce menü') yakalar ve wp_nav_menu çıkışını Dock menüsünün yerine koyar. Dock menüsünün HTML çıktısı, jqDock yüklenirken belirtilen seçeneklere göre değişir.

2. Soru:

Kullanıcının sitede bulunduğu yere göre belirli menü öğelerini görüntülemek (yani hariç tutmak) istemiyorum. Örneğin, Ana Sayfa öğesini yalnızca kullanıcı Ana Sayfa'da değilken ve Rastgele posta öğesini yalnızca o sırada göstermek istiyorum.

3. Atılan çözümler:

a. Çoklu menüler: Birden çok menüyü kaydetme ve oluşturma ve ardından bunları koşullu olarak çağırmak işe yarayabilir; ancak bunun pek çok nedenden dolayı ideal veya temiz bir çözüm olduğunu düşünmüyorum. Ayrıca, birden fazla menünün bakımı veya güncellenmesi kolay değildir.

b. Regex Arama ve Değiştirme: HTML çıkışı değiştirildiği için jqDock seçeneklerini her değiştirdiğimde bu beni iğne parametresini değiştirmeye zorlayabilir.

c. CSS 'display' özelliği: CSS display özelliği aracılığıyla öğeleri gizlemek çalışır, ancak jqDock menü çıkışına uygulanması gerektiğinden, menünün görsel olarak işlenmesini etkiler.

4. Başarısız Çözümler:

a. Filtre wp_nav_menu_items : '$ items' değişkenini (string) yakalamayı ve aşağıdaki kodla koşullu etiketler aracılığıyla farklı değerler atamayı denedim:

function userf_dynamic_nav_menu ($items) {
    $items_array_home = explode('<a', $items);
    $items_array_nothome = $items_array_home;

    unset($items_array_home[1]);
    unset($items_array_nothome[2]);

    $items_home = implode('<a', $items_array_home);
    $items_nothome = implode('<a', $items_array_nothome);

    if ( is_home() ) {
        $items = $items_home;
    } else {
        $items = $items_nothome;
    }
    return $items;
}
add_filter('wp_nav_menu_first_items', 'userf_dynamic_nav_menu');

Menü öğeleri değiştiğinden, ancak koşullu etiketler yoksayıldığından bu yalnızca kısmen çalışır. Filtrenin uygulandığı andan dolayı bunun mantıklı olduğunu düşünüyorum.

b. Özel nav menü işlevi : $ defaults dizisine bir dışlama argümanı eklemek wp_list_pagesve ek argümanı doldurmak için bu biraz değiştirilmiş kodu kullanmak için kendi özel nav menü işlevimi oluşturmaya çalıştım :

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

Herhangi bir fikir?


Bize özel yürüteç çocuk sınıfınızı gösterebilir misiniz?
soulseekah

Merhaba Souleseekah, sadece orijinal yazıma ekledim. Teşekkürler!
Marventus

Ben de bir excludeargüman aktarmayı düşündüm , ama wp_list_pagesdiğer birçok WP işlevinin aksine , bir tane wp_nav_menuiçermiyor. Bu yüzden menüyü çağırırken veya yürüteçte bir tane belirtsem bile, içeri alınmaz wp_nav_menu, değil mi?
Marventus

Üzgünüm, bunu yazarken düz düşünmüyordum, derhal silindi
soulseekah

Endişelenme!
Marventus

Yanıtlar:


26

Yöntem 1

Bazı özel hariç tutma bağımsız değişkenlerini saklamak için özel Walker'ınıza bir kurucu ekleyebilirsiniz:

class custom_nav_walker extends Walker_Nav_Menu {
    function __construct( $exclude = null ) {
        $this->exclude = $exclude;
    }

    function skip( $item ) {
        return in_array($item->ID, (array)$this->exclude);
        // or
        return in_array($item->title, (array)$this->exclude);
        // etc.
    }

    // ...inside start_el, end_el
    if ( $this->skip( $item ) ) return;
}

Ya da yapıcıyı bırakın ve $excludebir yürüteç olarak geçmeden önce özelliğini ayarlayın wp_nav_menu():

$my_custom_nav_walker = new custom_nav_walker;
$my_custom_nav_walker->exclude = array( ... );

Neleri hariç tuttuğunuza bağlı olarak, hariç tutmaya doğru formu sağlayın.

Yöntem 2

wp_get_nav_menu_itemsFiltreye bağlayarak bunu yapmaya devam edersiniz .

function wpse31748_exclude_menu_items( $items, $menu, $args ) {
    // Iterate over the items to search and destroy
    foreach ( $items as $key => $item ) {
        if ( $item->object_id == 168 ) unset( $items[$key] );
    }

    return $items;
}

add_filter( 'wp_get_nav_menu_items', 'wpse31748_exclude_menu_items', null, 3 );

Not: object_idmenünün işaret ettiği nesne ID, menü kimliği ise bunlar farklıdır.

Fikirlerinizi öğrenebilir miyim.


Teşekkürler! İşe yarayabilir. Bir deneyeceğim ve size bildireceğim.
Marventus

Yapıcı yaklaşımını denedim ve ne denesem denesem de in_arrayfonksiyon için "İkinci argüman için yanlış veri tipi" hatası alıyorum . Yanlış bir şey mi yapıyorum?
Marventus

$excludeÖzelliği bir dizi olmalıdır. Bu yüzden yapıcıya bir dizi geçirdiğinizden emin olun veya cevabımdaki güncellenmiş kodu izleyin. $this->excludeBir dizinin geçilmemesi durumunda , tipik olarak için tahmin .
soulseekah

Bunun için üzgünüm: İşlevimde bir yazım hatası vardı. Sadece $exclude = array ('4', '7');sümüklü böcekleri de denedim ve kullanıyorum, ancak yürüteç çıktısı üzerinde herhangi bir etkisi yok. İkinci yaklaşımı deneyeceğim ve size bildireceğim.
Marventus

Hayır, bu da işe yaramadı. Ben bunu anlamaya çalışırken beyin öldüğümü düşünüyorum, bu benim "performans", :-) etkiler olabilir
Marventus

0

Bu yardımcı olur mu

$exclude_array = ( $args->exclude ) ? explode(',', $args->exclude) : array();
$args->exclude = implode( ',', apply_filters('wp_nav_menu_excludes', $exclude_array) );

Örnek olarak

< ?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'exclude' => '66' ) ); ?>

Merhaba Saq, işe yaramayan çözümlerden birinin özel bir nav_menu işlevi oluşturmak ve bu kodu işlevin varsayılanlarına ek bir argüman olarak eklemek olduğunu belirtmeyi unuttum. Ne yazık ki, işe yaramadı. Yürüteç içine dahil etmeye çalışmadım, ama bunun yukarıda bahsettiğim aynı nedenden ötürü işe yarayacağını düşünmüyorum, esas olarak bunun wp_nav_menubir "hariç tutma" argümanı yok, ama yanlış olabilirim.
Marventus

Orijinal yayınımı, bunu açıklığa kavuşturmak için güncelledim.
Marventus

özel bir yürüteç kullanmazsanız, normal bir nav_menu kullanırsınız ve wp_get_nav_menu_items () ile öğeleri özel resminizle
çıkarırsınız

Bu genel olarak iyi bir geçici çözüm olabilir, ancak bu özel durumda wp_get_nav_menu_itemsimg etiketleri gerçek özel menüde depolanmadığı için görüntüleri almaz (yalnızca dosya adları açıklama alanındadır, örneğin, "image1.png" ). Özel yürüteç, img etiketlerini menü çıkışına eklememe izin veren şeydir.
Marventus
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.