Exiba uma parte / ramificação da árvore de menus usando wp_nav_menu ()

109

Eu tenho um menu definido no WP Admin que se parece com isso:

texto alternativo

Quero poder exibir todos os links filhos na barra lateral sempre que estiver na página pai. Por exemplo, se o usuário estiver na minha página "Sobre nós", desejo que uma lista dos 4 links destacados em verde apareça na barra lateral.

Eu olhei para a documentação de wp_nav_menu () e ela não parece ter nenhuma maneira interna de especificar um nó específico de um determinado menu para usar como ponto de partida na geração dos links.

Criei uma solução para uma situação semelhante que se baseava nos relacionamentos criados pelo pai da página, mas estou procurando um que use especificamente o sistema de menus. Qualquer ajuda seria apreciada.

jessegavin
fonte
2
Então, você deseja manter o menu inteiro como um menu personalizado, mas criar um andador personalizado que o exiba expandindo apenas a subárvore ativa? Como esse código , mas estendendo wp_nav_menu em vez de wp_list_pages? Recentemente, fiz algo semelhante e poderia postar o código se é isso que você está procurando ...
goldenapples
1
@ goldenapples, é exatamente isso que eu estou procurando. Se você não se importa de postar seu código como resposta, ficaria muito grato.
Jessegavin
1
Gostaria de saber que uma funcionalidade útil tão óbvia ainda não a construa. No geral, é muito útil para qualquer site que faça "CMS".
hakre
Estou tentando resolver o problema acima ou algo similar. Como alternativa, eu vim com uma solução CSS aqui: stackoverflow.com/q/7640837/518169
hyperknot

Respostas:

75

Ainda estava em minha mente, então eu a revisitei e montei esta solução, que não depende tanto do contexto:

add_filter( 'wp_nav_menu_objects', 'submenu_limit', 10, 2 );

function submenu_limit( $items, $args ) {

    if ( empty( $args->submenu ) ) {
        return $items;
    }

    $ids       = wp_filter_object_list( $items, array( 'title' => $args->submenu ), 'and', 'ID' );
    $parent_id = array_pop( $ids );
    $children  = submenu_get_children_ids( $parent_id, $items );

    foreach ( $items as $key => $item ) {

        if ( ! in_array( $item->ID, $children ) ) {
            unset( $items[$key] );
        }
    }

    return $items;
}

function submenu_get_children_ids( $id, $items ) {

    $ids = wp_filter_object_list( $items, array( 'menu_item_parent' => $id ), 'and', 'ID' );

    foreach ( $ids as $id ) {

        $ids = array_merge( $ids, submenu_get_children_ids( $id, $items ) );
    }

    return $ids;
}

Uso

$args = array(
    'theme_location' => 'slug-of-the-menu', // the one used on register_nav_menus
    'submenu' => 'About Us', // could be used __() for translations
);

wp_nav_menu( $args );
Rarst
fonte
Técnica adorável! Posso perguntar algo possivelmente relacionado a este: Como você exibirá o conteúdo dessas páginas de submenu listadas no modelo?
Daniel.tosaba
2
@ daniel.tosaba, você precisará subclassificar ou usar filtros na Walker_Nav_Menuaula. Como todas as coisas do menu demais para comentar - faça uma nova pergunta sobre isso?
Rarst 22/08/2012
3
Uma resposta tão fantástica. Muito obrigado. Essa deve ser realmente uma opção padrão no WordPress.
22812 Dotty
3
Realmente limpo. Se alguém estiver interessado, faça o mesmo, mas por ID da página, altere a wp_filter_object_listlinha parawp_filter_object_list( $items, array( 'object_id' => $args->submenu ), 'and', 'ID' );
Ben
14

@ goldenapples: Sua classe Walker não funciona. Mas a ideia é realmente boa. Eu criei um andador com base na sua ideia:

class Selective_Walker extends Walker_Nav_Menu
{
    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = '';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields['id'];
        $parent_field = $this->db_fields['parent'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field )
                $top_level_elements[] = $e;
            else
                $children_elements[ $e->$parent_field ][] = $e;
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );  //added by continent7
        foreach ( $top_level_elements as $e ){  //changed by continent7
            // descend only on current tree
            $descend_test = array_intersect( $current_element_markers, $e->classes );
            if ( !empty( $descend_test ) ) 
                $this->display_element( $e, $children_elements, 2, 0, $args, $output );
        }

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
         /* removed by continent7
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }
        */
         return $output;
    }
}

