Come personalizzare wp_list_categories
Ho una lista di categorie in WooCommerce che sto cercando di personalizzare per farla apparire come nell'immagine seguente.
Ho creato l'immagine sopra usando HTML e CSS standard, ma ora vorrei convertirla in WordPress per averla generata dinamicamente.
Ecco l'HTML:
<div class="col tertiary" id="filters">
<ul class="product-categories">
<li id="pattern_garment_type">
<h5>Donna</h5>
<ul>
<li class="selected">
<a href="#">Tutti</a>
</li>
<li class="">
<a href="#">Accessori</a>
</li>
<li class="">
<a href="#">Camicette</a>
</li>
.ecc...
</ul>
</li>
<li id="pattern_garment_type">
<h5>Uomo</h5>
<ul>
<li class="selected">
<a href="#">Tutti</a>
</li>
<li class="">
<a href="#">Accessori</a>
</li>
<li class="">
<a href="#">Cappotti</a>
</li>
..ecc..
</ul>
</li>
<li id="pattern_garment_type">
<h5>Bambini</h5>
<ul>
<li class="selected">
<a href="#">Tutti</a>
</li>
<li class="">
<a href="#">Neonati</a>
</li>
<li class="">
<a href="#">Bambine</a>
</li>
<li class="">
<a href="#">Bambini</a>
</li>
</ul>
</li>
</ul>
</div>
Ecco il codice WordPress attuale con cui sto lavorando (non sono sicuro se dovrei usare il walker per personalizzare l'output da generare come l'HTML sopra):
<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' => __('Nessuna Voce di Menu'),
'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) Come posso usare il filtro wp_list_categories per aggiungere un link "Tutti" in cima alle sotto-categorie che colleghi a una pagina che mostra tutti gli elementi.
2) Come posso anche usare il filtro wp_list_categories per rimuovere il link dalla categoria genitore e avvolgerlo in un tag h5 per renderlo in grassetto (come nell'immagine di esempio)?
Qualsiasi aiuto sarebbe apprezzato
Anche se esiste un filtro wp_list_categories
, questo passa (e quindi devi restituire) il markup html generato dalla funzione wp_list_categories()
. Ciò significa che se vuoi usare quel filtro devi modificare il DOM con php, e anche se è possibile (si spera utilizzando librerie php esterne), sicuramente non è la soluzione migliore per le tue esigenze.
Un'alternativa è usare js per modificare l'html dopo che è stato creato. È una possibilità, ma io sono uno sviluppatore WP non js, quindi ti darò la soluzione WordPress.
Devi creare una classe personalizzata Category Walker e poi usarla all'interno di una versione personalizzata di wp_list_categories();
Iniziamo.
Prima di tutto la classe personalizzata Category Walker (inseriscila in 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 . "'>" . __('All') . "</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;
}
}
Estende la WP Walker_Category e sovrascrive tutti i 4 metodi con qualcosa che si adatti alle tue esigenze.
Dopodiché, nel functions.php
inserisci la funzione personalizzata:
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 difficile è fatta. Ora il codice del template, inseriscilo dove ti serve:
<div id="content-filters" class="two columns">
<div class="col tertiary" id="filters">
<?php
$args = array(
'taxonomy' => 'product_cat',
'show_option_none' => __('No Menu Items.'),
'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>
Personalizza gli $args se vuoi, li ho impostati secondo il codice della tua risposta. Solo ho cambiato 'pattern_garment_type' in classe e non in id, perché non puoi avere lo stesso id di tag più volte in html (come nel tuo markup).
Questo è tutto, spero che ti aiuti.

Oudin,
Risponderò qui alla parte CSS della tua domanda:
Usa questo per rimuovere i pallini dell'elenco:
.ul.product-categories, ul.children{
list-style-type: none;
}
Usa questo per rendere in grassetto solo le categorie principali:
li {font-weight:normal} // devi prima impostare lo stato predefinito della lista
ul.product-categories > li{font-weight:bold;} //poi puoi modificare il livello superiore della lista senza influenzare i figli
Ecco come puoi mirare a quegli elementi con css senza dover scrivere le tue classi.
Puoi anche aggiungere questo agli argomenti di wp_list_categories
'hide_empty' => 0
Per mostrare tutte le categorie, anche quelle che non hanno un post.
Ci sono due approcci che puoi adottare per la seconda parte della tua domanda (aggiungere il link TUTTO e rimuovere il link dalle categorie principali)
- Puoi usare Javascript/jquery per rimuovere/aggiungere ciò che vuoi una volta che la pagina è stata caricata
- Puoi scrivere un filtro wp_list_categories, per fare quei cambiamenti
L'opzione 2 sarebbe il modo più pulito per farlo. L'opzione 1 sarebbe il modo più veloce per farlo.
Non ho avuto il tempo di approfondire nessuna delle due, per mancanza di tempo. Ma dai un'occhiata alla creazione di filtri in wordpress.

Grazie per la risposta, tuttavia sono più interessato alla codifica di WordPress piuttosto che al CSS, come ho già detto ho già creato l'HTML e il CSS per l'immagine inclusa. Ciò che è necessario è il modo corretto per generare l'HTML tramite WordPress, simile a quello che ho fornito. Quindi, se puoi approfondire i filtri, sarebbe fantastico.
