añadir clase span dentro de la etiqueta anchor de wp_nav_menu

15 nov 2012, 11:12:19
Vistas: 27K
Votos: 4

Encontré ejemplos añadiendo una clase a elementos de nivel superior, para poder mostrar una flecha en elementos del menú con subitems, pero parece terrible lidiar con las clases ya integradas de WordPress, no se puede mostrar la flecha con el estado actual y hover de css, simplemente arruina todos los estados.

El menú de navegación actual es así <li><a>Texto</a></li>

¿Hay alguna manera de añadir un <span class="arrow"></span> dentro de las etiquetas padre <a></a>?

Ejemplo,

Añadir ⇒ <span class="arrow"></span> dentro de ⇒ <a/></a> etiquetas

Por lo tanto ⇒ <li><a>Texto<span class="arrow"></span></a></li> que es padre.

El código actual añade las etiquetas <span></span> fuera de las etiquetas <a></a> que es padre

class My_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl(&$output, $depth, $args) {
        $indent = str_repeat("\t", $depth);
        if('primary' == $args->theme_location && $depth ==0){
            $output .='<span class="arrow"></span>';
        }
        $output .= "\n$indent<ul class=\"sub-menu\">\n";
    }
}

Título de la pregunta original editado de: "añadir clase span dentro de <a>"

1
Comentarios

como quieres editar el elemento, no todo el nivel, deberías extender la función start_el en lugar de start_lvl. aquí puedes agregar el <span> dentro del <a>.

fischi fischi
15 nov 2012 12:11:20
Todas las respuestas a la pregunta 3
0

¿Has intentado usar los parámetros before o link_before en los argumentos de tu array al declarar la función wp_nav_menu?

Nota: usa after o link_after para el efecto opuesto.

Ejemplo:

wp_nav_menu(

    //argumentos normales aquí...etc

    'before'    => '<span class="arrow"></span>',

    //o 'link_before' => '<span class="arrow"></span>',


); 

Del Codex:

$before
(string) (opcional) Texto de salida antes del del enlace
Por defecto: Ninguno

   ej. 'before'    => ''

o...

$link_before
(string) (opcional) Texto de salida antes del texto del enlace
Por defecto: Ninguno

   ej. 'link_before'    => ''

Recursos de apoyo:

http://codex.wordpress.org/Function_Reference/wp_nav_menu

15 nov 2012 15:55:12
0

Esto crea dos instancias donde muestra una clase span dentro de la etiqueta en los niveles primario y secundario, para que puedas agregar diferentes imágenes a tu clase span con fines de diseño y navegación.

Esto ayuda a los usuarios y desarrolladores a mostrar si hay un menú desplegable en el encabezado y también facilita la navegación dentro del sitio web.

1. Primero agrega este código a tu functions.php

class Nav_Walker_Nav_Menu extends Walker_Nav_Menu {
     function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        global $wp_query;
        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

        $class_names = '';

        $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 . $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;

        if ( 'primary' == $args->theme_location ) {
            $submenus = 0 == $depth || 1 == $depth ? get_posts( array( 'post_type' => 'nav_menu_item', 'numberposts' => 1, 'meta_query' => array( array( 'key' => '_menu_item_menu_item_parent', 'value' => $item->ID, 'fields' => 'ids' ) ) ) ) : false;
            $item_output .= ! empty( $submenus ) ? ( 0 == $depth ? '<span class="arrow"></span>' : '<span class="sub-arrow"></span>' ) : '';
        }
        $item_output .= '</a>';
        $item_output .= $args->after;

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

2. Agrega este código en tu header.php donde esté instalado tu wp_nav_menu

Se explica a continuación cómo instalar el nuevo menú personalizado, en este caso sería Nav_Walker_Nav_Menu.

<?php wp_nav_menu( array( 'container_class' => 'menu-header', 'theme_location' => 'primary', 'walker' => new Nav_Walker_Nav_Menu() ) ); ?>

3. Agrega algo de CSS

Para que pueda mostrar tus nuevas imágenes de flecha span dentro de tus etiquetas en nivel primario y secundario.

#menu-header-menu li span.arrow { height:12px;background-image: url("images/nav-arrows.png");background-position: -8px -3px;background-repeat: no-repeat;float: right;margin: 0 0px 0 10px;text-indent: -9999px;width: 12px;}
#menu-header-menu li a:hover span.arrow{ height:12px;background-image: url("images/nav-arrows.png");background-position: -39px -3px;background-repeat: no-repeat;float: right;margin: 0 0px 0 10px;text-indent: -9999px;width: 12px;}
#menu-header-menu ul.sub-menu li span.sub-arrow { height:12px;background-image: url("images/nav-arrows.png");background-position: -8px -39px;background-repeat: no-repeat;float: right;margin: -2px 0px 0 10px;text-indent: -9999px;width: 12px;}
#menu-header-menu ul.sub-menu li a:hover span.sub-arrow{ height:12px;background-image: url("images/nav-arrows.png");background-position: -39px -39px;background-repeat: no-repeat;float: right;margin: -2px 0px 0 10px;text-indent: -9999px;width: 12px;}

¡Espero que esto ayude! :)

15 nov 2012 22:32:45
0

Ambas respuestas publicadas por userabuser y wordpress_designer son excelentes, pero me gustaría publicar una respuesta que es una combinación de las dos.

Con esta respuesta puedes usar lógica para definir dónde no quieres que se aplique el link_before. Así como también qué quieres poner antes del texto del enlace.

Primero crea una clase muy simple como la que se muestra a continuación. Esta clase en realidad solo es responsable de verificar cuando el elemento no es un submenú ($depth <= 0) y para limpiar y recordar el valor de link_before.

if ( ! class_exists('PREFIX_Menu_Walker')) {
    class PREFIX_Menu_Walker extends Walker_Nav_Menu {
        public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
            $before = property_exists($args, 'link_before') ? $args->link_before : '';

            // Vaciar el `link_before` al navegar sobre un elemento de nivel raíz
            if ($depth <= 0 && !empty($before)) {
                $args->link_before = '';
            }

            // Continuar con la clase predeterminada/núcleo del walker de menú de WordPress
            parent::start_el( $output, $item, $depth, $args, $id );

            // Recordar qué `link_before` $args estaban establecidos.
            $args->link_before = $before;
        }
    }
}

Lo segundo que tendrás que hacer es aplicar el argumento walker y el argumento link_before a tu array de wp_nav_menu, así:

wp_nav_menu([
    'link_before' => '<span>Hola</span>',
    'walker' => new PREFIX_Menu_Walker()
]);
4 dic 2017 15:52:33