Cum pot personaliza wp_list_categories
Am o listă de categorii în WooCommerce pe care încerc să o personalizez pentru a arăta ca în imaginea următoare.
Am creat imaginea de mai sus folosind HTML și CSS obișnuit, însă acum aș dori să o convertesc în WordPress pentru a fi generată dinamic.
Iată codul HTML:
<div class="col tertiary" id="filters">
<ul class="product-categories">
<li id="pattern_garment_type">
<h5>Femei</h5>
<ul>
<li class="selected">
<a href="#">Toate</a>
</li>
<li class="">
<a href="#">Accesorii</a>
</li>
<li class="">
<a href="#">Bluze</a>
</li>
.etc...
</ul>
</li>
<li id="pattern_garment_type">
<h5>Bărbați</h5>
<ul>
<li class="selected">
<a href="#">Toate</a>
</li>
<li class="">
<a href="#">Accesorii</a>
</li>
<li class="">
<a href="#">Paltoane</a>
</li>
..etc..
</ul>
</li>
<li id="pattern_garment_type">
<h5>Copii</h5>
<ul>
<li class="selected">
<a href="#">Toate</a>
</li>
<li class="">
<a href="#">Bebeluși</a>
</li>
<li class="">
<a href="#">Fete</a>
</li>
<li class="">
<a href="#">Băieți</a>
</li>
</ul>
</li>
</ul>
</div>
Iată codul WordPress actual cu care lucrez (nu sunt sigur dacă ar trebui să folosesc walker-ul pentru a personaliza output-ul care să fie generat ca HTML-ul de mai sus):
<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' => __('Nu există elemente în meniu'),
'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) Cum pot folosi filtrul wp_list_categories pentru a adăuga un link "Toate" în partea de sus a subcategoriilor care să facă legătura către o pagină ce afișează toate elementele.
2) Cum pot folosi filtrul wp_list_categories pentru a elimina link-ul din categoria părinte principală și a-l împacheta într-un <h5> pentru a-l face îngroșat (ca în exemplul din imagine)?
Orice ajutor ar fi apreciat
Chiar dacă există un filtru wp_list_categories
, acesta trece (și deci trebuie să returnezi) markup-ul HTML generat de funcția wp_list_categories()
. Aceasta înseamnă că dacă vrei să folosești acel filtru, trebuie să alterezi DOM-ul cu PHP, și chiar dacă este posibil (sperăm folosind biblioteci PHP externe), cu siguranță nu este cea mai bună soluție pentru nevoile tale.
Alternativa este să folosești JavaScript pentru a modifica HTML-ul după ce a fost creat. Este o posibilitate, dar eu sunt un dezvoltator WordPress, nu unul de JavaScript, așa că îți voi oferi soluția WordPress.
Trebuie să creezi o clasă personalizată Category Walker și apoi să o folosești în cadrul unei versiuni personalizate a funcției wp_list_categories().
Să începem.
Mai întâi, clasa personalizată Category Walker (pune-o în 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 . "'>" . __('Toate') . "</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;
}
}
Aceasta extinde WP Walker_Category și suprascrie toate cele 4 metode cu ceva care se potrivește nevoilor tale.
După aceea, în functions.php
pune funcția personalizată:
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;
}
Partea dificilă este făcută. Acum codul pentru template, pune-l oriunde ai nevoie:
<div id="content-filters" class="two columns">
<div class="col tertiary" id="filters">
<?php
$args = array(
'taxonomy' => 'product_cat',
'show_option_none' => __('Nu există elemente de meniu.'),
'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>
Personalizează argumentele $args dacă dorești, le-am setat conform codului din răspunsul tău. Doar am schimbat 'pattern_garment_type' să fie clasă și nu id, pentru că nu poți avea același id de tag de mai multe ori în HTML (ca în markup-ul tău).
Asta e tot, sper că te ajută.

Oudin,
Voi răspunde aici la partea CSS a întrebării tale:
Folosește următoarele pentru a elimina bullet points-urile din listă:
.ul.product-categories, ul.children{
list-style-type: none;
}
Folosește următoarele pentru a face doar categoriile principale bold:
li {font-weight:normal} // trebuie să setezi mai întâi starea implicită a listei
ul.product-categories > li{font-weight:bold;} // apoi poți modifica doar nivelul superior al listei fără a afecta elementele copil
Așa poți ținti acele elemente cu CSS fără a fi nevoie să scrii propriile clase.
Poți adăuga și acest argument la wp_list_categories
'hide_empty' => 0
Pentru a afișa toate categoriile, chiar și cele care nu au postări.
Există două abordări pentru partea a doua a întrebării tale (adaugarea linkului ALL și eliminarea linkului din categoriile principale)
- Poți folosi Javascript/jQuery pentru a elimina/adauga ce dorești după ce pagina s-a încărcat
- Poți scrie un filtru pentru wp_list_categories pentru a face acele modificări
Opțiunea 2 ar fi cea mai elegantă modalitate de a face acest lucru. Opțiunea 1 ar fi cea mai rapidă modalitate de a face acest lucru.
Nu am ajuns încă la niciuna din ele din cauza lipsei de timp. Dar uită-te la crearea de filtre în WordPress.

Mulțumesc pentru răspuns, totuși sunt mai interesat de codarea în WordPress decât de CSS, așa cum am menționat deja am creat HTML și CSS pentru imaginea inclusă. Ceea ce este necesar este modalitatea corectă de a genera HTML prin WordPress similar cu ceea ce am oferit. Deci dacă poți să dezvolți mai mult despre filtre, ar fi minunat.
