wp_list_categories, Añadir clase a todos los elementos de lista con hijos

27 mar 2013, 22:49:18
Vistas: 13.5K
Votos: 2

Estoy usando wp_list_categories(); para mostrar una lista de todos los términos dentro de una taxonomía personalizada, pero necesito aplicar estilos diferentes a los elementos de lista que tienen hijos en comparación con los que no.

¿Existe alguna forma, ya sea con PHP o jQuery, de dar a todos los elementos padre una clase especial?

0
Todas las respuestas a la pregunta 2
1

Puedes engancharte al filtro que está implementado exactamente para este propósito de la siguiente manera. Mi ejemplo agregará una clase "has_children" al elemento padre.

function add_category_parent_css($css_classes, $category, $depth, $args){
    if($args['has_children']){
        $css_classes[] = 'has_children';
    }
    return $css_classes;
}

add_filter( 'category_css_class', 'add_category_parent_css', 10, 4);
18 abr 2017 16:38:26
Comentarios

Esta es la forma correcta de hacerlo, parece que el filtro se agregó en la versión 4.2.0 lo que explica por qué no se mencionó previamente en la respuesta original. ¡Gracias!

Radley Sustaire Radley Sustaire
8 may 2017 03:46:24
2

Solución con jQuery:

Puedes probar esto si quieres usar jQuery:

<script>
jQuery(document).ready(function($) {
    $('li.cat-item:has(ul.children)').addClass('i-have-kids');
}); 
</script>

para agregar la clase i-have-kids a todos los elementos li padres que incluyen los items ul.children, dentro del HTML generado por wp_list_categories().

Solución con Walker de categorías:

Puedes revisar la clase Walker_Category en /wp-includes/category-template.php y extenderla con una parte adicional como:

$termchildren = get_term_children( $category->term_id, $category->taxonomy );
if(count($termchildren)>0){
    $class .=  ' i-have-kids';
}

Si omitimos la parte de la imagen de feed y los elementos de feed, el walker extendido podría verse así:

class Walker_Category_Find_Parents extends Walker_Category {
    function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
        extract($args);

        $cat_name = esc_attr( $category->name );
        $cat_name = apply_filters( 'list_cats', $cat_name, $category );
        $link = '<a href="' . esc_url( get_term_link($category) ) . '" ';
        if ( $use_desc_for_title == 0 || empty($category->description) )
            $link .= 'title="' . esc_attr( sprintf(__( 'Ver todas las entradas archivadas en %s' ), $cat_name) ) . '"';
        else
            $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
            $link .= '>';
            $link .= $cat_name . '</a>';

        if ( !empty($show_count) )
            $link .= ' (' . intval($category->count) . ')';

                if ( 'list' == $args['style'] ) {
                        $output .= "\t<li";
                        $class = 'cat-item cat-item-' . $category->term_id;

                        $termchildren = get_term_children( $category->term_id, $category->taxonomy );
                        if(count($termchildren)>0){
                            $class .=  ' i-have-kids';
                        }

                        if ( !empty($current_category) ) {
                                $_current_category = get_term( $current_category, $category->taxonomy );
                                if ( $category->term_id == $current_category )
                                        $class .=  ' current-cat';
                                elseif ( $category->term_id == $_current_category->parent )
                                        $class .=  ' current-cat-parent';
                        }
                        $output .=  ' class="' . $class . '"';
                        $output .= ">$link\n";
                } else {
                        $output .= "\t$link<br />\n";
                }
        }
    }

Puedes quitar además las partes que no necesites.

Ejemplo de uso:

<?php 
$args = array(
  'taxonomy'     => 'my_custom_taxonomy_slug',
  'orderby'      => 'name',
  'hide_empty'   => 0,
  'title_li'     => '',
  'hierarchical' => 1,
  'walker'       => new Walker_Category_Find_Parents(),
);
?>
<ul class="menu">
   <?php wp_list_categories( $args ); ?>
</ul>

Ejemplo de salida:

Aquí hay un ejemplo de lista, usando el walker Walker_Category_Find_Parents:

Ejemplo de lista

con la siguiente estructura HTML:

<ul class="menu">
    <li class="cat-item cat-item-1">
        <a href="http://example.com/category/plants/">plantas</a>
    </li>
    <li class="cat-item cat-item-2 i-have-kids">
        <a href="http://example.com/category/animals/">animales</a>
        <ul class="children">
            <li class="cat-item cat-item-3 i-have-kids">
                <a href="http://example.com/category/animals/birds/">aves</a>
                <ul class="children">
                    <li class="cat-item cat-item-4">
                        <a href="http://example.com/category/animals/birds/falcons/">halcones</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li class="cat-item cat-item-5">
        <a href="http://example.com/category/stones">piedras</a>
    </li>
</ul>

He eliminado los atributos title para hacerlo más legible.

Pero puedes ver dónde se agrega la clase i-have-kids a los elementos li que tienen hijos.

Cuando visito la categoría / Animales / Aves /, la estructura HTML se convierte en:

<ul class="menu">
    <li class="cat-item cat-item-1">
        <a href="http://example.com/category/plants/">plantas</a>
    </li>
    <li class="cat-item cat-item-2 i-have-kids current-cat-parent">
        <a href="http://example.com/category/animals/">animales</a>
        <ul class="children">
            <li class="cat-item cat-item-3 i-have-kids current-cat">
                <a href="http://example.com/category/animals/birds/">aves</a>
                <ul class="children">
                    <li class="cat-item cat-item-4">
                        <a href="http://example.com/category/animals/birds/falcons/">halcones</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
    <li class="cat-item cat-item-5">
        <a href="http://example.com/category/stones">piedras</a>
    </li>
</ul>
28 mar 2013 01:14:20
Comentarios

¡Genial! :-) Solo una cosa. El LI de nivel superior no recibe la clase current-cat-parent. ¿Sabes por qué?

curly_brackets curly_brackets
2 may 2014 12:09:57

Hola @KennethB, la clase current-cat-parent aparece en la etiqueta li de nivel superior, en mi instalación de 3.9.1 con el tema por defecto. Actualicé la respuesta para mostrarte la estructura HTML.

birgire birgire
9 may 2014 21:04:23