¿Cómo puedo personalizar wp_list_categories?

8 may 2013, 17:37:39
Vistas: 30.1K
Votos: 2

Tengo una lista de categorías en WooCommerce que estoy tratando de personalizar para que se muestre como en la siguiente imagen.

Lista de categorías

Creé la imagen de arriba usando HTML y CSS normal, sin embargo, ahora me gustaría convertirla a WordPress para que se cree dinámicamente.

Aquí está el HTML:

<div class="col tertiary" id="filters">
        <ul class="product-categories">        

            <li id="pattern_garment_type">
                <h5>Mujeres</h5>
                <ul>
                    <li class="selected">                
                          <a href="#">Todo</a>                        
                    </li>

                    <li class="">
                      <a href="#">Accesorios</a>
                    </li>

                    <li class="">
                      <a href="#">Blusas</a>
                    </li>

                    .etc...

          </ul>
            </li>

            <li id="pattern_garment_type">
                <h5>Hombres</h5>
                <ul>
                <li class="selected">

                      <a href="#">Todo</a>

                </li>

                  <li class="">
                      <a href="#">Accesorios</a>
                  </li>

                  <li class="">
                      <a href="#">Abrigos</a>
                  </li>
                  ..etc..

                </ul>
            </li>


            <li id="pattern_garment_type">
                <h5>Niños</h5>
                <ul>
                <li class="selected">

                      <a href="#">Todo</a>

                </li>

                  <li class="">
                      <a href="#">Bebés</a>
                  </li>

                  <li class="">
                      <a href="#">Niñas</a>
                  </li>

                  <li class="">
                      <a href="#">Niños</a>
                  </li>

                </ul>
            </li>

        </ul>
    </div>

Aquí está el código actual de WordPress con el que estoy trabajando (no estoy seguro si debería usar el walker para personalizar la salida para que se genere como el HTML anterior):

<div id="content-filters" class="two columns">
<?php $args = array(
    'style'              => 'list',
    'show_count'         => 0,
    'use_desc_for_title' => 1,
    'child_of'           => 0,
    'title_li'           => __( '' ),
    'show_option_none'   => __('No hay elementos del menú'),
    'number'             => null,
    'echo'               => 1,
    'depth'              => 2,
    'taxonomy'           => 'product_cat',
); ?>

<div class="col tertiary" id="filters">
    <ul class="product-categories">   
        <?php wp_list_categories( $args ); ?>
    </ul>
</div>

1) ¿Cómo puedo usar el filtro wp_list_categories para agregar un enlace "Todo" en la parte superior de las subcategorías que enlace a una página que muestre todos los elementos?

2) ¿Cómo puedo también usar el filtro wp_list_categories para eliminar el enlace de la categoría principal y envolverlo en una etiqueta para hacerlo negrita (como en la imagen de ejemplo)?

Cualquier ayuda sería apreciada

2
Comentarios

Lo que tienes debería imprimir ya las categorías y subcategorías de product_cat. ¿Estás preguntando cómo darle estilo? Si es así, solo necesitas usar las clases que WordPress te proporciona. Por ejemplo: "cat-item" para la categoría padre y "children" para las subcategorías.

gdaniel gdaniel
8 may 2013 18:10:03

Actualicé la pregunta para proporcionar más detalles sobre lo que estoy tratando de lograr

Oudin Oudin
9 may 2013 02:29:27
Todas las respuestas a la pregunta 2
0

Aunque exista un filtro wp_list_categories, este pasa (y por lo tanto debes devolver) el marcado HTML generado por la función wp_list_categories(). Esto significa que si quieres usar ese filtro, tendrás que alterar el DOM con PHP, y aunque es posible (ojalá usando bibliotecas externas de PHP), seguro que no es la mejor solución para tus necesidades.

Una alternativa es usar JavaScript para alterar el HTML después de creado. Es una posibilidad, pero yo soy desarrollador de WordPress, no de JavaScript, así que te daré la solución de WordPress.

Debes crear una clase personalizada de Category Walker y luego usarla dentro de una versión personalizada de wp_list_categories().

Empecemos.

Primero, la clase personalizada Category Walker (colócala en functions.php):

class My_Category_Walker extends Walker_Category {

  var $lev = -1;
  var $skip = 0;
  static $current_parent;

  function start_lvl( &$output, $depth = 0, $args = array() ) {
    $this->lev = 0;
    $output .= "<ul>" . PHP_EOL;
  }

  function end_lvl( &$output, $depth = 0, $args = array() ) {
    $output .= "</ul>" . PHP_EOL;
    $this->lev = -1;
  }

