Vurgulanması wp_nav_menu () Gezegen Yapısı Altındaki Atalar Sınıfı mı?


30

( Moderatörler notu: Aslen "navigasyon yapısında çocuksuz" wp_nav_menu Ata sınıfı ").

Bir var wp_nav_menubunun üç sayfa vardı benim başlığında. Bu sayfalardan birinde olduğumda li, menüde bu sayfayı içeren sınıf alır .current_page_item. Bu üç sayfa şablonlara sahiptir ve bu şablonlar belirli bir içerik türündeki tüm yayınları almak için özel sorgular içerir. Aslında , bu üst düzey sayfanın algılanan "çocukları" aslında çocuklar değildir, bunlar yalnızca bir şablon kullanarak bu üst düzey sayfayla ilişkilendirdiğim bir içerik türüdür.

'current-ancestor'Kullanıcı, belirli bir yazı türünün tek bir sayfasına göz atarken, yalnızca şablon dosyasındaki özel bir sorguda söz konusu sayfa ile ilişkilendirildiğinde , üst düzey menü öğelerinin bir sınıf almasını isterim .

Bu mantıklı umarım - değilse, seni nerede kaybettim bana bildirin! Herhangi bir yardım için çok teşekkür ederiz.

- Özellikler için düzenlenmiş: Örneğin, şablon kullanan Atölyeler adında statik bir sayfam var . Sümüklü böcek atölyeleridir . Şablon, atölye adı verilen özel bir içerik türünün tüm yayınlarını çeken ve görüntüleyen özel bir get_posts işlevine ve döngüsüne sahiptir . Bu atölye çalışmalarının başlığına tıklarsam, o içeriğin tam içeriğine bakarım. Özel gönderi türünün kalıcı bağlantı yapısı atölye çalışmaları / posta adı olarak ayarlanmıştır.Böylece, kullanıcının gördüğü gibi, bu içerik parçaları Atölyeler sayfasının çocuklarıdır, gerçekte hepsi tek bir içerik türüyken, ancak sayfa ile ilgisi yoktur. 'Atölye' türündeki içeriğe göz atarken 'Atölyeler' menü öğesini vurgulayarak, menüde etkin bir şekilde kapatmam gereken boşluk.

Yine, bu mantıklı umarım, bir paragrafta 20 kez yukarı 'atölye' dedim!


@Gavin - Yapmaya çalıştığınız şeyle ilgili birkaç ayrıntı daha ekleyebilir misiniz? Cevap olarak yazmak, soyut olarak yapmaya çalışmaktan daha kolaydır. Ayrıca , bunlarla ilgili URL yapınızı açıklarsanız, bu yardımcı olacaktır.
MikeSchinkel

1
@Gavin - Bu yardımcı olur. Bu nedenle, üst düzey menü seçeneğiniz "Atölyelerdeki" bir yolun bulunduğu /workshops/ve bir kullanıcı bir atölye sayfasındayken (örn. /workshops/example-workshop/) "Atölye Çalışmaları" menü öğesinin sınıfın current_page_itematanmasını istediğiniz, doğru mu?
MikeSchinkel

wp_nav_menu () geçerli menü atası sınıfını ortaya koyuyor
Daniel Sachs

Yanıtlar:


29

Daha basit bir çözüm var. Her gönderi türü için sayfalar oluşturmayı unutun, böylece nav öğelerine sahip olabilirsiniz, çünkü öğrendiğiniz gibi WP, göz attığınız özel türlerin o sayfa ile ilgili olduğunu kabul etmenin bir yolunu yoktur.

Bunun yerine, Görünüm-> Menüler'de özel bir bağlantı oluşturun. Özel türünüzü döndürecek URL'yi girin ve bir etiket verin, ardından "Menüye Ekle" ye basın.

http://example.com/workshops/

veya hoş olmayan kalıcı bağlantılar:

http://example.com/?post_type=workshops

tek başına bu, yalnızca bu özel yazı türüne sahip tüm gönderileri görüntüleyen bir gezinti düğmesi oluşturur ve bu gezinti öğesini tıklattığınızda geçerli menü öğesi sınıfını da ekler - ancak henüz gezinti sınıfını eklemez Bunun dışındaki URL

Ardından, oluşturulduktan sonra, o yeni öğenin yapılandırmasına gidin ve "Başlık Özniteliği" alanına özel yazı tipinin bilgisini girin (açıklama alanını da kullanabilirsiniz, ancak bu yönetici ekran seçeneklerinde gizlidir) varsayılan olarak).

Şimdi, nav_menu_css_classfiltreyi bağlamanız gerekir (her nav öğesi için kovulur) ve görüntülenen içeriğin özel nav öğenizde belirtilen posta türünde olup olmadığını kontrol etmeniz gerekir:

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_query_var('post_type');
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

