You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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' );

原因分析

  1. 全局$post上下文变化:WooCommerce更新后,产品页面的全局$post对象可能在短码执行时未正确指向当前产品,导致get_field('composer', $post->ID)获取不到正确的作曲家标题。
  2. Slug匹配问题:原代码用sanitize_title($title)生成slug去查询Composers文章,但自动生成的文章slug可能和手动处理后的字符串不一致(比如包含特殊字符、多空格处理差异),导致查询不到结果。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:29:56