Agora você pode usar:

<?php wp_nav_menu( 
   array(
       'theme_location'=>'test', 
       'walker'=>new Selective_Walker() ) 
   ); ?>

A saída é uma lista que contém o elemento raiz atual e seus filhos (não seus filhos). Def: Elemento raiz: = O item de menu de nível superior que corresponde à página atual ou é pai de uma página atual ou pai de um pai ...

Isso não responde exatamente à pergunta original, mas quase, já que ainda existe o item de nível superior. Isso é bom para mim, porque quero o elemento de nível superior como um título da barra lateral. Se você deseja se livrar disso, pode ser necessário substituir o display_element ou usar um analisador de HTML.

davidn
fonte
12

Oi @jessegavin :

Os menus de navegação são armazenados em uma combinação de tipos de postagem personalizados e taxonomias personalizadas. Cada menu é armazenado como um termo (ou seja, "Sobre o menu" , encontrado em wp_terms) de uma taxonomia personalizada (ou seja nav_menu, encontrado em wp_term_taxonomy).

Cada item do menu Nav é armazenado como uma postagem de post_type=='nav_menu_item'(por exemplo, "Sobre a empresa" , encontrada em wp_posts) com seus atributos armazenados como meta meta (in wp_postmeta) usando um meta_keyprefixo de _menu_item_*onde _menu_item_menu_item_parenté o ID da postagem do item do menu Nav do pai do item de menu.

O relacionamento entre menus e itens de menu é armazenado em wp_term_relationshipsonde object_idse refere ao $post->IDitem de menu Nav e o $term_relationships->term_taxonomy_idse refere ao menu definido coletivamente em wp_term_taxonomye wp_terms.

Tenho certeza de que seria possível conectar os dois 'wp_update_nav_menu'e 'wp_update_nav_menu_item'criar menus reais wp_termse um conjunto paralelo de relações wp_term_taxonomye wp_term_relationshipsonde cada item do menu Nav que possui itens de sub-menu Nav também se torna seu próprio menu Nav.

Você também gostaria de conectar 'wp_get_nav_menus' (o que sugeri ser adicionado ao WP 3.0 com base em algum trabalho semelhante que eu fazia alguns meses atrás) para garantir que os menus de navegação gerados não sejam exibidos para manipulação pelo usuário no administrador; caso contrário, eles sairia da sincronização muito rápido e você teria um pesadelo de dados na sua mão.

Soa como um projeto divertido e útil, mas é um pouco mais de código e teste do que posso me dar ao luxo de lidar agora, em parte porque qualquer coisa que sincronize dados tende a ser uma PITA quando se trata de resolver todos os erros (e porque clientes pagantes estão me pressionando para fazer as coisas. :) Mas, armado com as informações acima, sou bastante desenvolvedor de plugins WordPress motivado que poderia codificá-lo, se quisesse.

É claro que você percebe agora que, se codificá-lo, é obrigado a publicá-lo aqui para que todos possamos nos beneficiar da sua generosidade! :-)

MikeSchinkel
fonte
Não tenho certeza se estou seguindo o que você está dizendo. Estou procurando uma solução somente leitura para exibir "submenus" relacionados à página atual em que um usuário está. Estamos falando sobre a mesma coisa? - Agradeço sua explicação mais profunda sobre o esquema do banco de dados.
Jessegavin
@ jessegavin - Sim, se você quiser ligar wp_nav_menu(), precisará clonar os menus porque wp_nav_menu()está fortemente acoplado à estrutura do menu . A outra opção é copiar o wp_nav_menu()código e fazer as modificações necessárias para exibir como um submenu.
21810 MikeSchinkel
10

Esta é uma extensão de walker que deve fazer o que você está procurando:

class Selective_Walker extends Walker_Nav_Menu
{

