Afficher une portion / branche de l’arborescence du menu en utilisant wp_nav_menu ()

109

J'ai un menu défini dans WP Admin qui ressemble à ceci:

texte alternatif

Je veux pouvoir afficher tous les liens enfants dans la barre latérale chaque fois que je suis sur une page parent. Par exemple, si l'utilisateur se trouve sur ma page "À propos de nous", je souhaite qu'une liste des 4 liens surlignés en vert apparaisse dans la barre latérale.

J'ai consulté la documentation de wp_nav_menu () et il ne semble pas y avoir de moyen intégré pour spécifier un nœud particulier d'un menu donné à utiliser comme point de départ lors de la génération des liens.

J'ai créé une solution pour une situation similaire qui s'appuyait sur les relations créées par la page parent, mais je cherche une solution qui utilise spécifiquement le système de menus. Toute aide serait appréciée.

Jessegavin
la source
2
Vous souhaitez donc conserver l’ensemble du menu en tant que menu personnalisé, mais créer un programme personnalisé qui l’affiche en développant uniquement le sous-arbre actif? Comme ce code , mais en étendant wp_nav_menu au lieu de wp_list_pages? J'ai récemment fait quelque chose de similaire et je pourrais poster le code si c'est ce que vous cherchez ...
goldenapples
1
@goldenapples, c'est exactement ce que je recherche. Si cela ne vous dérange pas de poster votre code comme réponse, je vous en serais très reconnaissant.
Jessegavin
1
Je me demande si une fonctionnalité aussi évidente et utile ne l’a pas déjà été. C'est globalement très utile pour tout site qui fait du "CMS".
hakre
J'essaie de résoudre le problème ci-dessus ou quelque chose de similaire. Au lieu de cela, j'ai proposé une solution CSS ici: stackoverflow.com/q/7640837/518169
hyperknot

Réponses:

75

J'y pensais toujours, je l'ai donc revisitée et mise au point cette solution qui ne dépend pas beaucoup du contexte:

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

Usage

$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
la source
Belle technique! Puis-je poser une question relative à celle-ci: comment afficheriez-vous le contenu de ces pages de sous-menu dans un modèle?
daniel.tosaba
2
@ daniel.tosaba, vous devrez sous- Walker_Nav_Menuclasser ou utiliser des filtres en classe. Vous aimez trop les commentaires sur les menus - vous posez une nouvelle question à ce sujet?
Rarst
3
Une telle réponse fantastique. Merci beaucoup. Cela devrait vraiment être une option par défaut dans WordPress.
dotty
3
Vraiment bien. Si quelqu'un est intéressé, faites de même, mais en vous référant à l'identifiant de la page, remplacez la wp_filter_object_listligne parwp_filter_object_list( $items, array( 'object_id' => $args->submenu ), 'and', 'ID' );
Ben
14

@goldenapples: Votre Walker Class ne fonctionne pas. Mais l'idée est vraiment bonne. J'ai créé un walker basé sur votre idée:

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

Maintenant vous pouvez utiliser:

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

La sortie est une liste contenant l'élément racine actuel et ses enfants (pas leurs enfants). Def: Elément racine: = L'élément de menu de niveau supérieur qui correspond à la page en cours ou est le parent d'une page en cours ou le parent d'un parent ...

Cela ne répond pas exactement à la question initiale, mais presque, car il y a toujours l'élément de niveau supérieur. Cela me convient, car je souhaite que l’élément de niveau supérieur figure dans le titre de la barre latérale. Si vous souhaitez vous en débarrasser, vous devrez peut-être remplacer display_element ou utiliser un analyseur HTML.

Davidn
la source
12

Bonjour @jessegavin :

