WooCommerce产品页Read More与Show Composer按钮冲突问题排查
问题与解决方案
问题现象
在WordPress 2024主题的单个产品模板中,存在两个功能按钮:
- 产品详情区块内的Read More按钮:用于展开产品长描述
- Show Composer按钮:点击后匹配ACF字段值与自定义文章类型
composers的标题,展示对应文章内容,无匹配时不显示
当前问题:仅当Show Composer按钮显示时,Read More按钮失效;无匹配时Read More按钮可正常工作。
冲突原因
你的推测完全正确,冲突源于the_content过滤器和the_content()函数的调用逻辑问题:
- 原
filter_the_content过滤器仅用is_product()判断生效条件,但is_product()是针对主查询的。当执行composer_query自定义查询并调用the_content()时,主查询仍为产品页面,但当前循环的post已经是composers类型,过滤器会错误地作用在composer的内容上 - 这会导致页面出现重复的
#more、#read-button、#dots等全局唯一ID,同时Read More的JS代码会被重复输出多次,直接干扰原产品描述的JS逻辑,最终导致Read More按钮失效
解决步骤
1. 修改Read More过滤器,精准限制作用范围
更新filter_the_content函数,在is_product()基础上增加get_post_type() == 'product'判断,确保过滤器只处理产品类型的文章内容:
/*====================================================================================== #6 Shorten product long description with read more button =======================================================================================*/ function filter_the_content( $content ) { // 仅作用于单个产品页面,且当前post类型为product if( ! is_product() || get_post_type() !== 'product' ) return $content; // 设置字数限制 $limit = 25; // 移除p标签 $content = str_replace( array( '<p>', '</p>' ), '', $content ); // 内容超过限制时处理 if ( str_word_count( $content, 0 ) > $limit ) { $arr = str_word_count( $content, 2 ); $pos = array_keys( $arr ); // 拼接截断后的内容与按钮 $text = '<p>' . substr( $content, 0, $pos[$limit] ) . '<span id="dots">...</span>'; $text .= '<span id="more">' . substr( $content, $pos[$limit] ) . '</span></p>'; $text .= '<button id="read-button"></button>'; $content = force_balance_tags( $text ); } return $content; } add_filter( 'the_content', 'filter_the_content', 10, 1 );
2. 将Read More的JS代码移到独立钩子,避免重复加载
原代码中JS直接嵌入过滤器输出,会随the_content()多次加载,现在把它移到wp_footer钩子,确保仅加载一次:
// 加载Read More的JS脚本 function product_read_more_scripts() { if( ! is_product() ) return; ?> <script type="text/javascript"> jQuery(document).ready( function ($) { var read_more_btn_txt = 'Read more'; var read_less_btn_txt = 'Read less'; var more = '#more'; var read_button = '#read-button'; var dots = '#dots'; $( more ).hide(); $( read_button ).html( read_more_btn_txt ); $( read_button ).on( 'click', function() { if ( $( more ).is( ':hidden' ) ) { $( more ).show(); $( dots ).hide(); $( read_button ).html( read_less_btn_txt ); } else { $( more ).hide(); $( dots ).show(); $( read_button ).html( read_more_btn_txt ); } }); }); </script> <?php } add_action('wp_footer', 'product_read_more_scripts');
3. 保留Show Composer原有代码(无需修改)
原有的Show Composer短代码和JS逻辑保持不变,因为我们已经通过修改过滤器避免了它的内容被错误处理。
验证效果
修改后,当Show Composer按钮显示时:
- 产品描述的Read More过滤器只会作用在产品内容上
- Composer的内容不会被Read More过滤器修改,不会生成重复ID
- JS脚本仅加载一次,保证Read More按钮的点击逻辑正常运行
内容的提问来源于stack exchange,提问作者RobPL
相关产品推荐
相关产品推荐

