术语核对表查看器-禁用父类别

时间:2014-06-11 作者:Howdy_McGee

目前,我有一个结构,其中顶级类别的作用类似于登录页,因此它们应该没有直接分配给它们的帖子。我想做的是禁用顶级术语,只允许用户检查子术语(子术语)。我发现了一种可以将复选框转换为单选按钮的助行器here 但我对它的理解还不够,只能更改顶级父级,它一直是级联的。我希望有人能分析一下这个助行器中发生的事情,主要问题是“如何禁用管理面板术语元数据库中的顶级术语”

/**
 * 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\' );
元素保存数组中的所有术语,因此我使用它来测试该元素在我的foreach中是否有父元素,然后我尝试替换一些输出并附加我的禁用标志(很像链接的问题将复选框变成单选按钮)。

1 个回复
最合适的回答,由SO网友:gmazzap 整理而成

编辑是因为我完全误读了这个问题walk().

也就是说,我知道OP中的代码在函数中使用类定义来避免致命错误,因为Walker_Category_Checklist 类未定义,但代码很难以这种方式读取。

因此,我认为最好编写一个自定义函数,返回自定义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;
}
现在,让我们编写get_Walker_Category_No_Parent() 和定制步行者:

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;
}
此walker仅当父类别有一些子类别时,才将其输出为文本。

结束