    function walk( $elements, $max_depth) {

        $args = array_slice(func_get_args(), 2);
        $output = '';

        if ($max_depth < -1) //invalid parameter
            return $output;

        if (empty($elements)) //nothing to walk
            return $output;

        $id_field = $this->db_fields['id'];
        $parent_field = $this->db_fields['parent'];

        // flat display
        if ( -1 == $max_depth ) {
            $empty_array = array();
            foreach ( $elements as $e )
                $this->display_element( $e, $empty_array, 1, 0, $args, $output );
            return $output;
        }

        /*
         * need to display in hierarchical order
         * separate elements into two buckets: top level and children elements
         * children_elements is two dimensional array, eg.
         * children_elements[10][] contains all sub-elements whose parent is 10.
         */
        $top_level_elements = array();
        $children_elements  = array();
        foreach ( $elements as $e) {
            if ( 0 == $e->$parent_field )
                $top_level_elements[] = $e;
            else
                $children_elements[ $e->$parent_field ][] = $e;
        }

        /*
         * when none of the elements is top level
         * assume the first one must be root of the sub elements
         */
        if ( empty($top_level_elements) ) {

            $first = array_slice( $elements, 0, 1 );
            $root = $first[0];

            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( $root->$parent_field == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }
        }

        $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );

        foreach ( $top_level_elements as $e ) {

            // descend only on current tree
            $descend_test = array_intersect( $current_element_markers, $e->classes );
            if ( empty( $descend_test ) )  unset ( $children_elements );

            $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );
        }

        /*
         * if we are displaying all levels, and remaining children_elements is not empty,
         * then we got orphans, which should be displayed regardless
         */
        if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
            $empty_array = array();
            foreach ( $children_elements as $orphans )
                foreach( $orphans as $op )
                    $this->display_element( $op, $empty_array, 1, 0, $args, $output );
         }

         return $output;
    }

}

Baseado livremente no código dos mfields, referi no meu comentário anterior. Tudo o que faz é verificar ao percorrer o menu se o elemento atual é (1) o item de menu atual ou (2) um ancestral do item de menu atual e expande a subárvore abaixo apenas se uma dessas condições for verdadeira . Espero que funcione para voce.

Para usá-lo, basta adicionar um argumento "walker" ao chamar o menu, ou seja:

<?php wp_nav_menu( 
   array(
       'theme_location'=>'test', 
       'walker'=>new Selective_Walker() ) 
   ); ?>
maçãs douradas
fonte
Ah ... acabei de reler sua pergunta e percebi que a tinha entendido mal a princípio. Este andador mostrará todos os outros itens de menu de nível superior, apenas não os expandirá. Não era exatamente isso que você queria fazer. Ainda assim, esse código pode ser modificado da maneira que você desejar. Basta olhar para o loop $top_level_elementse adicionar seu próprio teste antes da chamada para $this->display_element.
goldenapples 16/10/10
É possível fazer com que esta classe mostre a profundidade da subpágina atual? Ou seja ... Se eu tiver uma profundidade de três ou mais níveis, o terceiro e os níveis subsequentes serão mostrados para a (sub) página atual? No momento, só mostra A> B, e não> C (sendo o terceiro (nível)
Zolomon
@Zolomon - Não sei se entendi sua pergunta. Isso deve expandir a árvore inteira em qualquer item de menu com as classes 'item de menu atual', 'pai do menu atual' ou 'ancestral do menu atual'. Quando eu testo, ele exibe todos os níveis de subpáginas no menu. O que você está pensando em fazer?
goldenapples
Talvez você queira passar um depthparâmetro para a chamada wp_nav_menu, caso seu tema esteja substituindo o padrão de 0 (mostrar todos os níveis)?
goldenapples
8

Atualização: Eu fiz isso em um plugin. Faça o download aqui .


Eu mesmo precisava resolver isso e acabei escrevendo um filtro nos resultados da pesquisa do menu. Permite que você use wp_nav_menunormalmente, mas escolha uma subseção do menu com base no título do elemento pai. Adicione um submenuparâmetro ao menu da seguinte maneira:

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => 'About Us',
));

Você pode até atingir vários níveis de profundidade colocando barras:

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => 'About Us/Board of Directors'
));

Ou se você preferir com uma matriz:

wp_nav_menu(array(
  'menu' => 'header',
  'submenu' => array('About Us', 'Board of Directors')
));

Ele usa uma versão slug do título, que deve perdoar coisas como letras maiúsculas e pontuação.

Marcus Downing
fonte
É possível acessar o submenu via id? Quero dizer o ID da página ou o ID da postagem.
Digerkam 28/02
split () está obsoleto, substitua $loc = split( "/", $loc );no plugin por$loc = preg_split( "~/~", $loc );
Floris
Eu também sugeriria tornar o submenu $ opcional. Assim, você ainda pode buscar o menu inteiro quando necessário. Adicione isso ao filtro no topo: `if (! Isset ($ args-> submenu)) {retorne $ items; } `
Floris
8

