Clasa current-menu-item pentru părintele unui custom post type

4 nov. 2013, 19:48:02
Vizualizări: 16K
Voturi: 1

Am o problemă cu meniul meu și un custom post type.

Am un custom post type numit "servicii". Am creat o pagină nouă pentru acesta numită Servicii. Pe acea pagină afișez o listă cu toate postările din acel custom post type. Clasa current-menu-item funcționează cum trebuie.

Problema apare când fac clic pe unul dintre servicii și merg la mysite.com/servicii/serviciu-1, clasa current-menu-item de pe pagina Servicii din meniu dispare. Trebuie să arăt că această postare curentă este un copil al paginii Servicii.

Toate elementele de meniu au același HTML:

<li id="menu-item-23" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23"><a href="http://localhost/wordpress/servicii/">Servicii</a></li>

Nu există nicio clasă CSS pe care aș putea să o folosesc pentru a stiliza acest link ca părinte. Ceva de genul current-menu-parent sau similar. Cum aș putea rezolva această problemă? Mulțumesc.

2
Comentarii

s-ar putea face probabil prin jQuery... sunt toate aceste posturi de tip Service în meniu?

GhostToast GhostToast
4 nov. 2013 20:00:52

@GhostToast de fapt este doar un singur element în meniu numit Servicii. Când dai click, deschide pagina Servicii care are o buclă și afișează toate postările de servicii.

Richard Mišenčík Richard Mišenčík
4 nov. 2013 21:27:15
Toate răspunsurile la întrebare 4
9

De obicei includ următoarea variabilă, filtru și metodă în plugin-urile mele pentru a gestiona acest caz. Nu am fost niciodată sigur dacă aceasta este calea "corectă" de abordare, dar pare mai bună decât aplicarea ei cu JavaScript.

class Plugin_Name {
    private $parent = 'services'; // ideal ar fi ca aceasta să fie o setare în plugin, nu o variabilă hard-codată în cazul în care slug-ul paginii se schimbă

    function __construct() {
        // Adaugă clase la 'parent'
        add_filter( 'nav_menu_css_class', array( &$this, 'nav_parent_class' ), 10, 2 );
    }

    function nav_parent_class( $classes, $item ) {

        if ( $this->nicename == get_post_type() && ! is_admin() ) {
            global $wpdb;

            // elimină orice clasă activă din navigație (blog-ul primește de obicei clasa current_page_parent pe paginile/postările individuale CPT)
            $classes = array_filter($classes, ($class == 'current_page_item' || $class == 'current_page_parent' || $class == 'current_page_ancestor'  || $class == 'current-menu-item' ? false : true ));

            // obține informațiile despre pagină
            // - ne interesează doar post_name pentru a putea fi comparat cu slug-ul tipului de postare
            $page = get_page_by_title( $item->title, OBJECT, 'page' );

            // verifică dacă slug-ul se potrivește cu post_name
            if( $page->post_name == $this->parent ) {
                $classes[] = 'current_page_parent';
            }

        }

        return $classes;
    }
}

La cererea ta, varianta non-plugin. Nu am testat acest cod pentru erori, doar l-am adaptat din clasa de mai sus, dar ar trebui să te îndrepte în direcția corectă:

add_filter( 'nav_menu_css_class', 'nav_parent_class', 10, 2 );

function nav_parent_class( $classes, $item ) {
    $cpt_name = 'service';
    $parent_slug = 'services';

    if ( $cpt_name == get_post_type() && ! is_admin() ) {
        global $wpdb;

        // elimină orice clasă activă din navigație (blog-ul primește de obicei clasa current_page_parent pe paginile/postările individuale CPT)
        $classes = array_filter($classes, ($class == 'current_page_item' || $class == 'current_page_parent' || $class == 'current_page_ancestor'  || $class == 'current-menu-item' ? false : true ));

        // obține informațiile despre pagină
        // - ne interesează doar post_name pentru a putea fi comparat cu slug-ul tipului de postare
        $page = get_page_by_title( $item->title, OBJECT, 'page' );

        // verifică dacă slug-ul se potrivește cu post_name
        if( $page->post_name == $parent_slug ) {
            $classes[] = 'current_page_parent';
        }

    }

    return $classes;
}
4 nov. 2013 20:05:44
Comentarii

