Currently I have a structure where the top level categories are acting like landing pages, so they should have no posts directly assigned to them. What I would like to do is disable the top level terms and only allow the user to check sub-terms (children). I’ve found a walker which transforms checkboxes to radio buttons here but I don’t quite understand it enough to only change the top level parent, it keeps cascading. Was hoping somebody could break down what is going on in this walker with the main question being “How do I disable top level terms in the admin panel term metabox”
/**
* 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 holds all the terms in an array so I use that to test whether that element has a parent in my foreach then I try to replace some output and append my disabled flag (much like the linked question turns checkboxes into radio buttons).
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Edited because I had completely misread question.
To know if term is a parent or not, we need access to term post parent, so is better to replace more specialized methods istead of walk().
That said, I understand that code in OP uses class definition inside the function to avoid fatal error because of Walker_Category_Checklist class not defined, however code becomes hardly readable in that way.
So I think is better write a custom function that return an instance of the custom walker:
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;
}
now let’s code the get_Walker_Category_No_Parent() and the custom walker:
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;
}
This walker output parent categories as text and only if they have some children.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0