Bu durumda, Başlık Özelliği alan içeriğinin boş olmadığını ve sorgulanan geçerli post_type ile eşleşip eşleşmediklerini kontrol edeceğiz. Öyleyse, geçerli menü öğesi sınıfını sınıf dizisine ekler, sonra değiştirilen diziyi döndürür.

Bunu yalnızca nav öğesinin başlığına uyacak şekilde değiştirebilirsiniz, ancak bazı nedenlerden dolayı nav öğesini yazı türünün düz ucundan farklı bir şekilde adlandırmak istiyorsanız, Başlık Özelliği veya Açıklama alanını kullanarak size bu esnekliği sağlar.

Şimdi, bir nav menü öğesiyle eşleşen bir posta türünün tek bir öğesini (veya muhtemelen arşiv listelerini) görüntülemekte olduğunuzda, bu öğeye CSS sınıfı geçerli menü menüsü öğesi verilir;

Sayfa veya sayfa şablonu gerekmiyor ;-) URL sorgusu, doğru yayınların getirilmesiyle ilgileniyor. Döngü şablonunuz, sorgu çıktısını görüntülemeye özen gösterir. Bu işlev ne gösterildiğini tanımaya ve CSS sınıfını eklemeye özen gösterir.

BONUS

wp_update_nav_menu_itemTüm gönderi türleriniz için otomatik olarak oluşturulan menü öğelerini kullanarak işlemi otomatik hale getirebilirsiniz . Bu örnekte, önce $menu_idbu öğelerin eklenmesini istediğiniz navigasyon menüsünü almış olmanız gerekir .

$types = get_post_types( array( 'exclude_from_search' => false, '_builtin' => false  ), 'objects' );
foreach ($types as $type) {
    wp_update_nav_menu_item( $menu_id, 0, array(
        'menu-item-type' => 'custom',
        'menu-item-title' => $type->labels->name,
        'menu-item-url' => get_bloginfo('url') . '/?post_type=' . $type->rewrite['slug'],
        'menu-item-attr-title' => $type->rewrite['slug'],
        'menu-item-status' => 'publish'
        )
    );
}

