Filtro wp_nav_menu ()

9

Eu tento dividir minha navegação em 3 barras de navegação únicas (nível 1, nível 2 e nível 3 +). Três porque estão separados no site e só devem aparecer dependendo da página atual.

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

A primeira barra de navegação contendo o nível 1 é sempre visível. A segunda barra de navegação (nível 2) somente quando estou atualmente na página pai correspondente. O mesmo vale para a terceira barra de navegação (nível 3+, mais porque esta barra de navegação também conterá subpáginas e sub-páginas ... do nível 3).

Resumindo: quero exibir todos os menus pai em suas barras de navegação e somente os filhos diretos da página atual.

O que eu tentei:

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

Chamando isso no meu header.php: <?php my_nav_menu( array( 'echo' => false , 'navlevel' => 1 ) ); ?>

No entanto, $args está definido para os valores padrão e minha entrada personalizada navlevel isnt é mostrada no filtro.

Como posso dividir minha barra de navegação conforme descrito? Como defino meu $args -entry personalizado?

    
por nonsensation 07.04.2014 / 20:26

2 respostas

3

Acho que recebi a resposta:

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

Isso faz o truque: permite alterar os itens de menu e os argumentos personalizados ainda estão disponíveis. Eu acidentalmente conectei o filtro em wp_get_nav_menu_items em vez de wp_nav_menu_objects . Eu ainda tenho problemas com a filtragem, no entanto, estes são provavelmente alguns erros lógicos ..

EDIT: eu vou resolver o meu problema, combinando o nível de navbar 2 e nível de navbar 3 + em um e separando-os com css

heres a parte atual do 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;
}
    
por nonsensation 08.04.2014 / 00:20
1

Parece-me que você poderia lidar com isso por meio do CSS, pois você poderia ocultar as opções de menu de nível inferior por padrão e, em seguida, optar por mostrá-las se elas tivessem certas classes acima deles.

Em esta página do Codex , você pode ver as classes de menu (e em sua própria página). Então, para o "segundo nível" que você descreveu, assumindo que o primeiro nível de menu é nível 1 - não 0.

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

E então algo semelhante para o próximo nível abaixo:

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

Obviamente, substitua "block" por "inline-block" ou qualquer que seja o seu menu normalmente configurado.

Você pode precisar brincar para encontrar a combinação certa de classes, mas já tive sorte com esse método antes. WP deixa cair uma tonelada de classes lá, também pode usá-las.

    
por Amanda Giles 08.04.2014 / 01:23