Les menus de navigation sont stockés dans une combinaison de types de publication personnalisés et de taxonomies personnalisées. Chaque menu est stocké en tant que terme (c'est-à-dire "À propos du menu" , trouvé dans wp_terms) d'une taxonomie personnalisée (c'est nav_menu-à- dire trouvé dans wp_term_taxonomy.)

Chaque élément de menu de navigation est stocké sous forme de publication post_type=='nav_menu_item'(c.-à-d. "À propos de la société" , dans wp_posts), ses attributs étant stocké en tant que post meta (en wp_postmeta) en utilisant un meta_keypréfixe _menu_item_*_menu_item_menu_item_parentest l'ID de l'élément de menu de navigation parent de votre élément de menu.

La relation entre les menus et les éléments de menu est stockée dans wp_term_relationshipsoù se object_idrapporte à l' $post->IDélément de menu de navigation et se $term_relationships->term_taxonomy_idrapporte au menu défini collectivement dans wp_term_taxonomyet wp_terms.

Je suis sûr qu'il serait possible de brancher deux 'wp_update_nav_menu'et 'wp_update_nav_menu_item'pour créer des menus réels dans wp_termset un ensemble parallèle de relations dans wp_term_taxonomyet wp_term_relationshipsoù chaque menu Nav Point qui a des éléments de menu sous-Nav devient également son propre menu de navigation.

Vous voudriez également accrocher 'wp_get_nav_menus' (que j’ai suggéré d’ajouter à WP 3.0 sur la base d’un travail similaire à celui que je faisais il ya quelques mois) pour vous assurer que vos menus de navigation générés ne sont pas affichés pour être manipulés par l’utilisateur dans l’administrateur, sinon ils ne seraient pas affichés. vous vous désynchroniseriez très vite et vous auriez un cauchemar de données sur votre main.

C’est un projet amusant et utile, mais c’est un peu plus de code et de tests que je ne peux me permettre, en partie parce que tout ce qui synchronise les données a tendance à être un PITA quand il s’agit de résoudre tous les bugs (et parce que Les clients payants me poussent à faire avancer les choses. :) Mais armé des informations ci-dessus, je suis assez motivé pour qu'un développeur de plug-in WordPress puisse le coder s'il le souhaite.

Bien sûr, vous réalisez maintenant que si vous le codez, vous êtes obligé de le poster ici pour que nous puissions tous profiter de vos largesses! :-)

Mike Schinkel
la source
Je ne suis pas sûr de suivre ce que vous dites. Je recherche une solution en lecture seule permettant d'afficher des "sous-menus" liés à la page actuelle d'un utilisateur. Parlons-nous de la même chose? - J'apprécie votre explication plus profonde sur le schéma de base de données.
jessegavin
@jessegavin - Oui, si vous souhaitez appeler, wp_nav_menu()vous devez cloner les menus car il wp_nav_menu()est étroitement lié à la structure du menu . L'autre option consiste à copier le wp_nav_menu()code et à apporter les modifications nécessaires pour l'affichage sous forme de sous-menu.
MikeSchinkel
10

Ceci est une extension du marcheur qui devrait faire ce que vous cherchez:

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

}

Basé vaguement sur le code de mfields que j'ai mentionné dans mon commentaire plus tôt. Il suffit de vérifier dans le menu pour voir si l'élément en cours est (1) l'élément de menu en cours ou (2) un ancêtre de l'élément de menu en cours, et développe la sous-arborescence située en dessous uniquement si l'une de ces conditions est remplie. . J'espère que cela fonctionne pour toi.

Pour l'utiliser, ajoutez simplement un argument "walker" lorsque vous appelez le menu, c'est-à-dire:

<?php wp_nav_menu( 
   array(
       'theme_location'=>'test', 
       'walker'=>new Selective_Walker() ) 
   ); ?>