Işte bunlar! Sayfa şablonlarını yalnızca sayfa düzenleri kullanıyorum çünkü sayfa düzenleri bu sayfalar için oldukça karmaşık ve sadece sayfaları listelemiyor, ancak sayfa kimliğini kontrol etmek için sağladığınız filtreyi kullanabiliyorum. Bu temanın doğası, tema seçeneklerinin sayfaları eşleştirmenizi sağlamasıdır ('ana sayfa bu sayfadır,' yaklaşık 'bu sayfadır, vb.), Bu yüzden mükemmel çalışması gerekir. (İnanılmaz derecede ayrıntılı) yardım için teşekkür ederiz!
Gavin

current_page_parentblogum olan gezinti öğesinden kaldırmak zorunda kaldım - ancak bu işe yaramadı. thx
pkyeck 10:11

bu benim için işe yaramadı çünkü $item->attr_titleTITLE’ı çıkardım ve unvanı büyük harflerle yazdım. bu yüzden niteliği değiştirdim $item->post_nameve şimdi benim için iyi çalışıyor.
honk31

Kodun temam için çalışmasını sağladım, ancak çalışamıyorum. Özel posta tipimdeyken, üst öğeme menüde uygulanmış bir sınıf olmayacak portfolio. Yukarıdaki kodu kullandım. Sorun ne olabilir?
Casper

4

kullanmak yerine

$ post_type = get_query_var ('post_type');

Denemek isteyebilirsiniz:

$ post_type = get_post_type ();

Somtimes olarak post tipi var sorguda ayarlanmadı. Bu, "post" un varsayılan post_type tipi için geçerlidir, bu yüzden bir liste sayfasından listelenen bir postayı vurgulamak istiyorsanız, bunu kullanmanız gerekecektir. get_very_var () sadece özel olmayan yazı tipleri için boş bir dize döndürür.

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {
    $post_type = get_post_type();
    if ($item->attr_title != '' && $item->attr_title == $post_type) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

2

@ Somatik - bu fantasik! Kodunuzu biraz değiştirdim, böylece belirli bir Taksonomi için de işe yaradı (sadece ilgili post_type için kullanıyorum). Buradaki fikir, hem post_type hem de taksonominin adını, iki nokta üst üste ile ayrılmış ve sonra işlev tarafından patlatılanı saklamak için menü öğesinin Title özelliğini kullanmaktır.

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 );
function current_type_nav_class($classes, $item) {

    # get Query Vars
    $post_type = get_query_var('post_type');  
    $taxonomy = get_query_var('taxonomy');

    # get and parse Title attribute of Menu item
    $title = $item->attr_title; // menu item Title attribute, as post_type;taxonomy
    $title_array = explode(";", $title);
    $title_posttype = $title_array[0];
    $title_taxonomy = $title_array[1];

    # add class if needed
    if ($title != '' && ($title_posttype == $post_type || $title_taxonomy == $taxonomy)) {
        array_push($classes, 'current-menu-item');
    };
    return $classes;
}

2

İşte benim çözümüm wp_list_pages ile çalışmak istiyorsanız.

Bunu functions.php dosyasına ekleyin

add_filter('page_css_class', 'my_page_css_class', 10, 2);
function my_page_css_class($css_class, $page){
    $post_type = get_post_type();
    if($post_type != "page"){
        $parent_page = get_option('page_for_custom_post_type-'.$post_type);
        if($page->ID == $parent_page)
            $css_class[] = 'current_page_parent';
    }
    return $css_class;
}

Şimdi sadece birlikte wp_options tablosunda yeni bir satır eklemek option_name ait page_for_custom_post_type-xxxx ve option_value ile sayfa numarası u bağlamak istiyorum.

Belki de page_for_posts adında bir seçenek olduğunu zaten biliyordunuz . Yalnızca 1 özel gönderi türüne sahipseniz, sayfanızı aşağı açılan menüde /wp-admin/options-reading.php olarak ayarlayabilirsiniz; gezinti geçerli_ sayfayı doğru şekilde ayarlar.

Wordpress çekirdeğinin bu bölümü, kayıtlı her yazı tipi için bir açılır menü ile genişletmesi gerektiğini düşünüyorum.


2

Sayfalara bağlı kalmaya ve sayfa şablonu adını nav öğesinde bir sınıf olarak kullanmaya karar verdim. Bu, diğer çözümlerden bazılarını beğenmediğim başlık özniteliğini karıştırmama izin veriyor.

add_filter('nav_menu_css_class', 'mbudm_add_page_type_to_menu', 10, 2 );
//If a menu item is a page then add the template name to it as a css class 
function mbudm_add_page_type_to_menu($classes, $item) {
    if($item->object == 'page'){
        $template_name = get_post_meta( $item->object_id, '_wp_page_template', true );
        $new_class =str_replace(".php","",$template_name);
        array_push($classes, $new_class);
        return $classes;
    }   
}

Ayrıca header.php dosyasına eklenen beden dersleri var

<body <?php body_class(); ?>>

Son olarak, bu çözüm, seçili / aktif durumu nav menü öğelerinize uygulamak için bazı ekstra css'ler gerektirir. Taksonomi arşivlerini ve sayfa ile ilgili özel yazı türlerini bu sayfanın çocukları olarak göstermek için kullanıyorum:

/* selected states - include sub pages for anything related to products */
#nav-main li.current-menu-item a,
body.single-mbudm_product #nav-main li.lp_products a,
body.tax-mbudm_product_category #nav-main li.lp_products a,
#nav-main li.current_page_parent a{color:#c00;}

Bu bana şu hatayı verdi: Warning: join() [function.join]: Invalid arguments passed in /home/path/to/wp-includes/nav-menu-template.php on line 76 Burada ne olduğu hakkında bir fikriniz var mı?
Jeff K.,

Oh, ne olduğunu anladım galiba. Bunun nedeni if ​​ifadesinde $ sınıfları döndürmenizdir. Basitçe return $classesdışarıda hareket etmek ve bundan sonra ifyukarıdaki hatayı çözmek gibi görünüyor.
Jeff K.

1

@Somatic - Harika kod! Kendimde bir değişiklik yaptım. Title Özniteliğini amaçlanan amacı için saklamak istedim, bunun yerine Özel Post Type fişini Link Options (XFN) gelişmiş Menü özelliklerinde Ekran Seçenekleri'nde etkinleştirebileceğiniz özelliklere yerleştirdim. değiştirdim

if ($item->attr_title != '' && $item->attr_title == $post_type) {

ve onu değiştirdi

if ($item->xfn != '' && $item->xfn == $post_type) {

0

İyi iş Somatic.

Maalesef, özel gönderi türlerinizi açıkladığınız şekilde bir sayfada nasıl listeleyebileceğinizi anlamadım. Page-portföy.php kullanmaz ve sayfaya eklemezsem, tek elde edeceğim 404 sayfadır.

Gavin’in yaptığı gibi, "current_page_parent" ı da blog sayfasından bu şekilde kaldırmak için işlevinizi biraz değiştirdim.

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2);
function current_type_nav_class($css_class, $item) {
$post_type = get_query_var('post_type');

if (get_post_type()=='portfolio') {
    $current_value = "current_page_parent"; 
    $css_class = array_filter($css_class, function ($element) use ($current_value) { return ($element != $current_value); } );
}

if ($item->attr_title != '' && $item->attr_title == $post_type) {       
    array_push($css_class, 'current_page_parent');
};
return $css_class;

}

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.