如何通过子主题或functions.php保留WooCommerce筛选小部件H1标签修改
解决WooCommerce筛选结果属性名改为H1且避免插件更新丢失的方法
方法一:使用内置过滤器修改输出(推荐)
WooCommerce提供了woocommerce_layered_nav_filters_term_html过滤器,可直接修改筛选标签的HTML结构,无需改动插件核心文件,步骤如下:
- 在子主题的
functions.php文件中添加以下代码:
add_filter( 'woocommerce_layered_nav_filters_term_html', 'replace_filter_term_with_h1', 10, 4 ); function replace_filter_term_with_h1( $html, $term, $taxonomy, $link ) { // 保留原样式类,将默认标签替换为H1 $filter_classes = array( 'chosen', 'chosen-' . sanitize_html_class( str_replace( 'pa_', '', $taxonomy ) ), 'chosen-' . sanitize_html_class( str_replace( 'pa_', '', $taxonomy ) . '-' . $term->slug ) ); $class_str = esc_attr( implode( ' ', $filter_classes ) ); $aria_label = esc_attr__( 'Remove filter', 'woocommerce' ); $term_name = esc_html( $term->name ); return "<h1 class=\"{$class_str}\"><a rel=\"nofollow\" aria-label=\"{$aria_label}\" href=\"{$link}\">{$term_name}</a></h1>"; }
这段代码会拦截原筛选标签输出,将默认的<span>替换为<h1>,同时保留原有样式和移除筛选的功能。
方法二:重写Layered Nav Filters Widget类
若需深度自定义,可通过子主题重写Widget类,步骤如下:
- 在子主题的
functions.php中添加以下代码:
// 注销原Widget add_action( 'widgets_init', 'unregister_original_layered_nav_filters_widget', 11 ); function unregister_original_layered_nav_filters_widget() { unregister_widget( 'WC_Widget_Layered_Nav_Filters' ); } // 重写Widget类,仅修改标签输出部分 class WC_Widget_Layered_Nav_Filters_Custom extends WC_Widget_Layered_Nav_Filters { public function widget( $args, $instance ) { global $_chosen_attributes, $wp_query; if ( ! is_shop() && ! is_product_taxonomy() ) { return; } $base_link = esc_url( apply_filters( 'woocommerce_layered_nav_filters_base_link', get_permalink( wc_get_page_id( 'shop' ) ) ) ); ob_start(); do_action( 'woocommerce_widget_layered_nav_filters_start', $args, $instance ); // 遍历选中的属性 if ( ! empty( $_chosen_attributes ) ) { foreach ( $_chosen_attributes as $taxonomy => $data ) { foreach ( $data['terms'] as $term_slug ) { $term = get_term_by( 'slug', $term_slug, $taxonomy ); if ( ! $term ) { continue; } $filter_name = 'filter_' . wc_attribute_taxonomy_slug( $taxonomy ); $current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( wp_unslash( $_GET[ $filter_name ] ) ) ) : array(); $current_filter = array_map( 'sanitize_title', $current_filter ); $new_filter = array_diff( $current_filter, array( $term_slug ) ); $link = remove_query_arg( array( 'add-to-cart', $filter_name ), $base_link ); if ( count( $new_filter ) > 0 ) { $link = add_query_arg( $filter_name, implode( ',', $new_filter ), $link ); } $filter_classes = array( 'chosen', 'chosen-' . sanitize_html_class( str_replace( 'pa_', '', $taxonomy ) ), 'chosen-' . sanitize_html_class( str_replace( 'pa_', '', $taxonomy ) . '-' . $term_slug ) ); // 替换为H1标签 echo '<h1 class="' . esc_attr( implode( ' ', $filter_classes ) ) . '"><a rel="nofollow" aria-label="' . esc_attr__( 'Remove filter', 'woocommerce' ) . '" href="' . esc_url( $link ) . '">' . esc_html( $term->name ) . '</a></h1>'; } } } do_action( 'woocommerce_widget_layered_nav_filters_end', $args, $instance ); $content = ob_get_clean(); if ( ! empty( $content ) ) { echo $args['before_widget'] . $args['before_title'] . apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base ) . $args['after_title'] . $content . $args['after_widget']; } } } // 注册自定义Widget add_action( 'widgets_init', 'register_custom_layered_nav_filters_widget' ); function register_custom_layered_nav_filters_widget() { register_widget( 'WC_Widget_Layered_Nav_Filters_Custom' ); }
这段代码会先注销原有筛选Widget,再注册一个继承原类的自定义Widget,仅修改输出标签为H1,其余逻辑与原插件保持一致。
关键说明
- 子主题无法直接覆盖插件
includes/widgets目录下的文件,因为WooCommerce的模板覆盖机制仅针对templates目录下的前端模板,不包含核心类文件。 - 优先使用方法一,代码更简洁,且无需关注原Widget类的逻辑变更,兼容性更强。
内容的提问来源于stack exchange,提问作者John Adams
相关产品推荐
相关产品推荐

