首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >产品目录用自定义文章类型还是 WooCommerce 商品:数据结构、查询和扩展的差别

产品目录用自定义文章类型还是 WooCommerce 商品:数据结构、查询和扩展的差别

原创
作者头像
用户10345225
发布于 2026-10-30 12:22:18
发布于 2026-10-30 12:22:18
870
举报

一个工业配件站,产品页要列型号、功率、接口、认证,访客按功率区间筛,暂时不结账。上线前先要定的是这些型号存成 catalog_item 还是 WooCommerce 的 product,模板好不好看反而在后面。两者都能做出列表页,差别在数据落在哪里、查询怎么写、以后接不接交易。

需要做的事

自定义文章类型

WooCommerce 商品

只展示、询价

用 wp_posts 加自定义字段就能跑

也能做,但会带上商品、购物车、订单的概念

价格、库存、购物车、订单

要自己补

已有对应字段和流程

变体(颜色、尺寸、型号)

自己建关系或子文章

内置变体文章类型

查询入口

WP_Query

wc_get_products / WC_Product_Query

REST

show_in_rest 后走 /wp/v2/...

WooCommerce REST API 和 Store API

以后转交易

要把字段、分类、URL 映射过去

一开始就在商品模型里

数据落在哪几张表

自定义文章类型的本体在 wp_posts:标题、正文、摘要、状态、别名、父级、排序都在这里。自定义字段在 wp_postmeta,分类和标签在 wp_terms、wp_term_taxonomy、wp_term_relationships。register_post_meta() 不会给数据库加列,它做的是声明字段类型、REST 暴露和清理回调;值仍然按 key-value 存在 wp_postmeta。

WooCommerce 的商品也是 wp_posts 里的 product,但多了商品类型、属性、变体、价格、库存这些语义。简单商品和变体是不同文章类型,产品分类走 product_cat,标签走 product_tag,属性常见为 pa_* 分类法。价格、库存状态等还会进入 WooCommerce 自己维护的 lookup 表,供商品列表和筛选用。订单、优惠券、税率、配送这些数据由 WooCommerce 管理,不需要你在 CPT 上重造。

下面这段注册一个目录文章类型、两个分类法和两个字段。可以放进自建插件,也可以临时放进主题的 functions.php:

代码语言:php
复制
add_action('init', function () {
    register_post_type('catalog_item', [
        'label' => '产品目录',
        'public' => true,
        'show_in_rest' => true,
        'has_archive' => true,
        'rewrite' => ['slug' => 'catalog', 'with_front' => false],
        'supports' => ['title', 'editor', 'thumbnail', 'excerpt', 'custom-fields'],
        'menu_icon' => 'dashicons-products',
    ]);

    register_taxonomy('catalog_category', ['catalog_item'], [
        'label' => '目录分类',
        'public' => true,
        'hierarchical' => true,
        'show_in_rest' => true,
        'rewrite' => ['slug' => 'catalog-category'],
    ]);

    register_taxonomy('catalog_brand', ['catalog_item'], [
        'label' => '品牌',
        'public' => true,
        'hierarchical' => false,
        'show_in_rest' => true,
        'rewrite' => ['slug' => 'catalog-brand'],
    ]);

    register_post_meta('catalog_item', 'catalog_model', [
        'type' => 'string',
        'single' => true,
        'show_in_rest' => true,
        'sanitize_callback' => 'sanitize_text_field',
        'auth_callback' => function () {
            return current_user_can('edit_posts');
        },
    ]);

    register_post_meta('catalog_item', 'catalog_power_w', [
        'type' => 'number',
        'single' => true,
        'show_in_rest' => true,
        'sanitize_callback' => function ($value) {
            return is_numeric($value) ? (float) $value : 0;
        },
        'auth_callback' => function () {
            return current_user_can('edit_posts');
        },
    ]);
});

字段名不要用 _price、_sku、_stock_status 这类 WooCommerce 已经占用的 key。以后真要迁到商品模型,少一层命名冲突。

目录页对搜索引擎输出结构化数据这件事,可以自己按字段拼 JSON-LD,也可以交给插件。AumViso 是 AumCreate 做的免费插件(AumViso),做的是 schema 结构化数据、sitemap、meta、内链和 llms.txt 这几块。上面把型号、品牌、功率定义成独立字段,这一步的价值就在这儿:字段拆得清楚,schema 里的属性才有东西可填。

查询方式有什么不同

CPT 的查询就是 WP_Query。分类用 tax_query,数值区间用 meta_query,排序用 orderby。下面按目录分类取一页,按功率从低到高排:

代码语言:php
复制
$paged = max(1, get_query_var('paged') ?: get_query_var('page'));