Eu montei a seguinte aula para mim. Ele encontrará o pai de navegação superior da página atual ou você pode fornecer um ID de navegação superior de destino no construtor walker.

class Walker_SubNav_Menu extends Walker_Nav_Menu {
    var $target_id = false;

    function __construct($target_id = false) {
        $this->target_id = $target_id;
    }

    function walk($items, $depth) {
        $args = array_slice(func_get_args(), 2);
        $args = $args[0];
        $parent_field = $this->db_fields['parent'];
        $target_id = $this->target_id;
        $filtered_items = array();

        // if the parent is not set, set it based on the post
        if (!$target_id) {
            global $post;
            foreach ($items as $item) {
                if ($item->object_id == $post->ID) {
                    $target_id = $item->ID;
                }
            }
        }

        // if there isn't a parent, do a regular menu
        if (!$target_id) return parent::walk($items, $depth, $args);

        // get the top nav item
        $target_id = $this->top_level_id($items, $target_id);

        // only include items under the parent
        foreach ($items as $item) {
            if (!$item->$parent_field) continue;

            $item_id = $this->top_level_id($items, $item->ID);

            if ($item_id == $target_id) {
                $filtered_items[] = $item;
            }
        }

        return parent::walk($filtered_items, $depth, $args);
    }

    // gets the top level ID for an item ID
    function top_level_id($items, $item_id) {
        $parent_field = $this->db_fields['parent'];

        $parents = array();
        foreach ($items as $item) {
            if ($item->$parent_field) {
                $parents[$item->ID] = $item->$parent_field;
            }
        }

        // find the top level item
        while (array_key_exists($item_id, $parents)) {
            $item_id = $parents[$item_id];
        }

        return $item_id;
    }
}

Chamada de navegação:

wp_nav_menu(array(
    'theme_location' => 'main_menu',
    'walker' => new Walker_SubNav_Menu(22), // with ID
));
Matt
fonte
4

@davidn @hakre Oi, eu tenho uma solução feia sem um parser HTML ou substituição de display_element.

 class Selective_Walker extends Walker_Nav_Menu
    {
        function walk( $elements, $max_depth) {

            $args = array_slice(func_get_args(), 2);
            $output = '';

            if ($max_depth < -1) //invalid parameter
                return $output;

            if (empty($elements)) //nothing to walk
                return $output;

            $id_field = $this->db_fields['id'];
            $parent_field = $this->db_fields['parent'];

            // flat display
            if ( -1 == $max_depth ) {
                $empty_array = array();
                foreach ( $elements as $e )
                    $this->display_element( $e, $empty_array, 1, 0, $args, $output );
                return $output;
            }

            /*
             * need to display in hierarchical order
             * separate elements into two buckets: top level and children elements
             * children_elements is two dimensional array, eg.
             * children_elements[10][] contains all sub-elements whose parent is 10.
             */
            $top_level_elements = array();
            $children_elements  = array();
            foreach ( $elements as $e) {
                if ( 0 == $e->$parent_field )
                    $top_level_elements[] = $e;
                else
                    $children_elements[ $e->$parent_field ][] = $e;
            }

            /*
             * when none of the elements is top level
             * assume the first one must be root of the sub elements
             */
            if ( empty($top_level_elements) ) {

                $first = array_slice( $elements, 0, 1 );
                $root = $first[0];

                $top_level_elements = array();
                $children_elements  = array();
                foreach ( $elements as $e) {
                    if ( $root->$parent_field == $e->$parent_field )
                        $top_level_elements[] = $e;
                    else
                        $children_elements[ $e->$parent_field ][] = $e;
                }
            }

            $current_element_markers = array( 'current-menu-item', 'current-menu-parent', 'current-menu-ancestor' );  //added by continent7
            foreach ( $top_level_elements as $e ){  //changed by continent7
                // descend only on current tree
                $descend_test = array_intersect( $current_element_markers, $e->classes );
                if ( !empty( $descend_test ) ) 
                    $this->display_element( $e, $children_elements, 2, 0, $args, $output );
            }

            /*
             * if we are displaying all levels, and remaining children_elements is not empty,
             * then we got orphans, which should be displayed regardless
             */
             /* removed by continent7
            if ( ( $max_depth == 0 ) && count( $children_elements ) > 0 ) {
                $empty_array = array();
                foreach ( $children_elements as $orphans )
                    foreach( $orphans as $op )
                        $this->display_element( $op, $empty_array, 1, 0, $args, $output );
             }
            */

/*added by alpguneysel  */
                $pos = strpos($output, '<a');
            $pos2 = strpos($output, 'a>');
            $topper= substr($output, 0, $pos).substr($output, $pos2+2);
            $pos3 = strpos($topper, '>');
            $lasst=substr($topper, $pos3+1);
            $submenu= substr($lasst, 0, -6);

        return $submenu;
        }
    }
