wake-up-neo.net

Filter wp_nav_menu ()

Ich versuche meine Navigation in 3 einzelne Navigationsleisten aufzuteilen (Level 1, Level 2 und Level3 +). Drei, weil sie über die Site verteilt sind und nur abhängig von der aktuellen Seite angezeigt werden sollen.

-0-------1--------2-------3+- level/depth
Home
 |
 |\___ Lobby
 |
 |\___ Projects
 |       |\___ Project A
 |       |       |\___ Review
 |       |       |\___ Comments
 |       |       \____ Download
 |       \____ Project B
 |               |\___ Review
 |               |\___ Comments
 |               \____ Download
 |\___ Blog
 |
 \____ About
         |\___ Legal
         \____ Contact

Die erste Navigationsleiste mit der Ebene 1 ist immer sichtbar. Die zweite Navigationsleiste (Ebene 2) nur, wenn ich gerade auf der entsprechenden übergeordneten Seite bin. Gleiches gilt für die dritte Navigationsleiste (Level 3+ und höher, da diese Navigationsleiste auch Unterseiten und Unterseiten ... von Level 3 enthält).

Kurz gesagt: Ich möchte alle übergeordneten Menüs in ihren Navigationsleisten und nur die direkten untergeordneten Menüs der aktuellen Seite anzeigen.

Was ich versucht habe:

function my_nav_menu( $args = array() )
{
    $echo = isset( $args['echo'] ) ? (bool)( $args['echo'] ) : true;
    $args['echo'] = false;

    add_filter( 'wp_get_nav_menu_items' , 'my_nav_menu_filter' , 666 , 3 );

    $menu = wp_nav_menu( $args );

    remove_filter( 'wp_nav_menu_objects' , 'my_nav_menu_filter' , 666 );

    if( $echo )
        echo $menu;
    else
        return $menu;
}

function my_nav_menu_filter( $items , $menu , $args )
{
    //var_dump( $args );

    $navLevel = isset( $args['navlevel'] ) ? (int)( $args['navlevel'] ) : 0;

    //echo 'navlevel = ' . $args['navlevel'] . ' | ' . $navLevel;

    if( $navLevel == 1 )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
                unset( $items[$key] );
        }
    }
    else if( $navLevel == 2 )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
            {
                $page = get_page( $item->menu_item_parent );

                if( $page->menu_item_parent == 0 )
                    continue;
            }

            unset( $items[$key] );
        }
    }
    else if( $navLevel == 3 )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
            {
                $page = get_page( $item->menu_item_parent );

                if( $page->menu_item_parent != 0 )
                    continue;
            }

            unset( $items[$key] );
        }
    }
    else
    {
        //var_dump( $items );
    }

    return $items;
}

Aufruf in meiner header.php: <?php my_nav_menu( array( 'echo' => false , 'navlevel' => 1 ) ); ?>

$args ist jedoch auf die Standardwerte gesetzt und mein benutzerdefinierter Eintrag navlevel wird im Filter nicht angezeigt.

Wie kann ich meine Navigationsleiste wie beschrieben aufteilen? Wie lege ich meinen benutzerdefinierten $args- Eintrag fest?

9
nonsensation

Ich glaube ich habe die Antwort bekommen:

function my_nav_menu( $args = array() )
{
    $echo = isset( $args['echo'] ) ? (bool)( $args['echo'] ) : true;

    $args['echo'] = false;

    add_filter( 'wp_nav_menu_objects' , 'my_filter_nav_menu' , 100 , 2 );

    $menu = wp_nav_menu( $args );

    remove_filter( 'wp_nav_menu_objects' , 'my_filter_nav_menu' , 100, 2 );

    if( $echo )
        echo $menu;
    else
        return $menu;
}

Dies ist der Trick: Lassen Sie mich die Menüs ändern und benutzerdefinierte Argumente sind immer noch verfügbar. Ich habe den Filter versehentlich in wp_get_nav_menu_items anstatt in wp_nav_menu_objects eingebunden. Ich habe immer noch Probleme mit der Filterung, aber dies sind wahrscheinlich einige logische Fehler.

BEARBEITEN: Ich werde mein Problem lösen, indem ich Navbar Level 2 und Navbar Level 3+ zu einem kombiniere und sie mit CSS trenne

hier ist der aktuelle PHP-Teil:

function serthy_filter_nav_menu( $items , $args )
{
    $argArray = (array)( $args );

    if( isset( $argArray['toplevel'] ) )
    {
        foreach( $items as $key => $item )
        {
            if( $item->menu_item_parent != 0 )
                unset( $items[$key] );
        }

        return $items;
    }

    global $post;

    $arr = array();

    foreach( $items as $key => $item )
    {
        $parentIDs = get_post_ancestors( $item->ID );

        foreach( $parentIDs as $i => $parentID )
        {
            if( $parentID == $post->ID )
            {
                array_Push( $arr , $item );

                break;
            }
        }
    }

    return $arr;
}
3
nonsensation

Es scheint mir, dass Sie dies durch CSS handhaben können, indem Sie hide die Menüoptionen der unteren Ebene standardmäßig ausblenden und dann show wählen, wenn sie bestimmte Klassen darüber haben.

Auf dieser Codex-Seite sehen Sie die Menüklassen (und auf Ihrer Seite selbst). Für die von Ihnen beschriebene "zweite Ebene" wird angenommen, dass das Menü der ersten Ebene die Ebene 1 und nicht die Ebene 0 ist.

ul > li > ul.sub-menu { display: none; }  /* Hide by default */
ul > li.current-menu-parent > ul.sub-menu { display: block; } /* Show menu */

Und dann etwas Ähnliches für das nächste Level:

ul > li > ul.sub-menu > li > ul.sub-menu{ display: none; }  /* Hide by default */
ul > li > ul.sub-menu > li.current-menu-parent > ul.sub-menu { display: block; }

Offensichtlich ersetzen Sie "Block" durch "Inline-Block" oder was auch immer Ihre Menüs normalerweise eingestellt sind.

Möglicherweise müssen Sie herumspielen, um die richtige Klassenkombination zu finden, aber ich hatte zuvor viel Glück mit dieser Methode. WP legt dort eine Menge Klassen ab, kann sie aber auch verwenden.

1
Amanda Giles