Personalizando Walker_Nav_Menu

4 oct 2013, 05:01:18
Vistas: 30.5K
Votos: 2

Estoy buscando una solución para ajustar la salida de wp_nav_menu solo en un menú de navegación específico. Tengo mi menú:

wp_nav_menu(
    array(
        "container"         => "nav",
        "container_class"   => "container",
        "container_id"      => "nav",
        "fallback_cb"       => false,
        "menu_class"        => "six columns omega main-nav sf-menu",
        "theme_location"    => "main-nav"
    )
);

El Problema

Necesito encontrar una manera de insertar <span>[número]</span> dentro del elemento anchor. [número] representa el número del elemento comenzando en 1. Aquí hay una visualización:Ejemplo visual de la estructura del menú con números

La estructura del menú sería:

<li class="...">
    <a href="#"><span>01.</span>Home</a>
</li>
<li class="...">
    <a href="#"><span>02.</span>Services</a>
</li>
<li class="...">
    <a href="#"><span>03.</span>Portfolio</a>
</li>

Actualmente, estoy usando un hack de jQuery. Esto funciona pero no hay garantía de que el usuario simplemente pueda deshabilitar JavaScript. He consultado:

Tengo la idea de que es necesario extender la clase walker, pero mi confusión principal radica en construir los enlaces manualmente y insertar información dinámica antes de que se imprima el texto del enlace. La pregunta de Stack Overflow lo hace pero no explica cómo llegar ahí.

Anexo

Para obtener el resultado preciso que quería, ver pastebin. $item->title necesitaba ser modificado para seguir la estructura HTML como se indica arriba.

0
Todas las respuestas a la pregunta 1
3

Solo necesitas crear tu propia clase walker y extender el método start_el. Este método construye el enlace a y podrás agregar tu span antes de él:

class Wpse8170_Menu_Walker extends Walker_Nav_Menu {

    var $number = 1;

    function start_el( &$output, $item, $depth = 0, $args = array(), $id = 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, $args ) );
        $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

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

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

        // agregar span con número aquí
        if ( $depth == 0 ) { // eliminar if si no se requiere validación de profundidad
            $output .= sprintf( '<span>%02s.</span>', $this->number++ );
        }

        $atts = array();
        $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
        $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
        $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
        $atts['href']   = ! empty( $item->url )        ? $item->url        : '';

        $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );

        $attributes = '';
        foreach ( $atts as $attr => $value ) {
            if ( ! empty( $value ) ) {
                $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
                $attributes .= ' ' . $attr . '="' . $value . '"';
            }
        }

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

}

Después de esto podrás usar esta clase en tu llamada a la función wp_nav_menu:

wp_nav_menu(
    array(
        "container"         => "nav",
        "container_class"   => "container",
        "container_id"      => "nav",
        "fallback_cb"       => false,
        "menu_class"        => "six columns omega main-nav sf-menu",
        "theme_location"    => "main-nav",
        "walker"            => 'Wpse8170_Menu_Walker',
    )
);
4 oct 2013 09:28:08
Comentarios

¿Necesito incluir la clase en el mismo archivo que la navegación o esto sucede automáticamente a través del sistema de hooks?

djthoms djthoms
4 oct 2013 19:45:28

Crea un archivo separado wpse8170-menu-walker.php en la raíz de tu tema. Copia la clase en este archivo. Añade esto include 'wpse8170-menu-walker.php' en tu plantilla.

Eugene Manuilov Eugene Manuilov
4 oct 2013 20:17:05

¡Muchas gracias! Me di cuenta de que estaba cometiendo un error de principiante al editar el archivo equivocado, jaja

djthoms djthoms
5 oct 2013 19:18:53