子比主题开发文档
使用指南Codestar Framework主题扩展在线部署AI 功能推荐插件赞助打赏

商城参数与继承配置

梳理子比主题商城商品参数模板、product_config.params、商品分类统一配置、zib_shop_get_product_in_turn_config 继承读取和商品详情页展示边界。

子比主题商城里常说的“商品参数”有两层含义:一层是商品详情页展示的参数表,例如规格、材质、尺寸;另一层是商品、分类、主题设置之间的统一配置继承,例如服务保障、运费、售后、推广返佣、详情页 Tab、详情页布局等。

扩展时要先分清这两件事。product_config.params 主要用于商品详情页展示,默认模板来自主题设置;继承配置则由 zib_shop_get_product_in_turn_config() 或对应业务函数按“商品 -> 商品分类 -> 主题设置”读取。

相关源码:

文件作用
inc/functions/shop/admin/options/admin-option.php主题设置里的商城商品参数模板和全局配置
inc/functions/shop/admin/options/meta-option.php商品编辑页 product_config.params 字段
inc/functions/shop/admin/options/term-option.php商品分类统一参数配置
inc/functions/shop/admin/options/option-module.php服务、售后、运费、返佣、Tab、布局等复用字段模块
inc/functions/shop/inc/product.phpzib_shop_get_product_in_turn_config() 和多种商品配置读取函数
inc/functions/shop/inc/cat.php商品分类配置读取、父级分类递归查找
inc/functions/shop/inc/vue.php商品详情页 Vue 数据里的 paramsservice 等字段
inc/functions/shop/inc/single.php商品详情页参数、服务、Tab、布局和底部内容渲染

两类参数

类型存储位置读取方式用途
商品展示参数product_config.paramszib_shop_get_product_config($id, 'params')商品详情页参数条和参数弹窗
默认参数模板_pz('shop_product_params_default')作为商品编辑字段默认值新建商品时预填参数项
分类统一配置shop_cat_config term metazib_shop_get_product_cat_config()分类下商品统一继承配置
全局商城配置主题设置 _pz('shop_*')_pz() 或继承函数全站商品默认配置
继承型商品配置product_config / shop_cat_config / _pz('shop_*')zib_shop_get_product_in_turn_config()服务、返佣、布局、背景、部分开关等

params 不等于所有继承配置。商品展示参数会进入 Vue 数据和详情页展示;继承配置通常会继续参与发货、售后、运费、返佣或页面布局。

商品参数模板

后台主题设置里有 shop_product_params_default

_pz('shop_product_params_default', array());

它在商品编辑页作为 params 字段的默认值:

'id'      => 'params',
'default' => _pz('shop_product_params_default', array()),

也就是说,这个模板主要解决“每次新建商品时预填一组参数项”。商品保存后,实际展示仍以当前商品的 product_config.params 为准。后续修改全局模板,不会自动覆盖已经保存过的商品参数。

适合放进模板的内容:

参数名示例
规格标准版、专业版、实体套装
材质电子资料、纸质资料、金属、棉
尺寸10cm、A4、均码
有效期永久、30 天、1 年
交付方式自动发货、快递发货、人工交付

不适合放进 params 的内容:

内容原因
真实库存库存有独立字段和自动发货覆盖逻辑
售后规则售后有商品、分类、全局继承和虚拟商品修正
运费金额运费由运费模块和订单确认链路计算
优惠金额优惠由优惠活动和优惠码链路计算
发货内容自动发货内容属于交付数据,不应公开展示

详情页展示参数

商品详情页 Vue 数据会过滤 params,只有同时存在 namevalue 的项才会输出:

$params = array();
if ($_configs['params'] && is_array($_configs['params'])) {
    $params = array_filter($_configs['params'], function ($value) {
        return $value['name'] && $value['value'];
    });
}

最终进入:

'params' => $params,

详情页会在 product-params-box 中展示参数条,点击后由前端 paramsModal(params) 打开参数弹窗。这里是展示层能力,不负责下单校验。

读取商品展示参数可以这样写:

function zib_child_get_product_params($product_id)
{
    $product = get_post($product_id);
    if (!$product || $product->post_type !== 'shop_product') {
        return array();
    }

    $params = zib_shop_get_product_config($product_id, 'params', array());
    if (!$params || !is_array($params)) {
        return array();
    }

    return array_filter($params, function ($item) {
        return !empty($item['name']) && !empty($item['value']);
    });
}

如果要在商品卡片、海报或自定义模块里展示参数,建议先限制数量和长度,不要把完整参数表塞进列表页。

function zib_child_get_product_param_text($product_id, $limit = 3)
{
    $params = zib_child_get_product_params($product_id);
    if (!$params) {
        return '';
    }

    $texts = array();
    foreach ($params as $param) {
        $texts[] = sanitize_text_field($param['name']) . ':' . sanitize_text_field($param['value']);
        if (count($texts) >= $limit) {
            break;
        }
    }

    return implode(' / ', $texts);
}

分类统一配置

商品分类配置存储在 shop_cat_config term meta。分类后台会创建“商品统一参数配置”,包含这些模块:

配置字段模块
限购zib_shop_csf_module::limit_buy('cat')
运费zib_shop_csf_module::shipping_fee('cat')
免登录购买zib_shop_csf_module::guest_buy('cat')
邮箱填写zib_shop_csf_module::email_fill('cat')
售后政策zib_shop_csf_module::after_sale('cat')
推广返佣zib_shop_csf_module::rebate('cat')
服务保障zib_shop_csf_module::service('cat')
商品详情 Tabzib_shop_csf_module::single_tab('cat')
详情页底部内容zib_shop_csf_module::content_after('cat')
内容布局zib_shop_csf_module::content_layout('cat')
详情背景盒子zib_shop_csf_module::content_show_bg('cat')

分类读取入口是:

$config = zib_shop_get_product_cat_config($product_id, 'service');

它会先检查商品所属的直接分类,再检查这些分类的父级分类。传入第三个参数时,会要求配置数组里对应子字段存在:

$config = zib_shop_get_product_cat_config($product_id, 'single_tabs', 'type');

多分类商品需要注意:源码按 get_the_terms($post, 'shop_cat') 返回顺序依次查找,找到第一份有效配置就返回。扩展依赖分类配置时,不要假设“最深分类”或“最新分类”一定优先。

三级继承函数

通用继承函数是:

function zib_shop_get_product_in_turn_config($product_id, $key, $default = '')
{
    $config = zib_shop_get_product_config($product_id, $key, '');
    if (!$config) {
        $config = zib_shop_get_product_cat_config($product_id, $key);
    }
    if (!$config) {
        $config = _pz('shop_' . $key, $default);
    }

    return $config;
}

读取顺序是:

  1. 当前商品 product_config[$key]
  2. 商品分类 shop_cat_config[$key],必要时递归父级分类。
  3. 主题设置 _pz('shop_' . $key)
  4. 调用方传入的默认值。

这个函数适合值为空就继承的配置。对于带 type 的复杂配置,有些业务函数会自己处理 defaultcustomoffdisable 等状态,不应盲目替代。

已封装的业务读取

优先使用主题已经封装好的业务函数:

需求推荐函数说明
服务保障zib_shop_get_product_service($product_id)会过滤无名称的服务项
商品返佣zib_shop_get_product_rebate_config($product_id)推广返佣关闭或配置关闭时返回空
免登录购买zib_shop_product_is_allow_guest_buy($product_id)只允许自动发货、非积分商品继续判断继承开关
邮箱填写zib_shop_get_product_email_fill_config($product_id)非自动发货商品直接关闭
运费规则zib_shop_get_product_shipping_fee_config($product_id)会处理积分商品、包邮、固定运费、满额包邮
售后政策zib_shop_get_product_after_sale_opt($product_id)商品、分类、全局继承后还会按虚拟商品修正
内容布局zib_shop_get_product_content_layout($product_id)用于商品详情页宽度与侧栏布局
商品详情 Tabzib_shop_get_single_tabs($post)会处理禁用、自定义、分类继承和全局默认

示例:读取服务保障时不要自己拼三层配置:

function zib_child_get_product_service_names($product_id)
{
    $service = zib_shop_get_product_service($product_id);
    if (!$service) {
        return array();
    }

    $names = array();
    foreach ($service as $item) {
        if (!empty($item['name'])) {
            $names[] = sanitize_text_field($item['name']);
        }
    }

    return $names;
}

带状态的继承配置

很多分类和商品配置不是简单数组,而是带 type 字段:

状态常见含义
空值使用上一级配置
custom使用当前层级自定义配置
off关闭当前能力
on开启当前能力
disable禁用某个展示模块

例如商品详情 Tab 的逻辑是:

  1. 商品 single_tabs.typedisable:直接不显示额外 Tab。
  2. 商品 single_tabs.typecustom:使用商品自己的 tabs
  3. 否则读取分类 single_tabs.type
  4. 分类为 disable:不显示。
  5. 分类为 custom:使用分类 tabs
  6. 否则使用全局 _pz('shop_single_tabs')

这类配置不能只用 zib_shop_get_product_in_turn_config() 简单读取,因为空值、禁用、自定义都有业务含义。

扩展一个继承配置

如果你新增一个展示配置,并希望它支持“商品 -> 分类 -> 全局”的继承,可以沿用主题命名方式:

层级字段
全局主题设置shop_sale_notice
分类配置sale_notice
商品配置sale_notice

读取函数:

function zib_child_get_product_sale_notice($product_id)
{
    $product = get_post($product_id);
    if (!$product || $product->post_type !== 'shop_product') {
        return '';
    }

    $notice = zib_shop_get_product_in_turn_config($product_id, 'sale_notice', '');
    return $notice ? wp_kses_post($notice) : '';
}

挂到商品详情内容后:

add_action('shop_product_page_content_after', 'zib_child_shop_sale_notice');
function zib_child_shop_sale_notice()
{
    if (!is_singular('shop_product')) {
        return;
    }

    $notice = zib_child_get_product_sale_notice(get_the_ID());
    if (!$notice) {
        return;
    }

    echo '<div class="zib-widget product-sale-notice">';
    echo $notice;
    echo '</div>';
}

如果这个配置会影响交易结果,例如是否允许购买、是否收运费、是否计算返佣,不要只写一个通用读取函数,还要接入订单确认和提交订单的服务端校验。

保存商品参数

扩展后台或前台设置时,保存 params 仍然写回 product_config

function zib_child_save_product_params($product_id, $params)
{
    $product = get_post($product_id);
    if (!$product || $product->post_type !== 'shop_product') {
        return false;
    }

    if (!current_user_can('edit_post', $product_id)) {
        return false;
    }

    $new_params = array();
    if (is_array($params)) {
        foreach ($params as $param) {
            $name  = sanitize_text_field($param['name'] ?? '');
            $value = sanitize_text_field($param['value'] ?? '');

            if ($name && $value) {
                $new_params[] = array(
                    'name'  => $name,
                    'value' => $value,
                );
            }
        }
    }

    zib_shop_save_product_config($product_id, 'params', $new_params);

    return true;
}

params 是公开展示信息,保存前要做文本清洗。不要允许普通用户把 HTML、脚本、联系方式、售后承诺或发货密钥直接写进商品参数。

前台设置边界

商品详情页前台设置里已有两个字段会写回 product_config

$update_post_meta = array('content_layout', 'content_show_bg');

它们通过 zib_frontend_set_save 保存,用于商品详情页布局和背景盒子。这里说明主题已经允许少量页面展示配置前台保存,但这不等于可以把所有商品发布字段都开放给前台。

如果要新增前台可编辑的商品参数,至少要补:

检查说明
权限当前用户必须能编辑该商品
nonce不能只依赖前端按钮隐藏
字段白名单只允许保存预期字段
类型清洗文本、数字、数组分别处理
审核策略公开展示字段建议保留审核或限权
缓存刷新修改展示字段后清理相关缓存

常见误区

  • 不要把 shop_product_params_default 当成所有商品的实时继承来源。
  • 不要把 params 当成库存、运费、优惠、售后或发货规则。
  • 不要在多分类商品里假设某一个分类必然优先,源码会按 term 返回顺序查找。
  • 不要用 zib_shop_get_product_in_turn_config() 替代所有业务函数,带状态的配置要看具体业务逻辑。
  • 不要把分类统一配置写到商品 meta 里复制一份,否则后续分类调整无法生效。
  • 不要把详情页展示参数输出到订单、支付或发货校验里当可信依据。
  • 不要在前台开放商品参数保存时跳过权限、nonce、白名单和清洗。

On this page