Cum aș putea face asta fără un plugin, aș dori să-l inserez în functions.php dar presupun că trebuie modificat.

Richard Mišenčík Richard Mišenčík
4 nov. 2013 21:27:34

Am actualizat răspunsul meu cu o metodă de a face asta dacă CPT-ul tău nu este creat ca un plugin.

Joey Yax Joey Yax
4 nov. 2013 22:44:52

Asta nu pare să funcționeze pentru mine. Am schimbat variabilele dar tot nu merge. Dacă am înțeles corect, codul verifică numele postării și îl compară cu slug-ul? Nu cred că ar funcționa deoarece CPT-ul meu se numește "services". Dar folosesc rewrite la "sluzby", care în limba mea se traduce în "servicii". Dar postările mele de servicii nu conțin acel slug, adică serviciul poate fi numit de exemplu Webdesign, nu Service Webdesign.

Deci pagina folosită pentru afișarea postărilor mele de servicii este localhost/wordpress/sluzby. Apoi postările individuale sunt la localhost/wordpress/sluzby/numele-postului.

Richard Mišenčík Richard Mišenčík
4 nov. 2013 22:54:59

Verifică două lucruri: 1) Dacă postul vizualizat este din tipul tău personalizat de post ($cpt_name) și 2) caută un element de navigație cu slug-ul egal cu $parent_slug. Dacă ambele condiții se îndeplinesc, adaugă clasa current_page_parent acelui element de navigație.

Joey Yax Joey Yax
5 nov. 2013 02:01:26

Nu sunt sigur dacă fac ceva greșit, dar încă nu funcționează. Iată codul meu actual:

function nav_parent_class( $classes, $item ) { $cpt_name = 'services'; $parent_slug = 'sluzby';

if ...

return $classes;

}

Deci numele tipului meu de post personalizat este "services" și URL-ul pentru pagina de servicii este localhost/wordpress/sluzby. Apoi fiecare serviciu individual este aici localhost/wordpress/sluzby/numele-serviciului.

Am verificat codul sursă, dar clasa nu este adăugată și toate celelalte clase au dispărut. De asemenea, am modificat CSS-ul meu pentru a include și stilurile pentru această clasă.

Richard Mišenčík Richard Mišenčík
5 nov. 2013 13:19:51

Lucru ciudat este că acum, când am comentat linia $classes = array_filter... totul funcționează. Ceea ce este foarte ciudat.

Richard Mišenčík Richard Mišenčík
6 nov. 2013 14:23:56

Mă bucur că ai reușit să-l faci să funcționeze! Faptul că acea linie este comentată ar trebui să fie în regulă. Mă îngrijorează însă că, fiind comentată, există o mică șansă ca blogul (dacă îl ai în navigare) să fie evidențiat în același timp când vizualizezi o pagină singulară pentru CPT-ul tău.

Joey Yax Joey Yax
8 nov. 2013 04:05:03

Nu am un blog, așa că e în regulă, poate dacă l-aș avea ar funcționa cu codul complet, fără a comenta linia cu clasele :) Mulțumesc din nou. Am ales răspunsul tău ca fiind cel mai bun.

Richard Mišenčík Richard Mišenčík
9 nov. 2013 14:44:24

Reține că acest lucru funcționează doar dacă elementul din navigare are același titlu ca pagina. Nu uita că utilizatorii pot seta un titlu diferit în navigare față de cel al paginii.

adamtomat adamtomat
26 iun. 2014 11:06:10
Arată celelalte 4 comentarii
1

Acest cod adaugă clasa 'current-menu-item' elementului părinte din meniu pentru CPT-ul copil, taxonomia personalizată sau articolul standard, în cazul în care nu aveți o structură de meniu imbricată în panoul de administrare - doar dacă aveți un meniu de 'nivel 0'. De exemplu - dacă aveți o pagină Produse, care afișează o grilă de produse și accesați un singur produs - WordPress nu va recunoaște elementul părinte din meniu. Codul de mai jos îmbunătățește această situație:

function additional_active_item_classes( $classes = array(), $menu_item = false ) {
    // taxonomie personalizată
    if ( $menu_item->title == 'Pagina Taxonomie Personalizată' && is_tax('custom_tax') ) {
        $classes[] = 'current-menu-item';
    }
    // post type personalizat single
    if ( $menu_item->title == 'Pagina Post Type Personalizat' && is_singular('products') ) {
        $classes[] = 'current-menu-item';
    }
    // articol blog single
    if ( $menu_item->title == 'Pagina Blog' && is_singular('post') ) {
        $classes[] = 'current-menu-item';
    }
    return $classes;
}
add_filter( 'nav_menu_css_class', 'additional_active_item_classes', 10, 2 );
5 apr. 2019 13:10:59
Comentarii

Salut Marek, deși codul tău poate fi corect, ai putea să detaliezi și să explici puțin de ce acesta este răspunsul și cum funcționează, astfel încât și alți oameni să poată învăța din el?

Krzysiek Dróżdż Krzysiek Dróżdż
5 apr. 2019 13:40:12
0

Cod final:

function nav_parent_class($classes, $item) {
    $cpt_name = 'services'; // Numele custom post type
    $parent_slug = 'sluzby'; // Slug-ul paginii părinte

    // Verificăm dacă suntem pe un post de tipul CPT și nu în admin
    if ($cpt_name == get_post_type() && !is_admin()) {
        global $wpdb;

        // Obținem informațiile paginii (ne interesează doar post_name pentru comparație cu slug-ul CPT)
        $page = get_page_by_title($item->title, OBJECT, 'page');

        // Verificăm dacă slug-ul paginii se potrivește cu slug-ul părintelui
        if( $page->post_name == $parent_slug ) {
            $classes[] = 'current_page_parent'; // Adăugăm clasa pentru elementul părinte curent
        }

    }

    return $classes; // Returnăm clasele modificate
}

// Adăugăm filtrul pentru clasele din meniul de navigare
add_filter('nav_menu_css_class', 'nav_parent_class', 10, 2);
6 nov. 2013 17:48:32
7

În mod normal, există o clasă numită .current-menu-ancestor adăugată elementelor părinte din navigație.

Dacă această clasă lipsește, consultă acest articol: Cum să incluzi clasa 'current-menu-ancestor' pe un meniu de tip post personalizat în WordPress?

5 nov. 2013 12:24:20
Comentarii

nu funcționează pentru mine. Ar putea fi din cauză că folosesc rewrite și, prin urmare, am nume diferite pentru custom post type și pentru pagina în sine?

Richard Mišenčík Richard Mišenčík
5 nov. 2013 13:24:02

Folosești un meniu personalizat?

Joe Joe
5 nov. 2013 14:06:42

Acesta este codul pe care îl folosesc: wp_nav_menu(array( 'container' => false, 'container_class' => '', 'menu' => '', 'theme_location' => 'main-nav', 'items_wrap' => '<ul id="menu">%3$s</ul>', 'fallback_cb' => 'rm_main_nav_fallback' ));

Richard Mišenčík Richard Mišenčík
5 nov. 2013 14:29:02

Și ai meniul definit în zona de administrare sub Appearance->Menus. Dacă da, și meniul tot nu oferă clasa. Aceasta nu este o problemă pe care am întâlnit-o.

Joe Joe
5 nov. 2013 14:40:32

Da, am creat un Meniu cu toate linkurile în el. Cred că ar putea fi o problemă legată de rescriere, deoarece numele CPT-ului meu este services dar URL-ul pentru acea pagină este wordpress/sluzby. Sunt complet pierdut. Mai este ceva aș putea încerca?

Richard Mišenčík Richard Mišenčík
5 nov. 2013 14:50:58

Hmm, dacă crezi că problema ar putea fi legată de rescriere, ai încercat să nu rescrii CPT-ul? Doar pentru a confirma, paginile copil sunt setate ca 'Sub menu items' în meniu?

Joe Joe
5 nov. 2013 15:03:03

Am încercat acum, nu a funcționat. Am încercat altceva totuși, un exemplu de bază din codex-ul wp pentru această funcție. Iată-l:

function rm_custom_services_class($classes, $item) {

 if(is_single() && $item->title == "Služby") {
         $classes[] = "current_page_parent";
 }

 return $classes;

}

Asta e tot și funcționează. Mă întreb doar dacă este posibil să schimb $item->title = "Služby" în ceva de genul $item->slug == 'sluzby'. În caz că numele paginii s-ar schimba.

Richard Mišenčík Richard Mišenčík
5 nov. 2013 15:15:35
Arată celelalte 2 comentarii