Alp Güneysel
fonte
Depois de experimentar todos, a solução da Alp foi a única que funcionou para mim. No entanto, um problema com isso. Ele mostra apenas os filhos do primeiro nível, mas não mostra os filhos do terceiro ou quarto nível. Eu venho tentando há dias fazê-lo. Alguém sabe como modificar sua solução como tal? PS. Não me permite adicionar comentários, por isso é necessário fazê-lo como resposta.
cchiera 24/05
3

A saída do menu nav inclui muitas classes para o item atual, ancestral do item atual, etc. Em algumas situações, eu consegui fazer o que você deseja, deixando a saída da árvore de navegação inteira e, em seguida, usando o css para reduzi-lo para apenas filhos da página atual etc.


fonte
3

Eu fiz um andador modificado que deve ajudar! Não é perfeito - deixa alguns elementos vazios, mas funciona. A modificação é basicamente os bits $ current_branch. Espero que ajude alguém!

class Kanec_Walker_Nav_Menu extends Walker {
/**
 * @see Walker::$tree_type
 * @since 3.0.0
 * @var string
 */
var $tree_type = array( 'post_type', 'taxonomy', 'custom' );

/**
 * @see Walker::$db_fields
 * @since 3.0.0
 * @todo Decouple this.
 * @var array
 */
var $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

/**
 * @see Walker::start_lvl()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param int $depth Depth of page. Used for padding.
 */
function start_lvl(&$output, $depth) {
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent<ul class=\"sub-menu\">\n";
}

/**
 * @see Walker::end_lvl()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param int $depth Depth of page. Used for padding.
 */
function end_lvl(&$output, $depth) {
    global $current_branch;
    if ($depth == 0) $current_branch = false;
    $indent = str_repeat("\t", $depth);
    $output .= "$indent</ul>\n";
}

/**
 * @see Walker::start_el()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param object $item Menu item data object.
 * @param int $depth Depth of menu item. Used for padding.
 * @param int $current_page Menu item ID.
 * @param object $args
 */
function start_el(&$output, $item, $depth, $args) {
    global $wp_query;
    global $current_branch;

    // Is this menu item in the current branch?
    if(in_array('current-menu-ancestor',$item->classes) ||
    in_array('current-menu-parent',$item->classes) ||
    in_array('current-menu-item',$item->classes)) {
        $current_branch = true; 
    }

    if($current_branch && $depth > 0) {
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = 'menu-item-' . $item->ID;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="' . esc_attr( $class_names ) . '"';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';

        $output .= $indent . '<li' . $id . $value . $class_names .'>';

        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';

        $item_output = $args->before;
        $item_output .= '<a'. $attributes .'>';
        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }

}

/**
 * @see Walker::end_el()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param object $item Page data object. Not used.
 * @param int $depth Depth of page. Not Used.
 */
function end_el(&$output, $item, $depth) {
    global $current_branch;
    if($current_branch && $depth > 0) $output .= "</li>\n";
    if($depth == 0) $current_branch = 0;
}

}


fonte
3

Confira o código no meu plugin ou use-o para o seu propósito;)

Este plugin adiciona o widget "Menu de navegação" aprimorado. Ele oferece muitas opções que podem ser definidas para personalizar a saída do menu personalizado através do widget.

Características incluem:

  • Hierarquia personalizada - "Apenas subitens relacionados" ou "Somente subitens estritamente relacionados".
  • Profundidade inicial e nível máximo para exibição + exibição plana.
  • Exibe todos os itens de menu que começam com o selecionado.
  • Exibir apenas o caminho direto para o elemento atual ou apenas filhos do
    item selecionado (opção para incluir o item pai).
  • Classe customizada para um bloco de widgets.
  • E quase todos os parâmetros para a função wp_nav_menu.

http://wordpress.org/extend/plugins/advanced-menu-widget/

Ján Bočínec
fonte