$args = [
    'post_type' => 'catalog_item',
    'post_status' => 'publish',
    'posts_per_page' => 12,
    'paged' => $paged,
    'tax_query' => [
        'relation' => 'AND',
        [
            'taxonomy' => 'catalog_category',
            'field' => 'slug',
            'terms' => ['power-supply'],
        ],
    ],
    'meta_query' => [
        'relation' => 'AND',
        [
            'key' => 'catalog_power_w',
            'value' => [100, 500],
            'compare' => 'BETWEEN',
            'type' => 'NUMERIC',
        ],
    ],
    'orderby' => [
        'meta_value_num' => 'ASC',
        'title' => 'ASC',
    ],
    'meta_key' => 'catalog_power_w',
];

$q = new WP_Query($args);

if ($q->have_posts()) {
    while ($q->have_posts()) {
        $q->the_post();
        $model = get_post_meta(get_the_ID(), 'catalog_model', true);
        $power = get_post_meta(get_the_ID(), 'catalog_power_w', true);

        echo '<article>';
        the_title('<h2>', '</h2>');
        echo '<p>' . esc_html($model) . ' / ' . esc_html($power) . 'W</p>';
        the_excerpt();
        echo '</article>';
    }
    wp_reset_postdata();
}

meta_query 会 JOIN wp_postmeta。筛选条件一多,SQL 里会出现多次 JOIN,字段值又是长文本,数值比较要显式写 type 为 NUMERIC。如果目录有十几个筛选维度,先跑 EXPLAIN 看执行计划,再决定要不要把规格拆到单独的表或搜索索引里。

WooCommerce 这边用 wc_get_products(),它返回 WC_Product 对象,价格、库存、商品类型、可见性这些条件由商品查询层处理:

代码语言:php
复制
$page = max(1, get_query_var('paged') ?: get_query_var('page'));

$products = wc_get_products([
    'status' => 'publish',
    'limit' => 12,
    'page' => $page,
    'category' => ['power-supply'],
    'stock_status' => 'instock',
    'orderby' => 'price',
    'order' => 'ASC',
    'return' => 'objects',
]);

foreach ($products as $product) {
    if (! $product instanceof WC_Product) {
        continue;
    }

    echo '<article>';
    echo '<h2><a href=\'' . esc_url($product->get_permalink()) . '\'>' . esc_html($product->get_name()) . '</a></h2>';
    echo wp_kses_post($product->get_price_html());
    echo '<p>' . esc_html($product->get_sku()) . '</p>';
    echo '</article>';
}

category 传的是产品分类别名,不是分类显示名。直接写 WP_Query 查 product 也能取到文章,但商品可见性、库存状态、价格排序这些条件要自己补,容易和 WooCommerce 的查询层不一致。

如果后面要程序化创建商品,用 CRUD 比直接插 wp_posts 稳:

代码语言:php
复制
$product = new WC_Product_Simple();
$product->set_name('示例型号');
$product->set_status('publish');
$product->set_regular_price('199');
$product->set_sku('DEMO-001');
$product->save();

以后扩展要提前留什么

只做目录时,CPT 的字段和模板都可控,前台列表、详情页、参数筛选都能按自己的结构写。风险在以后接交易:商品 ID、分类、字段、图片、URL 都要映射到 WooCommerce 的商品模型,旧链接还要做 301。迁移时至少固定 SKU,把分类和品牌映射到 product_cat 或自定义分类法,把价格、库存、单位这些字段写清楚对应关系,再跑一遍列表页和筛选页的回归。

一开始就用 WooCommerce 商品,后面加价格、库存、变体、优惠券、订单、支付、发货会顺一些;代价是后台多出购物车、结账、订单这些概念,数据表也更多。只做展示时,可以把加购和结账入口收起来,但数据模型仍然是商品模型。

产品参数很多时,两种模型都会遇到同一个问题:把所有规格塞进一个序列化字段,查询很难写。把常用筛选字段拆成独立 meta 或独立分类法,把长文本参数留在详情页,后面加筛选条件时不用重做数据层。

怎么选

只做目录、询价、资料下载,短期不接在线支付,用自定义文章类型就够,字段和模板都由自己控制。

需要价格、库存、变体、优惠券、订单、支付、发货,用 WooCommerce 商品,不要在 CPT 上模拟交易流程。

现在只展示、但半年后大概率要卖,可以直接上 WooCommerce 商品;如果先用 CPT,至少把 SKU、分类、字段映射写进设计里,别等迁移时才发现字段对不上。

产品参数多、筛选维度复杂,先把规格拆成可查询的结构,再选 catalog_item 还是 product。目录站的技术债通常落在字段和查询上。

目录本身好搭,难的是目录之外的匹配逻辑:按多个维度联合筛选、访客输入一个型号返回自家等效型号、或者要和 ERP 的型号表对上。这部分自己写要先估工期。这类定制开发 AumCreate 接,$1,500 起,流程是填需求表、报价、付 50% 开工、验收付尾款,价格以官网为准。

定制开发的范围和交付方式写在 AumCreate 服务页。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 数据落在哪几张表
  • 查询方式有什么不同
  • 以后扩展要提前留什么
  • 怎么选
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档