Benutzerdefinierte WordPress-Posttyp-Hierarchie und Menü-Hervorhebung (current_page_parent)

Lesezeit: 7 Minuten

Craigs Benutzeravatar
Craig

Ich habe einen benutzerdefinierten Beitragstyp „Portfolio“ und eine Seite mit einer Vorlage erstellt, die alle Beiträge abruft, die diesem benutzerdefinierten Beitragstyp entsprechen.

Das Problem ist, wenn ich in den eigentlichen Beitrag eindringe, scheint der Beitrag unter „Blog“ in der Hervorhebung des Hauptmenüs zu sitzen (zeigt current_page_parent als Klasse an).

Die Permalink-URL ist korrekt: www.site.com/portfolio/post-slug

Aber das Menü denkt, dass der Elternteil ‘blog’ ist.

Dies ist offensichtlich ein hierarchisches Problem, aber ich weiß nicht, was ich tun soll, um es zu beheben.

Es scheint, dass dies ein Problem mit dem Kerncode von WordPress ist; Der Code, der die Menüklassen generiert, fügt Ihrer Blog-Seite überall current_page_parent hinzu, außer wenn statische Seitenvorlagen angezeigt werden.

(Dies wurde am Rande besprochen unter http://core.trac.wordpress.org/ticket/13543).

Sie können dies jedoch mit benutzerdefiniertem Code umgehen, der den Filter page_css_class verwendet. Fügen Sie beispielsweise etwas in dieser Richtung zu functions.php hinzu (nicht zu 100 % getestet):

function my_page_css_class($css_class, $page) {
    if (get_post_type()=='portfolio' || is_page(57)) {
        if ($page->ID == get_option('page_for_posts')) {
            foreach ($css_class as $k=>$v) {
                if ($v=='current_page_parent') unset($css_class[$k]);
            }
        }
        if ($page->ID==57) {
            $css_class[]='current_page_parent';
        }
    }
    return $css_class;
}
add_filter('page_css_class','my_page_css_class',10,2);

Ersetzen Sie 57 natürlich durch die ID Ihrer Portfolioseite. Dadurch wird current_page_parent beim Drucken der Blog-Seite entfernt und current_page_parent zu Ihrer Portfolio-Seite hinzugefügt, wenn Sie entweder ein einzelnes Portfolio oder die Portfolio-Seite selbst anzeigen.

  • Ich habe es vorerst mit CSS und Body-Klassen gemacht. Danke aber für die Funktion.

    – Craig

    18. Juli 2010 um 14:38 Uhr

Benutzeravatar von Tanuki
Tanuki

Hier ist meine optimierte/erweiterte Version der zuvor vorgeschlagenen Lösungen, die so ziemlich vollständig automatisiert ist. Keine zusätzlichen CSS- oder Menüattribute mehr erforderlich.

Diese Version ruft dynamisch eine Liste benutzerdefinierter Beitragstypen ab, und wenn der aktuelle Beitragstyp ein benutzerdefinierter Beitragstyp ist, entfernt sie die Klasse „current_page_parent“ aus allen Menüpunkten.

Außerdem überprüft es jeden Menüpunkt, um zu sehen, ob es sich um eine Seite mit einer Seitenvorlage wie “page-{custom_post_type_slug}.php” handelt, und wenn ja, fügt es die Klasse “current_page_parent” hinzu.

Die Filterpriorität ist 1, da einige Themes die current_page_parent/etc. Klassen mit einer Klasse wie ‘active’ (z. B. ‘roots’ tut dies), also muss dieser Filter zuerst ausgeführt werden.

Schließlich werden 3 statische Variablen verwendet, da diese Funktion wiederholt aufgerufen wird und diese (offensichtlich) bei allen Aufrufen gleich bleiben.

function theme_current_type_nav_class($css_class, $item) {
    static $custom_post_types, $post_type, $filter_func;

    if (empty($custom_post_types))
        $custom_post_types = get_post_types(array('_builtin' => false));

    if (empty($post_type))
        $post_type = get_post_type();

    if ('page' == $item->object && in_array($post_type, $custom_post_types)) {
        $css_class = array_filter($css_class, function($el) {
            return $el !== "current_page_parent";
        });

        $template = get_page_template_slug($item->object_id);
        if (!empty($template) && preg_match("/^page(-[^-]+)*-$post_type/", $template) === 1)
            array_push($css_class, 'current_page_parent');

    }

    return $css_class;
}
add_filter('nav_menu_css_class', 'theme_current_type_nav_class', 1, 2);

PS. Nur um auf einen Mangel in allen Nicht-CSS-Lösungen hinzuweisen, die ich bisher gesehen habe, einschließlich meiner eigenen: Etwas, das nicht berücksichtigt wird, ist das Hervorheben des Menüelements Eltern/Vorfahr eines Elements, das auf eine Seite verweist, die Beiträge des aktuellen Benutzers anzeigt Post-Typ. Betrachten Sie einen benutzerdefinierten Beitragstyp „Produkt“ und ein Menü wie:

Home  Company  News  Contact
      |
      \--About Us
      \--Products

„Produkte“ ist eine Seite mit einem Template „page-product.php“ und zeigt eine Übersicht von Beiträgen des Typs „Produkt“. Es ist aufgrund der geposteten Lösung hervorgehoben. Allerdings sollte „Company“ als übergeordneter/vorfahrender Name ebenfalls hervorgehoben werden, ist es aber nicht. Etwas zu beachten.

  • Danke. Dies löste mein Problem mit dem Blog-Beitrag, der eine aktive Klasse erhielt, während er einen benutzerdefinierten Beitragstyp anzeigte

    – Mattijs

    13. Februar 2015 um 5:14 Uhr

WP-Ticket: http://core.trac.wordpress.org/ticket/16382

function fix_blog_menu_css_class( $classes, $item ) {
    if ( is_tax( 'my-cat-tax' ) || is_singular( 'my-post-type' ) || is_post_type_archive( 'my-post-type' ) ) {
        if ( $item->object_id == get_option('page_for_posts') ) {
            $key = array_search( 'current_page_parent', $classes );
            if ( false !== $key )
                unset( $classes[ $key ] );
        }
    }

    return $classes;
}
add_filter( 'nav_menu_css_class', 'fix_blog_menu_css_class', 10, 2 );

Benutzeravatar von Vayu Robins
Vayu Robins

Ich habe mich noch etwas umgesehen und einen anderen Weg gefunden, dies zu tun.

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2);
function current_type_nav_class($css_class, $item)
{
    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);
        });
    }

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

    return $css_class;
}

