Tengo una estructura html que requiere la personalización de la wp_nav_menu código.

Este es el html que necesito para generar:

<ul class="main-nav">
    <li class="item">
        <a href="http://example.com/?p=123" class="title">Title</a>
        <a href="http://example.com/?p=123" class="desc">Description</a>
        <ul class="sub-menu">
            <li class="item">
                <a href="http://example.com/?p=123" class="title">Title</a>
                <a href="http://example.com/?p=123" class="desc">Description</a>
            </li>
        </ul>
    </li>
     <li class="item">
        <a href="http://example.com/?p=123" class="title">Title</a>
        <a href="http://example.com/?p=123" class="desc">Description</a>
    </li>
</ul>

Actualmente estoy usando wp_get_nav_menu_items para obtener todos los elementos de mi menú como una matriz.

Ahora soy capaz de generar el html anterior sin los sub-menús usando el siguiente código:

<?php

$menu_name = 'main-nav';
$locations = get_nav_menu_locations()
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$menuitems = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ) );

foreach ( $menuitems as $item ):

    $id = get_post_meta( $item->ID, '_menu_item_object_id', true );
    $page = get_page( $id );
    $link = get_page_link( $id ); ?>

    <li class="item">
        <a href="<?php echo $link; ?>" class="title">
            <?php echo $page->post_title; ?>
        </a>
        <a href="<?php echo $link; ?>" class="desc">
            <?php echo $page->post_excerpt; ?>
        </a>
    </li>

<?php endforeach; ?>

Yo habría generado el menú utilizando el wp_nav_menu función, pero todavía necesito la descripción de la muestra, mediante $page->post_excerpt.

He encontrado que hay es una propiedad de cada elemento denominado $item->menu_item_parent que da a la IDENTIFICACIÓN del padre elemento de menú.

¿Cómo puedo generar el sub-menú en mi foreach bucle?
O hay una manera muy sencilla de usar wp_nav_menu que Google se olvidó de mencionar?

  • puede que desee publicar esto en el WordPress de Intercambio de la Pila: wordpress.stackexchange.com
  • Creo que esto es más de una programación de que se trate. No estoy seguro de cuántas personas en realidad sería capaz de responder esto en wp stackexchange.

3 Comentarios

  1. 66

    Para cualquier persona que aborda algo similar aquí está mi solución:

    Rápido ejemplo de código en un gist

    Aquí está el código en github esencial para cualquier persona que quiere entrar en la acción de copiar y pegar.

    TL;DR

    TL;DR Bucle en la lista, desplácese hacia abajo si hay un sub menú, en caso de llegar a la final de la sub menú y menú.

    Completa explicación del Código de

    En primer lugar obtener los elementos de menú como un plano de la matriz:

    <?php
    $menu_name = 'main_nav';
    $locations = get_nav_menu_locations();
    $menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
    $menuitems = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ) );
    ?>

    Iterar sobre el conjunto de los elementos de menú:

    <nav>
    <ul class="main-nav">
        <?php
        $count = 0;
        $submenu = false;
    
        foreach( $menuitems as $item ):
            //set up title and url
            $title = $item->title;
            $link = $item->url;
    
            //item does not have a parent so menu_item_parent equals 0 (false)
            if ( !$item->menu_item_parent ):
    
            //save this id for later comparison with sub-menu items
            $parent_id = $item->ID;
        ?>

    Escribir el primer elemento principal <li>:

        <li class="item">
            <a href="<?php echo $link; ?>" class="title">
                <?php echo $title; ?>
            </a>
        <?php endif; ?>

    Comprobar que este tipo de elementos’ parent id coincide con el almacenado en la memoria de los padres id:

            <?php if ( $parent_id == $item->menu_item_parent ): ?>

    Inicio del sub-menú <ul> y establecer $submenu flag a true para su posterior referencia:

                <?php if ( !$submenu ): $submenu = true; ?>
                <ul class="sub-menu">
                <?php endif; ?>

    Escribir el sub-elemento de menú:

                    <li class="item">
                        <a href="<?php echo $link; ?>" class="title"><?php echo $title; ?></a>
                    </li>

    Si el siguiente elemento no tiene la misma matriz de identificación y tenemos un sub-menú declarado, a continuación, cierre el sub-menú <ul>

                <?php if ( $menuitems[ $count + 1 ]->menu_item_parent != $parent_id && $submenu ): ?>
                </ul>
                <?php $submenu = false; endif; ?>
    
            <?php endif; ?>

    De nuevo, si el siguiente elemento de la matriz no tiene la misma matriz de identificación de cerrar el <li>

        <?php if ( $menuitems[ $count + 1 ]->menu_item_parent != $parent_id ): ?>
        </li>                           
        <?php $submenu = false; endif; ?>
    
    <?php $count++; endforeach; ?>
    
      </ul>
    </nav>
    • Hay una falta el punto y coma en la primera sección de código. También, es realmente difícil de copiar y pegar su solución. Yo hubiera preferido un solo bloque de código con comentarios de código. Gracias por tu respuesta, sin embargo. +1 de mí
    • Gracias por el comentario, he añadido un gist y se añade el punto y coma que falta.
    • Creo que las etiquetas de cierre para las dos primeras líneas, <nav> y <ul>, también están perdiendo?
    • Estaban en el marcado, pero estaban ocultos. He actualizado la esencia también. Saludos!
    • Agregar (array) en foreach( (array) $menuitems as $item ).
    • Por qué? Por CIERTO, puede editar la respuesta así..
    • Acabo de actualizar tu respuesta. Sin (array) volvería error Invalid argument supplied for foreach().
    • Podría estar relacionado con la versión de php?
    • El Problema con esta solución es que sólo puede mostrar el nivel 1 sub elementos. Si usted tiene sub elementos que han subtemas no funciona correctamente ya.
    • thanx mucho … realmente ayudó a su

  2. 9

    Su mejor apuesta es hacer su propio Walker clase para adaptar la salida a sus necesidades. Algo como esto:

    class Excerpt_Walker extends Walker_Nav_Menu
    {
    function start_el(&$output, $item, $depth, $args)
    {
    global $wp_query;
    $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, $args ) );
    $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 )        ? ' pln">    . 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;
    /*GET THE EXCERPT*/
    $q = new WP_Query(array('post__in'=>$item->object_id));
    if($q->have_posts()) : while($q->have_posts()) : $q->the_post();
    $item_output .= '<span class="menu-excerpt">'.get_the_excerpt().'</span>';
    endwhile;endif;
    /*****************/
    $item_output .= '</a>';
    $item_output .= $args->after;
    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
    }

    Y, a continuación, la llaman así:

    <?php
    wp_nav_menu(array('walker' => new Excerpt_Walker()));
    ?>

    Todo antes y después de OBTENER EL EXTRACTO marcador en mi ejemplo era una copia directa de la start_el función en wp-includes/nav-menu-template.php. Mi ejemplo se utiliza WP_Query para determinar si el post/página tiene un extracto, y coloca el extracto de entre las etiquetas span después de que el título del enlace.

    Una idea sería hacer que las etiquetas span sólo aparecen en hover, que se puede hacer con CSS.

    Más información sobre los Caminantes aquí:

    WP Nav Menú del Codex

    Con El Caminante De La Clase

    Otro Digno Ejemplo de Uso de la Clase Walker

    • Eché un vistazo a los caminantes y que son demasiado complejos para que mi escasa necesidades. Terminé con una solución más simple.
    • Me alegro de que todo saliera bien para usted. Aún así, mantener a los Caminantes en la parte de atrás de su mente, como me han ayudado en un apuro con unas bonitas….. muy interesante, las solicitudes de cliente.
    • No respetar la estructura principal, se puede ver aquí: i.imgur.com/jIOXu4e.png
    • Que no me muestre nada. Estás usando los menús? ¿Puede definir el menú en el panel de control? Se le llama el menú correspondiente en la plantilla? Está usted seguro de que su menú no volver a caer en wp_page_menu? Si usted hizo todo correctamente, entonces este será respecto a la estructura principal, como esto es casi una réplica exacta de la original Walker clase WordPress utiliza internamente.
  3. 0
          //Just set your variable and apply.. for sub menu
    <ul>
    <?php
    $activeclass = '';
    $activeclass1='';
    $count=0;
    $submenu = FALSE;
    foreach ( $primaryNav as $navItem ) {
    $activeclass = '';  
    if($navItem->object_id == $getid){
    $activeclass = 'class="live-act"';
    }
    if (!$navItem->menu_item_parent ){
    $parent_id = $navItem->ID;
    echo '<li><a href="'.$navItem->url.'" '.$activeclass.'   title="'.$navItem->title.'">'.$navItem->title.'</a>';
    }
    ?>
    <?php if ( $parent_id == $navItem->menu_item_parent ) { ?>
    <?php if ( !$submenu ): $submenu = true; ?>
    <ul>
    <?php endif; ?>
    <li>
    <a href="<?php echo $navItem->url; ?>" class="title"><?php echo $navItem->title; ?></a>
    </li>
    <?php if ( $primaryNav[ $count + 1 ]->menu_item_parent != $parent_id && $submenu ){ ?>
    </ul>
    <?php $submenu = false; 
    }
    ?>
    <?php }
    if ( $primaryNav[ $count + 1 ]->menu_item_parent != $parent_id ){ ?>
    </li>                            
    <?php $submenu = false; } ?>
    <?php $count++;   ?>
    <?php } ?>
    </ul>

Dejar respuesta

Please enter your comment!
Please enter your name here