如何为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钩子,可按以下步骤排查修复:
- 检查钩子是否存在:添加代码打印钩子的回调列表,确认钩子是否被移除
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'; } } } );
- 调整优先级并修复原函数:如果钩子存在但未触发,调高函数优先级,并初始化可能不存在的
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
相关产品推荐
相关产品推荐