Ich habe Hilfe aus diesem Beitrag erhalten und ihn dann geändert, um auch die Klasse „current_page_parent“ von der Blog-Seite zu entfernen.
https://wordpress.stackexchange.com/questions/3014/highlighting-wp-nav-menu-ancestor-class-wo-children-in-nav-structure/3034#3034

Herzlich Vayu

Wie unter erklärt https://core.trac.wordpress.org/ticket/16382, .current_page_parent entspricht “alles, was keine Seite ist” aus Gründen der Abwärtskompatibilität (beachten Sie, dass dies vor 10 Jahren als rückwärts angesehen wurde …), sodass Themes es heutzutage wirklich nicht mehr verwenden sollten.

Die einfachste und effizienteste Lösung (da im Gegensatz zu früheren Antworten nicht bei jedem Seitenladen zusätzlicher Code ausgeführt werden muss) besteht darin, das CSS Ihres Designs zu ändern, um die Verwendung von zu ersetzen .current_page_parent Klassenwahl mit .current-menu-parent, was das Richtige tut. (NB Unterstriche vs. Bindestriche.)

Wenn Sie ein Design eines Drittanbieters verwenden und es nicht direkt ändern möchten, können Sie dessen Eigenschaften in Ihrem eigenen Stylesheet überschreiben. Zum Beispiel, wenn Ihr Thema Folgendes hat:

.current_page_parent > a {
    border-bottom: 4px solid blue;
}

dann würden Sie im Stylesheet Ihres untergeordneten Themas dies tun, um seine Effekte aufzuheben und sie auf die richtige Klasse anzuwenden:

.current_page_parent > a {
    border-bottom: transparent !important;  /* Cancel out incorrect styling */
}
.current-menu-parent > a {
    border-bottom: 4px solid blue;   /* Add styling correctly */
}

Dies ist nur ein Beispiel – der richtige Weg hängt davon ab, wie Ihr Thema diese Links gestaltet.

  • Ich hatte das gleiche Problem, aber diese Eigenschaften haben mir 7 Jahre später geholfen! Vielen Dank 😉

    – Kris

    10. September 2021 um 7:32 Uhr


Benutzeravatar von dtbaker
dtbäcker

Hier ist eine Lösung, die für mich funktioniert hat, ohne meinen benutzerdefinierten Beitragstyp oder meine Menü-ID oder Seiten-ID im Code definieren zu müssen:

http://dtbaker.net/web-development/how-to-stop-wordpress-automatically-highlighting-the-blog-page-in-the-menu/

function dtbaker_wp_nav_menu_objects($sorted_menu_items, $args){
    // this is the code from nav-menu-template.php that we want to stop running
    // so we try our best to "reverse" this code wp code in this filter.
    /* if ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && empty( $wp_query->is_page ) && $home_page_id == $menu_item->object_id )
            $classes[] = 'current_page_parent'; */

    // check if the current page is really a blog post.
    //print_r($wp_query);exit;
    global $wp_query;
    if(!empty($wp_query->queried_object_id)){
        $current_page = get_post($wp_query->queried_object_id);
        if($current_page && $current_page->post_type=='post'){
            //yes!
        }else{
            $current_page = false;
        }
    }else{
        $current_page = false;
    }


    $home_page_id = (int) get_option( 'page_for_posts' );
    foreach($sorted_menu_items as $id => $menu_item){
        if ( ! empty( $home_page_id ) && 'post_type' == $menu_item->type && empty( $wp_query->is_page ) && $home_page_id == $menu_item->object_id ){
            if(!$current_page){
                foreach($sorted_menu_items[$id]->classes as $classid=>$classname){
                    if($classname=='current_page_parent'){
                        unset($sorted_menu_items[$id]->classes[$classid]);
                    }
                }
            }
        }
    }
    return $sorted_menu_items;
}
add_filter('wp_nav_menu_objects','dtbaker_wp_nav_menu_objects',10,2);

  • Ich hatte das gleiche Problem, aber diese Eigenschaften haben mir 7 Jahre später geholfen! Vielen Dank 😉

    – Kris

    10. September 2021 um 7:32 Uhr


1394780cookie-checkBenutzerdefinierte WordPress-Posttyp-Hierarchie und Menü-Hervorhebung (current_page_parent)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy