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

如何为WooCommerce归档页添加OfferCatalog结构化数据(复用查询)

解决WooCommerce分类页OfferCatalog结构化数据无输出问题

问题背景

需要在WooCommerce分类页利用现有查询结果生成OfferCatalog类型的结构化数据,但使用woocommerce_structured_data钩子的代码无输出,怀疑该钩子在分类页被禁用/移除,且不想重复执行数据库查询。


可行解决方案(均避免重复数据库查询)

方法1:直接在分类页模板中输出JSON-LD

WooCommerce的分类页模板(通常是archive-product.php)中已经存在$wp_query对象,直接在模板的合适位置(比如页面头部或尾部)添加代码输出结构化数据,完全复用现有查询结果:

// 在archive-product.php的合适位置添加(比如wp_head结束前或页面底部)
if ( is_product_category() ) {
    $products = $wp_query->get_posts();
    $offer_catalog = array(
        '@context' => 'https://schema.org',
        '@type' => 'CollectionPage',
        'mainEntity' => array(
            '@type' => 'OfferCatalog',
            'itemListElement' => array()
        )
    );

    foreach ( $products as $product ) {
        $_product = wc_get_product( $product->ID );
        if ( ! $_product ) continue;
        
        $availability = $_product->is_in_stock() ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock';
        
        $offer_catalog['mainEntity']['itemListElement'][] = array(
            '@type' => 'Product',
            'name' => get_the_title( $product->ID ),
            'url' => get_permalink( $product->ID ),
            'image' => get_the_post_thumbnail_url( $product->ID, 'full' ),
            'description' => get_the_excerpt( $product->ID ),
            'offers' => array(
                '@type' => 'Offer',
                'price' => $_product->get_price(),
                'priceCurrency' => get_woocommerce_currency(),
                'availability' => $availability
            )
        );
    }

    echo '<script type="application/ld+json">' . json_encode( $offer_catalog ) . '</script>';
}

方法2:通过wp_footer钩子输出,复用全局查询对象

如果不想修改模板,可借助wp_footer钩子,调用全局的$wp_query对象来获取已查询的产品数据,避免重复数据库请求:

function woocommerce_category_offer_catalog_structured_data() {
    if ( ! is_product_category() ) return;

    global $wp_query;
    $products = $wp_query->get_posts();
    if ( empty( $products ) ) return;

    $offer_catalog = array(
        '@context' => 'https://schema.org',
        '@type' => 'CollectionPage',
        'mainEntity' => array(
            '@type' => 'OfferCatalog',
            'itemListElement' => array()
        )
    );

    foreach ( $products as $product ) {
        $_product = wc_get_product( $product->ID );
        if ( ! $_product ) continue;

        $availability = $_product->is_in_stock() ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock';
        
        $offer_catalog['mainEntity']['itemListElement'][] = array(
            '@type' => 'Product',
            'name' => get_the_title( $product->ID ),
            'url' => get_permalink( $product->ID ),
            'image' => get_the_post_thumbnail_url( $product->ID, 'full' ),
            'description' => get_the_excerpt( $product->ID ),
            'offers' => array(
                '@type' => 'Offer',
                'price' => $_product->get_price(),
                'priceCurrency' => get_woocommerce_currency(),
                'availability' => $availability
            )
        );
    }

    echo '<script type="application/ld+json">' . json_encode( $offer_catalog ) . '</script>';
}
add_action( 'wp_footer', 'woocommerce_category_offer_catalog_structured_data' );

方法3:修复原钩子失效问题

如果坚持使用woocommerce_structured_data钩子,可按以下步骤排查修复:

  1. 检查钩子是否存在:添加代码打印钩子的回调列表,确认钩子是否被移除
add_action( 'wp_head', function() {
    if ( is_product_category() ) {
        global $wp_filter;
        if ( isset( $wp_filter['woocommerce_structured_data'] ) ) {
            print_r( $wp_filter['woocommerce_structured_data'] );
        } else {
            echo 'woocommerce_structured_data hook not found';
        }
    }
} );
  1. 调整优先级并修复原函数:如果钩子存在但未触发,调高函数优先级,并初始化可能不存在的mainEntity字段:
function add_structured_data_to_shop_page( $markup, $query ) {
    if ( is_shop() || is_product_category() || is_product_tag() ) {
        $markup['@type'] = 'CollectionPage';
        
        // 初始化mainEntity字段,避免未定义报错
        if ( ! isset( $markup['mainEntity'] ) ) {
            $markup['mainEntity'] = array();
        }
        
        $markup['mainEntity']['@type'] = 'OfferCatalog';
        $markup['mainEntity']['itemListElement'] = array();

        $products = $query->get_posts();
        foreach ( $products as $product ) {
            $_product = wc_get_product( $product->ID );
            if ( ! $_product ) continue;
            
            $availability = $_product->is_in_stock() ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock';
            
            $markup['mainEntity']['itemListElement'][] = array(
                '@type' => 'Product',
                'name' => get_the_title( $product->ID ),
                'url' => get_permalink( $product->ID ),
                'image' => get_the_post_thumbnail_url( $product->ID, 'full' ),
                'description' => get_the_excerpt( $product->ID ),
                'offers' => array(
                    '@type' => 'Offer',
                    'price' => $_product->get_price(),
                    'priceCurrency' => get_woocommerce_currency(),
                    'availability' => $availability,
                ),
            );
        }
    }

    return $markup;
}
// 调高优先级确保函数被执行
add_filter( 'woocommerce_structured_data', 'add_structured_data_to_shop_page', 20, 2 );

内容的提问来源于stack exchange,提问作者Mesmer7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 02:42:04