使用WooCommerce钩子在分类页导致价格显示异常
问题描述
在WooCommerce产品分类列表页面,通过woocommerce_after_shop_loop_item_title钩子添加自定义字段展示逻辑后,自定义信息显示正常,但每个产品条目下会重复显示当前页面所有产品的价格。移除该钩子后价格显示恢复正常,即使清空函数内的代码块,问题依然存在。
异常表现:每个产品卡片下方会列出页面内所有产品的价格(产品条目重复叠加多个价格信息)。
原代码如下:
add_action( 'woocommerce_after_shop_loop_item_title', 'paradigm_custom_category_display', 5 ); function paradigm_custom_category_display() { global $product; if ( $product->get_short_description()) { ?> <h2 class="woocommerce-loop-product__title pp-shortdescription"> <?php echo apply_filters( 'woocommerce_short_description', $product->get_short_description() ) ?> </h2> <?php } ?> <div class="pp-block"> <?php if(get_field('author_name')) { ?> <div class="pp-author"><span>Author: </span><a href="<?php the_field('author_link'); ?>" class="fancybox-iframe"><?php the_field('author_name'); ?></a></div> <?php } if(get_field('pages')) { ?> <div class="pp-pages"><span>Pages: </span><?php the_field('pages'); ?></div> <?php } if(get_field('size')) { ?> <div class="pp-size"><span>Size: </span><?php the_field('size'); ?></div> <?php } if(get_field('isbn')) { ?> <div class="pp-isbn"><span>ISBN: </span><?php the_field('isbn'); ?></div> <?php } if(get_field('binding')) { ?> <div class="pp-binding"><span>Binding: </span><?php the_field('binding'); ?></div> <?php } ?> </div> <?php }
问题原因及解决办法
核心原因
- ACF的
get_field()/the_field()默认依赖全局$post->ID查询字段,但在WooCommerce产品循环中,全局$post可能与当前$product对象不同步,导致字段查询上下文混乱,进而破坏后续价格模板的输出逻辑。 - 钩子优先级设置为5(早于价格模板的默认优先级10),函数执行时的上下文干扰了价格模板的正常循环输出。
修正方案
修改代码,明确指定ACF字段查询的产品ID,并调整钩子优先级避免干扰价格输出:
add_action( 'woocommerce_after_shop_loop_item_title', 'paradigm_custom_category_display', 15 ); function paradigm_custom_category_display() { global $product; // 提前判断产品对象是否存在,避免报错 if ( ! $product ) return; $product_id = $product->get_id(); if ( $product->get_short_description()) { ?> <h2 class="woocommerce-loop-product__title pp-shortdescription"> <?php echo apply_filters( 'woocommerce_short_description', $product->get_short_description() ); ?> </h2> <?php } ?> <div class="pp-block"> <?php if( get_field('author_name', $product_id) ) { ?> <div class="pp-author"><span>Author: </span><a href="<?php the_field('author_link', $product_id); ?>" class="fancybox-iframe"><?php the_field('author_name', $product_id); ?></a></div> <?php } if( get_field('pages', $product_id) ) { ?> <div class="pp-pages"><span>Pages: </span><?php the_field('pages', $product_id); ?></div> <?php } if( get_field('size', $product_id) ) { ?> <div class="pp-size"><span>Size: </span><?php the_field('size', $product_id); ?></div> <?php } if( get_field('isbn', $product_id) ) { ?> <div class="pp-isbn"><span>ISBN: </span><?php the_field('isbn', $product_id); ?></div> <?php } if( get_field('binding', $product_id) ) { ?> <div class="pp-binding"><span>Binding: </span><?php the_field('binding', $product_id); ?></div> <?php } ?> </div> <?php }
关键修正点
- 所有ACF字段函数(
get_field()、the_field())都传入了当前产品ID$product_id,确保字段查询的是当前产品的数据,避免上下文混乱。 - 调整钩子优先级为15,让自定义内容在价格之后显示,彻底避免干扰价格模板的执行流程。
- 增加
$product对象存在检查,防止循环中出现空对象导致的报错。 - 修正了原代码中HTML标签的转义问题,恢复正常的HTML语法。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