pommes d'or
la source
Oh ... je viens de relire votre question et je me suis rendu compte que je l'avais mal comprise au début. Ce marcheur affichera tous les autres éléments de menu de niveau supérieur, mais ne les développez pas. Ce n'était pas exactement ce que tu voulais faire. Néanmoins, ce code peut être modifié comme vous le souhaitez. Il suffit de regarder la boucle $top_level_elementset d'ajouter votre propre test avant l'appel $this->display_element.
Goldenapples
Est-il possible d’obtenir de cette classe la profondeur de la sous-page actuelle? C’est .. Si j’ai une profondeur de trois niveaux ou plus, que le troisième niveau et les suivants sont affichés pour la (sous) page actuelle? Pour le moment, il ne montre que A> B, et non> C (C étant le troisième (niveau)
Zolomon
@Zolomon - Je ne suis pas sûr de comprendre votre question. Cela devrait développer toute l'arborescence sous n'importe quel élément de menu avec les éléments 'current-menu-item', 'current-menu-parent' ou 'current-menu-ancor' de la classe. Lorsque je le teste, il affiche tous les niveaux de sous-pages du menu. Que cherches-tu à faire?
Goldenapples
Peut-être voudrez-vous passer un depthparamètre à l'appel wp_nav_menu, au cas où votre thème surpasserait la valeur par défaut de 0 (afficher tous les niveaux)?
Goldenapples
8

Mise à jour: je l'ai fait dans un plugin. Téléchargez ici .


J'avais besoin de résoudre ce problème moi-même et d'écrire un filtre sur les résultats de la recherche de menu. Il vous permet de l'utiliser wp_nav_menunormalement, mais choisissez une sous-section du menu en fonction du titre de l'élément parent. Ajoutez un submenuparamètre au menu comme suit:

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

Vous pouvez même aller à plusieurs niveaux en mettant des slash dans:

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

Ou si vous préférez avec un tableau:

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

Il utilise une version limace du titre, ce qui devrait lui permettre de pardonner des choses comme les majuscules et la ponctuation.

Marcus Downing
la source
Est-il possible d'accéder au sous-menu via id? Je veux dire identifiant de page ou post ID.
Digerkam
split () est obsolète, remplace $loc = split( "/", $loc );dans le plugin avec$loc = preg_split( "~/~", $loc );
Floris
Je suggérerais également de rendre le sous-menu $ optionnel. Donc, vous pouvez toujours aller chercher le menu complet quand vous en avez besoin. Ajoutez ceci au filtre en haut: `if (! Isset ($ args-> sous-menu)) {return $ items; } `
Floris
8

J'ai mis en place le cours suivant pour moi-même. Il trouvera le parent de navigation supérieur de la page actuelle ou vous pouvez lui attribuer un ID de navigation supérieur cible dans le constructeur du lecteur.

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

Appel de navigation:

wp_nav_menu(array(
    'theme_location' => 'main_menu',
    'walker' => new Walker_SubNav_Menu(22), // with ID
));
Mat
la source
4

@davidn @hakre Bonjour, j'ai une solution laide sans HTML-Parser ni surcharger 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
la source
Après avoir tout essayé, la solution d'Alp était la seule qui fonctionnait pour moi. Cependant, un problème avec cela. Il ne montre que les enfants du premier niveau, mais ne montre pas les enfants du troisième ou du quatrième niveau. J'essaie de le faire depuis des jours. Quelqu'un sait comment modifier sa solution en tant que telle? PS Cela ne me permettra pas d'ajouter des commentaires, il est donc nécessaire de le faire en tant que réponse.
cchiera
3

La sortie du menu de navigation inclut de nombreuses classes pour l'élément en cours, l'ancêtre de l'élément en cours, etc. Dans certaines situations, j'ai été en mesure de faire ce que vous voulez faire en laissant toute la sortie de l'arborescence de navigation, puis en utilisant css pour la réduire à seuls les enfants de la page en cours, etc.


la source
3

J'ai fait un marcheur modifié qui devrait aider! Pas parfait - il laisse quelques éléments vides, mais ça fait l'affaire. La modification concerne essentiellement les bits $ current_branch. J'espère que ça aide quelqu'un!

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

}


la source
3

Découvrez le code dans mon plugin ou utilisez-le à vos fins;)

Ce plugin ajoute un widget "Menu de navigation" amélioré. Il offre de nombreuses options qui peuvent être définies pour personnaliser la sortie du menu personnalisé via le widget.

Les fonctionnalités incluent:

  • Hiérarchie personnalisée - "Seuls les sous-éléments liés" ou "Seuls les sous-éléments strictement liés".
  • Profondeur de départ et niveau maximum d'affichage + écran plat.
  • Affiche tous les éléments de menu en commençant par celui sélectionné.
  • Affiche uniquement le chemin direct vers l’élément en cours ou uniquement les enfants de l’
    élément sélectionné (option permettant d’inclure l’élément parent).
  • Classe personnalisée pour un bloc de widgets.
  • Et presque tous les paramètres de la fonction wp_nav_menu.

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

Ján Bočínec
la source