Cómo mostrar submenú usando solamente wp_nav_menu()

19 jun 2012, 11:07:20
Vistas: 31.6K
Votos: 4

Estoy usando este código para mostrar los submenús de páginas personalizadas cuando se está en la página padre. Pero este código también muestra una página padre en una página que no tiene submenú, la cual me gustaría ocultar. Básicamente, solo quiero usar este código si estamos en una página que tiene una subpágina.

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

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

        if ($max_depth < -1) //parámetro inválido
            return $output;

        if (empty($elements)) //nada que recorrer
            return $output;

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

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

        /*
         * necesita mostrar en orden jerárquico
         * separa elementos en dos grupos: elementos de nivel superior y elementos hijos
         * children_elements es un array bidimensional, por ejemplo
         * children_elements[10][] contiene todos los sub-elementos cuyo padre es 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;
        }

        /*
         * cuando ninguno de los elementos es de nivel superior
         * asume que el primero debe ser la raíz de los sub elementos
         */
        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' );  //añadido por continent7
        foreach ( $top_level_elements as $e ){  //modificado por continent7
            // desciende solo en el árbol actual
            $descend_test = array_intersect( $current_element_markers, $e->classes );
            if ( !empty( $descend_test ) ) 
                $this->display_element( $e, $children_elements, 2, 0, $args, $output );
        }

        /*
         * si estamos mostrando todos los niveles y children_elements restante no está vacío,
         * entonces tenemos huérfanos, que deberían mostrarse de todos modos
         */
         /* eliminado por 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;
    }
}

en la plantilla usando:

wp_nav_menu( 
   array(
       'theme_location'=>'primary', 
       'walker'=>new Selective_Walker() 
   )
);
5
Comentarios

¿Necesita ser una clase Nav Menu Walker? ¿O sería suficiente usar wp_list_pages?

Stephen Harris Stephen Harris
19 jun 2012 12:21:35

También - ¿qué pasa si estás en una página hija? ¿Muestras solo sus hijos (si los tienen)? ¿O los hijos del 'padre raíz'?

Stephen Harris Stephen Harris
19 jun 2012 12:22:34

Intenté usar wp_list_pages, pero no me mostraba las subpáginas, solo si las subpáginas estaban bajo el menú de Páginas. En mi menú personalizado tengo tipos de contenido personalizados como subpáginas para desplegables y esos no aparecían, este fue el único código que encontré que funciona hasta ahora...

Nolan Nolan
19 jun 2012 14:08:48

Solo quiero el padre raíz de los elementos hijos.

Nolan Nolan
19 jun 2012 14:09:05

He estado usando la solución a esta pregunta -> http://wordpress.stackexchange.com/questions/2802/display-a-portion-branch-of-the-menu-tree-using-wp-nav-menu/2809#2809

Agrega un filtro a wp_nav_menu que te permite pasar un parámetro 'submenu'.

gdaniel gdaniel
12 nov 2014 19:46:09
Todas las respuestas a la pregunta 2
0

He tenido este mismo problema muchas veces en el pasado con WordPress. En otros CMS que he utilizado, los menús siempre tenían una opción para start_depth (profundidad inicial), lo que hacía muy fácil implementar un menú secundario o terciario (menú dividido).

WordPress no incluye esta función; y muchas de las soluciones que encuentras en línea usan wp_list_pages, lo que ignora completamente la jerarquía del administrador de menús.

Después de probar diferentes walkers y widgets, finalmente decidí crear mi propio plugin que incluye la opción start_depth.

Se usa así:

wp_nav_menu(array('theme_location' => 'primary_navigation', 'start_depth' => 1));

Para quien esté interesado, pueden obtenerlo gratis en el repositorio de plugins de WordPress: https://wordpress.org/plugins/wp-nav-plus/

14 may 2013 04:25:30
0

¡He creado un plugin gratuito que resuelve este problema!

https://wordpress.org/plugins/wp-nav-menu-extended/

Este plugin extiende la función nativa wp_nav_menu y añade opciones adicionales:

  • level : (integer) (requerido para que funcione este plugin) El nivel del menú de navegación a mostrar. Si no se pasa el parámetro child_of, muestra todos los elementos de este nivel
  • child_of : (string|integer) (opcional) Puede ser el título o el ID del elemento padre en el menú cuyos hijos directos se mostrarán

Ejemplo de uso:

$defaults = array( 'theme_location' => 'main_menu', 'level' => 2, 'child_of' => 'About Us', );

wp_nav_menu( $defaults );
24 feb 2015 07:11:12