web-dev-qa-db-fra.com

Contrôle des listes de catégories de taxonomie pour masquer et afficher les détails

J'ai un menu vertical utilisant le script superfish qui montre les catégories dans une taxonomie personnalisée "productcategory". Ce menu a plusieurs niveaux et est hiérarchique. Au bas de chaque branche de l’arbre, nous avons la catégorie de fin qui représente une gamme de produits, ce que le client ne fait pas veux montrer dans ce menu.

J'utilise ce code pour l'afficher:

<ul class="frontcatlist sf-menu">
<?php
    $a = array(
        'title_li'  =>  '',
        'taxonomy'  =>  'productcategory',
        'depth'     =>  2
    );
    wp_list_categories( $a );
?>
</ul>

C'est ce que j'ai actuellement en termes de ce qui est affiché et de ce qui n'est pas. gauche étant les catégories principales, et chaque ligne étant 1 descendant à ses enfants:

alt text

Ceux dans le rouge sont les catégories qui ne sont pas affichées dans le menu,

Ce n'est cependant pas ce dont mon client a besoin. Bien que je puisse produire un menu qui corresponde aux exigences à l'aide des menus natifs de Wordpress 3, cela nécessiterait une intervention manuelle, une intervention indésirable, à la fois du point de vue de la convivialité et des souhaits du client.

Étant donné que certaines catégories principales ont des sous-catégories qui devraient être affichées et d’autres non, le paramètre profondeur ne suffira pas. C’est plutôt ce dont j’ai besoin, les catégories de niveau supérieur indiquant toujours:

alt text

Je ne suis pas sûr de savoir comment faire cela, et le seul indice que j’ai est une classe de promeneur personnalisée permettant de générer du code HTML personnalisé, au cours de laquelle je pourrais éventuellement filtrer celles que je ne souhaite pas (toutes catégories). avec un parent qui n’a pas d’enfants) . Mais je ne voyais pas suffisamment d'exemples ou d'articles sur le sujet, et je préférerais ne pas perdre les classes et le balisage fourni par wordpress

Si quelqu'un a des idées ou est au courant des publications sur le forum ou des articles d'utilisation de tutoriels, je l'apprécierais beaucoup =)

1
Tom J Nowell

J'ai fait quelques progrès en me basant sur les classes de marcheur, mais je n’ai pas réussi à travailler aussi bien que nécessaire, car Wordpress ne semble pas gérer les nœuds racine de l’arbre de taxonomie de la même manière que ceux d’enfant.

Par conséquent, il élague les éléments de menu de fin, mais si le parent de ce nœud est un nœud de niveau racine, il élague le nœud et laisse un élément ul vide derrière, <ul></ul>. Le code qui résout ce problème sur les nœuds enfants ne fonctionne pas pour un nœud racine, ce qui entraîne l'aplatissement de toute la structure sans sous-menu.

class Post_Category_Walker extends Walker_Category {

    private $term_ids = array();
    function __construct( /*$post_id,*/ $taxonomy )  {
        // fetch the list of term ids for the given post
        $this->taxterms = get_terms( $taxonomy);
        $this->noshow = array();
    }
    function isdisplayable( $element, &$children_elements, $args ){
        $id = $element->term_id;
        if(in_array($element->term_id, $this->noshow)){
            return false;
        }
        $display = true;
        if($element->parent != 0){
            $display = false;
            if ( isset( $children_elements[ $id ] ) ) {
                $display = true;
            }
        }
        if($depth == 0){
            $display = true;
        }
        return $display;
    }
    function hasChildren( $element/*, &$children_elements*/){
        foreach($this->taxterms as $term){
            if($term->parent == $element->term_id){
                return true;
            }
        }
        return false;//(isset($children_elements[$element->term_id]));
    }
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
        $display = $this->isdisplayable( $element, $children_elements, $args );
        $id = $element->term_id;
        if($element->parent != 0){

            if($this->hasChildren($element)){ //isset( $children_elements[ $id ] ) ) {
                $endnode = true;
                //print_r($children_elements[ $id ]);
                foreach($this->taxterms as $child){
                    if($child->parent == $element->term_id){
                        if($this->hasChildren($child)){
                            $endnode = false;
                            break;
                        }
                    }
                }
                if($endnode == true){
                    //$children_elements = NULL;
                    unset( $children_elements[ $id ] );
                    $newlevel = false;
                    $args[0]['has_children'] = 0;
                }
            }
        }else{
            // Wordpress separates out the terms into top level and child terms,
            // making the top level terms very costly as it passes in an empty 
            // array as the children_elements unlike the other terms
            //if($this->hasChildren($element)){
                foreach($this->taxterms as $term){
                    if($term->parent == $element->term_id){
                        if(!$this->hasChildren($term)){
                            $this->noshow[] = $term->term_id;
                            unset($newlevel);
                            $args[0]['has_children'] = 0;
                        }
                    }
                }
            //}
        }

        if ( $display )
            parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }
}
$a = array(
    'title_li'  =>  '',
    'taxonomy'  =>  'productcategory',
    'walker'    =>  new Post_Category_Walker('productcategory')
);
wp_list_categories( $a );

Une solution temporaire consiste à les supprimer via l'extrait de code jQuery suivant:

$("ul").each(
  function() {
    var elem = $(this);
    if (elem.children().length == 0) {
      elem.remove();
    }
  }
);
1
Tom J Nowell