web-dev-qa-db-fra.com

Terme Checklist Walker - Désactiver les catégories de parents

Actuellement, j'ai une structure dans laquelle les catégories de niveau supérieur agissent comme des pages de renvoi, elles ne doivent donc pas être directement affectées à des publications. Ce que je voudrais faire, c'est désactiver les termes de premier niveau et permettre uniquement à l'utilisateur de vérifier les sous-termes (enfants). J'ai trouvé un marcheur qui transforme les cases à cocher en boutons radio ici mais je ne le comprends pas assez pour ne changer que le parent de niveau supérieur, cela garde en cascade. J'espérais que quelqu'un pourrait expliquer ce qui se passe dans ce programme, la question principale étant "Comment puis-je désactiver les termes du plus haut niveau dans le terme métabox du panneau d'administration"

/**
 * Use radio inputs instead of checkboxes for term checklists in specified taxonomies.
 * https://wordpress.stackexchange.com/questions/139269/wordpress-taxonomy-radio-buttons
 *
 * @param   array   $args
 * @return  array
 */
function wpse_139269_term_radio_checklist( $args ) {
    if ( ! empty( $args['taxonomy'] ) && ($args['taxonomy'] === 'product_cat') ) {
        if ( empty( $args['walker'] ) || is_a( $args['walker'], 'Walker' ) ) {
            if ( ! class_exists( 'WPSE_139269_Walker_Category_Radio_Checklist' ) ) {
                class WPSE_139269_Walker_Category_Radio_Checklist extends Walker_Category_Checklist {
                    function walk( $elements, $max_depth, $args = array() ) {
                        $output = parent::walk( $elements, $max_depth, $args );

                        foreach($elements as $element){
                            if($element->parent == 0){
                                $output = str_replace(
                                    array( 'type="checkbox"', "type='checkbox'" ),
                                    array( 'type="checkbox"', "type='checkbox' disabled='disabled'" ),
                                    $output
                                );
                            }
                        }

                        return $output;
                    }
                }
            }

            $args['walker'] = new WPSE_139269_Walker_Category_Radio_Checklist;
        }
    }

    return $args;
}
add_filter( 'wp_terms_checklist_args', 'wpse_139269_term_radio_checklist' );

elements contient tous les termes dans un tableau, je l’utilise donc pour vérifier si cet élément a un parent dans mon foreach, puis j’essaie de remplacer une sortie et d’ajouter mon indicateur désactivé (un peu comme la question liée transforme les cases à cocher en boutons radio).

1
Howdy_McGee

Edité parce que j'avais complètement mal interprété la question.


Pour savoir si le terme est un parent ou non, nous devons avoir accès à un terme post-parent. Il est donc préférable de remplacer les méthodes plus spécialisées par le rôle de walk().

Cela dit, je comprends que le code dans OP utilise la définition de classe à l'intérieur de la fonction pour éviter une erreur fatale à cause de la classe Walker_Category_Checklist non définie, mais le code devient difficilement lisible de cette façon.

Il est donc préférable d’écrire une fonction personnalisée qui renvoie une instance du programme personnalisé:

add_filter( 'wp_terms_checklist_args', 'wpse_149328_set_walker' );  

function wpse_149328_set_walker( $args ) {
  if (
    ! empty( $args['taxonomy'] )
    && ( $args['taxonomy'] === 'product_cat' ) // only for 'product_cat' taxonomy
    && ( ! isset( $args['walker'] ) || ! $args['walker'] instanceof Walker )
  ) {
    $args['checked_ontop'] = FALSE;
    $args['walker'] = get_Walker_Category_No_Parent();
  }
  return $args;
}

codons maintenant la get_Walker_Category_No_Parent() et le walker personnalisé:

function get_Walker_Category_No_Parent() {

  class Walker_Category_No_Parent extends Walker_Category_Checklist {

   function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
      if ( (int) $category->parent === 0 ) {
         $this->doing_parent = esc_html( $category->name );
      } else {
        parent::start_el( $output, $category, $depth, $args, $id );
      }
    }

    function end_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
      if ( ! isset( $this->doing_parent ) || empty( $this->doing_parent ) ) {
        parent::end_el( $output, $category, $depth, $args, $id );
      }
    }

    function start_lvl( &$output, $depth = 0, $args = array() ) {
      if ( isset( $this->doing_parent ) && ! empty( $this->doing_parent ) ) {
        $output .= '<li><strong>' . $this->doing_parent . '</strong></li>';
        $this->doing_parent = FALSE;
      }
      parent::start_lvl( $output, $depth = 0, $args );
    }

  }
  return new Walker_Category_No_Parent;
}

Ce marcheur affiche les catégories de parents sous forme de texte et uniquement s’ils ont des enfants.

2
gmazzap