  function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
    extract($args);
    $cat_name = esc_attr( $category->name );
    $class_current = $current_class ? $current_class . ' ' : 'current ';
    if ( ! empty($current_category) ) {
      $_current_category = get_term( $current_category, $category->taxonomy );
      if ( $category->term_id == $current_category ) $class = $class_current;
      elseif ( $category->term_id == $_current_category->parent ) $class = rtrim($class_current) . '-parent ';
    } else {
      $class = '';
    }
    if ( ! $category->parent ) {
      if ( ! get_term_children( $category->term_id, $category->taxonomy ) {
          $this->skip = 1;
      } else {
        if ($class == $class_current) self::$current_parent = $category->term_id;
        $output .= "<li class='" . $class . $level_class . "'>" . PHP_EOL;
        $output .= sprintf($parent_title_format, $cat_name) . PHP_EOL;
      }
    } else { 
      if ( $this->lev == 0 && $category->parent) {
        $link = get_term_link(intval($category->parent) , $category->taxonomy);
        $stored_parent = intval(self::$current_parent);
        $now_parent = intval($category->parent);
        $all_class = ($stored_parent > 0 && ( $stored_parent === $now_parent) ) ? $class_current . ' all' : 'all';
        $output .= "<li class='" . $all_class . "'><a href='" . $link . "'>" . __('Todos') . "</a></li>\n";
        self::$current_parent = null;
      }
      $link = '<a href="' . esc_url( get_term_link($category) ) . '" >' . $cat_name . '</a>';
      $output .= "<li";
      $class .= $category->taxonomy . '-item ' . $category->taxonomy . '-item-' . $category->term_id;
      $output .=  ' class="' . $class . '"';
      $output .= ">" . $link;
    }
  }

  function end_el( &$output, $page, $depth = 0, $args = array() ) {
    $this->lev++;
    if ( $this->skip == 1 ) {
      $this->skip = 0;
      return;
    }
    $output .= "</li>" . PHP_EOL;
  }

}

Extiende la clase WP Walker_Category y sobrescribe los 4 métodos con algo que se ajuste a tus necesidades.

Después, en el functions.php coloca la función personalizada:

function custom_list_categories( $args = '' ) {
  $defaults = array(
    'taxonomy' => 'category',
    'show_option_none' => '',
    'echo' => 1,
    'depth' => 2,
    'wrap_class' => '',
    'level_class' => '',
    'parent_title_format' => '%s',
    'current_class' => 'current'
  );
  $r = wp_parse_args( $args, $defaults );
  if ( ! isset( $r['wrap_class'] ) ) $r['wrap_class'] = ( 'category' == $r['taxonomy'] ) ? 'categories' : $r['taxonomy'];
  extract( $r );
  if ( ! taxonomy_exists($taxonomy) ) return false;
  $categories = get_categories( $r );
  $output = "<ul class='" . esc_attr( $wrap_class ) . "'>" . PHP_EOL;
  if ( empty( $categories ) ) {
    if ( ! empty( $show_option_none ) ) $output .= "<li>" . $show_option_none . "</li>" . PHP_EOL;
  } else {
    if ( is_category() || is_tax() || is_tag() ) {
      $current_term_object = get_queried_object();
      if ( $r['taxonomy'] == $current_term_object->taxonomy ) $r['current_category'] = get_queried_object_id();
    }
    $depth = $r['depth'];
    $walker = new My_Category_Walker;
    $output .= $walker->walk($categories, $depth, $r);
  }
  $output .= "</ul>" . PHP_EOL;
  if ( $echo ) echo $output; else return $output;
}

La parte difícil está hecha. Ahora el código de la plantilla, colócalo donde lo necesites:

<div id="content-filters" class="two columns">
<div class="col tertiary" id="filters">
<?php
$args = array(
  'taxonomy' => 'product_cat',
  'show_option_none' => __('No hay elementos en el menú.'),
  'echo' => 1,
  'depth' => 2,
  'wrap_class' => 'product-categories',
  'level_class' => 'pattern_garment_type',
  'parent_title_format' => '<h5>%s</h5>',
  'current_class' => 'selected'
);
custom_list_categories( $args );
?>
</div>
</div>

Personaliza los argumentos $args si lo deseas, los he configurado según tu código de respuesta. Solo he cambiado 'pattern_garment_type' para que sea una clase y no un ID, porque no puedes tener el mismo ID de etiqueta múltiples veces en HTML (como en tu marcado).

Eso es todo, espero que te ayude.

25 jul 2013 06:11:52
1

Oudin,

Responderé aquí la parte CSS de tu pregunta:

Usa esto para eliminar los puntos de la lista:

.ul.product-categories, ul.children{
    list-style-type: none;

}

Usa esto para poner en negrita solo las categorías principales:

li {font-weight:normal} // necesitas establecer primero el estado por defecto de la lista

ul.product-categories > li{font-weight:bold;} //luego puedes cambiar el nivel superior de la lista sin afectar a sus hijos

Así es como puedes apuntar a esos elementos con css sin tener que escribir tus propias clases.

También puedes añadir esto a los argumentos de tu wp_list_categories

'hide_empty' => 0

Para mostrar todas las categorías, incluso aquellas que no tienen una publicación.

Hay dos enfoques que puedes tomar para la segunda parte de tu pregunta (añadir el enlace ALL, y eliminar el enlace de las categorías principales)

  1. Puedes usar Javascript/jquery para eliminar/añadir lo que quieras una vez que la página se haya cargado
  2. Puedes escribir un filtro wp_list_categories, para hacer esos cambios

La opción 2 sería la forma más limpia de hacerlo. La opción 1 sería la forma más rápida de hacerlo.

No he llegado a ninguna de las dos, por falta de tiempo. Pero echa un vistazo a cómo crear filtros en WordPress.

9 may 2013 21:32:30
Comentarios

Gracias por la respuesta, sin embargo estoy más interesado en la codificación de WordPress en lugar de CSS como mencioné, ya he creado el HTML y CSS para la imagen incluida. Lo que se requiere es la forma correcta de generar el HTML a través de WordPress similar a lo que he proporcionado. Así que si puedes ampliar los filtros sería genial.

Oudin Oudin
13 may 2013 07:12:32