WooCommerce更新后自定义作曲家内容显示代码失效求助
WooCommerce更新后自定义文章类型内容获取失效的修复方案
问题概述
我拥有名为Composers的自定义文章类型,此前在WordPress 2024子主题的产品描述页面模板中,通过自定义代码提取该类型文章内容并实现点击按钮显示/隐藏对应作曲家详情的功能,代码运行正常。但在最近的WooCommerce更新后,代码失效无法获取文章内容,目前在两个不同主机的网站上均出现此问题。原代码如下:
// Function to get the composer post content by title function get_composer_content_by_title( $title ) { $args = array( 'post_type' => 'composers', 'name' => sanitize_title( $title ), 'posts_per_page' => 1, 'post_status' => 'publish', ); $composer_posts = get_posts( $args ); if ( !empty( $composer_posts ) ) { return $composer_posts[0]->post_content; } return ''; // Return empty string if no post found } // Shortcode to display the composer content function display_composer_content_shortcode( $atts ) { $atts = shortcode_atts( array( 'button_text' => 'Show Composer Info', ), $atts ); global $post; $composer_title = get_field( 'composer', $post->ID ); $composer_content = get_composer_content_by_title( $composer_title ); // Button to show/hide the composer content $output = '<button class="show_composer" onclick="toggleComposerContent()">' . esc_html( $atts['button_text'] ) . '</button>'; $output .= '<div id="composerContent" style="display:none;">' . $composer_content . '</div>'; // Add some JavaScript to handle the toggle $output .= '<script> function toggleComposerContent() { var content = document.getElementById("composerContent"); if (content.style.display === "none") { content.style.display = "block"; } else { content.style.display = "none"; } } </script>'; return $output; } add_shortcode( 'composer_info', 'display_composer_content_shortcode' );
原因分析
- 全局$post上下文变化:WooCommerce更新后,产品页面的全局
$post对象可能在短码执行时未正确指向当前产品,导致get_field('composer', $post->ID)获取不到正确的作曲家标题。 - Slug匹配问题:原代码用
sanitize_title($title)生成slug去查询Composers文章,但自动生成的文章slug可能和手动处理后的字符串不一致(比如包含特殊字符、多空格处理差异),导致查询不到结果。 - JavaScript重复定义:如果短码在页面中多次使用,会重复定义
toggleComposerContent函数,引发冲突导致功能失效。
修复代码
针对上述问题,调整后的代码如下:
// Function to get the composer post content by title function get_composer_content_by_title( $title ) { if ( empty( $title ) ) { return ''; } // 使用WP_Query直接匹配文章标题,避免slug不匹配问题 $query = new WP_Query( array( 'post_type' => 'composers', 'post_title' => $title, 'posts_per_page' => 1, 'post_status' => 'publish', 'no_found_rows' => true, // 优化性能,不需要总条数 ) ); if ( $query->have_posts() ) { $query->the_post(); $content = get_the_content(); wp_reset_postdata(); // 重置查询上下文 return $content; } return ''; } // Shortcode to display the composer content function display_composer_content_shortcode( $atts ) { $atts = shortcode_atts( array( 'button_text' => 'Show Composer Info', ), $atts ); // 改用WooCommerce产品对象获取ID,确保上下文正确 $product_id = get_the_ID(); if ( function_exists( 'wc_get_product' ) ) { $product = wc_get_product( $product_id ); if ( $product ) { $product_id = $product->get_id(); } } $composer_title = get_field( 'composer', $product_id ); $composer_content = get_composer_content_by_title( $composer_title ); if ( empty( $composer_content ) ) { return ''; // 无内容时不输出按钮和容器 } // 生成唯一ID避免重复冲突 $unique_id = 'composer-content-' . uniqid(); // 输出按钮和内容容器,转义HTML避免XSS $output = '<button class="show_composer" onclick="toggleComposerContent(\'' . esc_js( $unique_id ) . '\')">' . esc_html( $atts['button_text'] ) . '</button>'; $output .= '<div id="' . esc_attr( $unique_id ) . '" style="display:none;">' . apply_filters( 'the_content', $composer_content ) . '</div>'; // 只输出一次JavaScript代码 static $script_added = false; if ( !$script_added ) { $output .= '<script> function toggleComposerContent(elementId) { var content = document.getElementById(elementId); if (content) { content.style.display = content.style.display === "none" ? "block" : "none"; } } </script>'; $script_added = true; } return $output; } add_shortcode( 'composer_info', 'display_composer_content_shortcode' );
额外优化建议
- ACF字段类型调整:如果你的ACF「composer」字段当前是文本类型存储标题,建议改为「文章」类型并选择Composers自定义文章类型,这样字段会存储文章ID,查询时直接用
get_post($composer_id)获取内容,比按标题查询更可靠且性能更好。 - 样式分离:将按钮和内容容器的样式移到子主题的CSS文件中,避免内联样式难以维护。
- 缓存优化:对作曲家内容添加缓存,比如使用
wp_cache_get和wp_cache_set,减少数据库查询次数。
内容的提问来源于stack exchange,提问作者RobPL
相关产品推荐
相关产品推荐

