Фільтр wp_nav_menu ()


9

Я намагаюся розділити свою навігацію на 3 одиничні панелі навігації (рівень 1, рівень 2 та рівень 3 +). Три, тому що вони розділені по сайту, і вони повинні з’являтися лише залежно від поточної сторінки.

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

Перший навбар, що містить рівень 1, завжди видно. Другий навігаційний рівень (рівень 2) лише тоді, коли вони наразі знаходяться на відповідній батьківській сторінці. Те саме стосується і третього навбар (рівень 3+, плюс тому, що цей навібар також буде містити підсторінки та підпункти ... рівня 3).

Коротше кажучи: я хочу відобразити всі батьківські меню у своїх навігаційних панелях та лише прямі підказки поточної сторінки.

Те, що я пробував:

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

Викликаю це у своєму header.php: <?php my_nav_menu( array( 'echo' => false , 'navlevel' => 1 ) ); ?>

Однак $argsвстановлено значення за замовчуванням, і мій власний запис navlevelне відображається у фільтрі.

Як я можу розділити свій навбар як описано? Як встановити свій власний набір $args?


2
Добрий день і ласкаво просимо до WPSE. Я повинен привітати вас з епічним побудованим питанням для першого таймера. Добре побудовані чіткі питання завжди привертають багато уваги при хороших відповідях. +1
Пітер Гусен

3
Відповідь на це передбачає користувацький клас Уокера, можливо, це допоможе будь-яким потенційним відповідачам
Том Дж. Ноуелл

Дякую. Я копався у php / wp лише у ці вихідні, так що я не цей знайомий. Я спробував власну Walker, однак Walker обробляє лише один предмет за один раз, тому я не можу порівняти його з поточним елементом. І фільтр не приймає мого спеціального аргументу.
Гммм

Відповіді:


3

Я думаю, що я отримав відповідь:

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

Це робить трюк: дозволяє мені змінити меню, а користувацькі аргументи все ще доступні. Я випадково зачепив фільтр wp_get_nav_menu_itemsзамість wp_nav_menu_objects. У мене все ще виникають проблеми з фільтруванням, проте це, мабуть, деякі логічні помилки.

EDIT: я вирішив свою проблему, поєднавши рівень navbar 2 та navbar рівень 3+ в один і відокремивши їх css

ось поточна частина php:

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

Мені добре здається з першого погляду. У вас є проблеми з цим кодом? Sidenote: Ви можете скоротити своє перше твердження:$echo = ! isset( $args['echo'] ) ?: $args['echo'];
кайзер

1

Мені здається , що ви могли б впоратися з цим з допомогою CSS в тому , що ви могли б приховати нижні опції меню рівня за замовчуванням, а потім виберіть показати їм , якщо у них є певні класи над ними.

На цій сторінці Codex ви можете побачити класи меню (і на самій своїй сторінці). Отже, для описаного вами "другого рівня", якщо припустити, що меню першого рівня - це рівень 1, а не 0.

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

А потім щось подібне для наступного рівня вниз:

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

Очевидно, замініть "блок" на "вбудований блок" або все, що зазвичай встановлено у ваших меню.

Можливо, вам доведеться пограти, щоб знайти правильну комбінацію класів, але я вже пощастив із цим методом. WP скидає туну класів там, можливо, також може їх використовувати.


Дякую, я використовував кілька класів css для своїх наві-барів! :)
безглуздість

Якщо ви вирішили скористатися цим рішенням, чи можете ви позначити мою відповідь прийнятою? Дякую.
Аманда Гілз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.