it-swarm-eu.dev

Zvýraznění wp_nav_menu () Třída předků bez dětí ve struktuře Nav?

( Poznámka moderátorů: Byl původně nazván "wp_nav_menu Třída předků bez dětí v navigační struktuře")

Mám v záhlaví wp_nav_menu, které obsahovalo tři stránky. Když jsem na jedné z těchto stránek, li obsahující tuto stránku v menu dostane třídu .current_page_item. Tyto tři stránky obsahují šablony a tyto šablony obsahují vlastní dotazy, které umožňují získat všechny příspěvky určitého typu obsahu. Ve skutečnosti, vnímané "děti" na této stránce na nejvyšší úrovni nejsou ve skutečnosti dětmi, jsou to pouze obsahové typy, které jsem přidružil k této stránce nejvyšší úrovně pomocí šablony.

Chtěl bych, aby položky nabídky na nejvyšší úrovni dostaly třídu 'current-ancestor', když uživatel prohlíží jednu stránku určitého typu příspěvku, opět spojenou s touto stránkou pouze ve vlastním dotazu v souboru šablony.

Doufám, že to dává smysl - pokud ne, dejte mi vědět, kde jsem vás ztratil! Velmi oceníte jakoukoliv pomoc.

--Edited pro specifika: Například mám statickou stránku nazvanou Workshopy , která používá šablonu. Jeho slug je workshopy . Šablona má v sobě vlastní funkci get_posts a smyčku, která táhne a zobrazuje všechny příspěvky vlastního typu obsahu nazvaného workshopy . Pokud kliknu na jeden z těchto workshopů, vezmu se k obsahu tohoto obsahu. Struktura permalinku vlastního typu příspěvku je nastavena na workshopy / postname , takže když to uživatel vidí, tyto obsahy jsou dětmi ze stránky Workshopy, když ve skutečnosti jsou všechny z jednoho typu obsahu ale nesouvisí se stránkou. Je to ta mezera, kterou potřebuji efektivně zavřít v menu a zvýraznit položku „Workshopy“ při procházení obsahu typu „workshop“.

Opět platí, že doufám, že to dává smysl, myslím, že jsem řekl 'workshop' nahoru 20 krát v jednom odstavci!

30
Gavin

Existuje jednodušší řešení. Zapomeňte na vytváření stránek pro každý typ příspěvku jen tak, abyste mohli mít položky nav, protože jak jste se naučili, WP nemá žádný způsob, jak rozpoznat, že vlastní typy, které procházíte, souvisejí s touto stránkou.

Místo toho vytvořte vlastní odkaz v nabídce Vzhled-> Nabídky. Stačí dát URL, které vrátí svůj vlastní typ a dát mu štítek, pak stiskněte "Přidat do menu".

http://example.com/workshops/

nebo non-pretty-permalinks:

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

to samo o sobě jednoduše vytvoří tlačítko nav, které zobrazí všechny příspěvky s daným typem příspěvků, a bude také přidávat třídu položek aktuálního menu, když kliknete na položku nav - ale ještě to nebude přidávat nav třída na jiné adrese URL než je tato

Poté, co je vytvořen, přejděte do konfigurace pro tuto novou položku a zadejte pole typu vlastního příspěvku do pole „Název atributu“ (můžete také použít pole popisu, ale ten je skryt v možnostech obrazovky pro správu) ve výchozím stavu).

Nyní je třeba zavěsit filtr nav_menu_css_class (který je vypálen pro každou položku nav) a zkontrolovat, zda je zobrazovaný obsah typu příspěvku, který je uveden ve vaší vlastní položce nav:

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;
}

V tomto případě zkontrolujeme, zda obsah pole Atribut titulů není prázdný a zda odpovídá aktuálnímu dotazu typu post_type. Pokud ano, přidáme třídu current-menu-item do pole jeho třídy a vrátíme upravené pole.

Dalo by se to změnit tak, aby odpovídalo názvu položky nav, ale pokud z nějakého důvodu chcete název položky navigovat jinak než obyčejný slim typu příspěvku, pomocí pole Atribut názvu nebo Popis vám tuto flexibilitu umožní.

Pokaždé, když si prohlížíte jednu položku (nebo pravděpodobně i archivní záznamy) typu příspěvku, který odpovídá položce menu nav, tato položka bude mít aktuální položku nabídky CSS třídy, takže vaše zvýraznění bude fungovat.

Žádné stránky nebo šablony stránek potřeba ;-) URL dotaz se stará o načítání správných příspěvků. Vaše šablona smyčky se stará o zobrazování výstupu dotazu. Tato funkce se stará o rozpoznání toho, co se zobrazuje a přidávání třídy CSS.

BONUS

Můžete dokonce automatizovat proces pomocí wp_update_nav_menu_item tím, že máte automaticky generované položky nabídky pro všechny typy příspěvků. V tomto příkladu byste nejprve museli získat $menu_id menu nav, do kterého chcete tyto položky přidat.

$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'
        )
    );
}
29
somatic

místo použití

$ post_type = get_query_var ('post_type');

Zkuste zkusit:

$ post_type = get_post_type ();

V některých případech není v příspěvku nastaven typ příspěvku. Toto je případ výchozího post_type "post", takže pokud chcete zvýraznit příspěvek, který byl uveden na stránce se seznamem, budete ho muset použít. get_very_var () vrací pouze prázdný řetězec pro typy příspěvků, které nejsou vlastní.

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;
}
4
Eric

@Somatic - to je fantazie! Trochu jsem váš kód upravil, takže funguje také pro konkrétní taxonomii (kterou používám pouze pro související post_type). Účelem je použít atribut Title menu k uložení názvu post_type AND názvu taxonomie, oddělené středníkem a pak explodovaného funkcí.

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
tzeldin88

Rozhodl jsem se držet se stránek a používat název šablony stránky jako třída na položce nav. To mi umožňuje, abych se vyhnul tomu, že by se některý z dalších řešení zpochybnil.

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;
    }   
}

Mám také třídy těla přidané do header.php

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

Konečně toto řešení vyžaduje nějaké další css pro použití vybraného/aktivního stavu na vaše položky menu nav. Používám jej k zobrazení archivů taxonomií a typů vlastních příspěvků souvisejících se stránkou jako dětí na této stránce:

/* 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;}
2
Steve

Zde moje řešení, pokud chcete pracovat s wp_list_pages.

přidejte to do svých funkcí

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;
}

Nyní stačí přidat v tabulce wp_options nový řádek s option_name of page_for_custom_post_type-xxxx a option_value s page-ID u chcete připojit.

Možná jste zjistili, že již existuje možnost nazvaná page_for_posts . Pokud u mají pouze 1 vlastní příspěvek typu u můžete nastavit stránku na /wp-admin/options-reading.php v rozevíracím seznamu a navigace nastaví current_page správně.

Myslím, že wordpress jádro by mělo tuto sekci rozšířit o rozevírací seznam pro každý registrovaný typ příspěvku.

2
Temo

@Somatic - Skvělý kód! Udělal jsem jednu změnu sám. Chtěl jsem si ponechat atribut Title pro jeho zamýšlený účel, takže místo toho jsem umístil Custom Post Type slug do rozšířených vlastností nabídky Link Relationship (XFN), které můžete povolit v nabídce Screen Options. Upravil jsem

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

a změnil to na

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

Hezká práce Somatic.

Bohužel, já dont dostat, jak si můžete vypsat své vlastní typy příspěvků na stránce tak, jak vysvětlíte. Pokud nepoužívám stránku-portfolio.php a přidám ji na stránku, vše, co dostanu, je 404 stránek.

Pokud se mi líbí Gavin dělá, jsem upravil funkci trochu odstranit také "current_page_parent" z této stránky blogu.

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;

}

0
Vayu