🪐前言
你有没有遇到过这种情况:公司有上百款产品,但 WordPress 默认的"文章"和"页面"根本装不下这些结构化数据——产品型号、规格参数、案例分类、客户名称……全堆在普通编辑器的正文里,找也找不到、搜也搜不准。
问题出在:你把"结构化数据"硬塞进了"非结构化内容容器"里。
这篇文章将带你一步步搭建两种典型的外贸数据模型——B2B 产品库和 B2C 客户案例库,用 自定义文章类型(CPT) 定义数据骨架,用 ACF(Advanced Custom Fields) 填充血肉,最终在前端模板中完整呈现。所有代码可直接复制使用。
一、CPT 是什么,为什么你的外贸站离不开它
WordPress 自带五种内容类型:文章(Post)、页面(Page)、附件(Attachment)、修订版(Revision)、导航菜单(Nav Menu)。它们够你写博客、搭页面——但不够你管理产品、案例、团队成员、FAQ 这些结构化信息。
CPT(Custom Post Type,自定义文章类型)就是让你自己定义新内容类型的能力。比如:
product—— 产品库,每一条有型号、价格、规格参数case—— 客户案例,每一条有客户名、行业、交付周期faq—— 常见问题,每一条有问题、回答、分类标签
每条 CPT 本质上在 WordPress 后台多出一个独立的菜单项,有专属的列表页、编辑页、归档页,跟默认的"文章"互不干扰。
💡 一句话口诀:CPT 就是给数据分类,ACF 是给每类数据加字段。两个加在一起,WordPress 就不再是博客,而是一个完整的 CMS。

二、方式一:纯代码注册 CPT——最可控的方案
如果你习惯直接改代码,把 CPT 注册逻辑写进主题的 functions.php 是最干净的做法。永远建议放在子主题里,或者做成一个小插件——别直接改父主题文件,更新后代码就丢了。
🔧 注册一个 B2B 产品 CPT
把以下代码放到 wp-content/themes/your-child-theme/functions.php 末尾。
// 注册 product 自定义文章类型
function b2b_register_product_cpt() {
$labels = array(
'name' => '产品',
'singular_name' => '产品',
'menu_name' => '产品库',
'add_new' => '添加新产品',
'add_new_item' => '添加新产品',
'edit_item' => '编辑产品',
'all_items' => '所有产品',
'search_items' => '搜索产品',
'not_found' => '未找到产品',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'products' ),
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
'menu_icon' => 'dashicons-products',
'show_in_rest' => true, // 启用 Gutenberg 编辑器
'taxonomies' => array( 'category' ), // 复用分类系统
);
register_post_type( 'product', $args );
}
add_action( 'init', 'b2b_register_product_cpt' );
⚡ 注册完第一件事:刷新固定链接
代码保存后,去 后台 > 设置 > 固定链接,什么都不要改,直接点"保存更改"。WordPress 自带的 rewrite 规则才会刷新——否则访问 /products/ 直接 404。这是 CPT 新手踩坑率最高的地方。
🏷️ 给产品 CPT 注册独立分类法(推荐)
产品分类用默认的 category 会跟博客文章混在一起。更好的做法是注册专用分类法:
function b2b_register_product_taxonomy() {
$labels = array(
'name' => '产品分类',
'singular_name' => '产品分类',
'search_items' => '搜索产品分类',
'all_items' => '所有产品分类',
'edit_item' => '编辑产品分类',
'update_item' => '更新产品分类',
'add_new_item' => '添加新产品分类',
'menu_name' => '产品分类',
);
$args = array(
'labels' => $labels,
'hierarchical' => true, // 类似分类目录,支持层级
'public' => true,
'rewrite' => array( 'slug' => 'product-category' ),
'show_in_rest' => true,
);
register_taxonomy( 'product_category', 'product', $args );
}
add_action( 'init', 'b2b_register_product_taxonomy' );
📐 B2C 客户案例 CPT 代码(同样逻辑)
案例 CPT 跟产品 CPT 结构几乎一样,调整 slug 和标签即可:
function b2c_register_case_cpt() {
$labels = array(
'name' => '客户案例',
'singular_name' => '客户案例',
'add_new' => '添加新案例',
);
$args = array(
'labels' => $labels,
'public' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'cases' ),
'supports' => array( 'title', 'editor', 'thumbnail' ),
'menu_icon' => 'dashicons-groups',
'show_in_rest' => true,
);
register_post_type( 'case', $args );
}
add_action( 'init', 'b2c_register_case_cpt' );

三、方式二:插件注册 CPT——零代码备选方案
如果你不想跟 functions.php 打交道,或者项目需要交接给不写代码的同事维护,插件方案是可靠的替代选择。
📦 推荐插件:Custom Post Type UI
Custom Post Type UI 是这一领域的标杆免费插件,已安装超过 100 万次、评分 4.8+。
操作路径:装好插件后,后台 > CPT UI > 添加/编辑文章类型,填以下参数:
| 字段 | B2B 产品 CPT | B2C 案例 CPT |
|---|---|---|
| 文章类型别名 | product |
case |
| 复数标签 | 产品 | 客户案例 |
| 单数标签 | 产品 | 客户案例 |
| 支持的功能 | 标题/编辑器/特色图片/摘要 | 标题/编辑器/特色图片 |
| 归档 | true | true |
| 自定义 Rewrite | products |
cases |
| 菜单图标 | dashicons-products | dashicons-groups |
填完点"添加文章类型",插件会自动生成注册代码。同一个插件页还能注册专属分类法,操作逻辑完全一致。
⚠️ CPT UI 注册的 CPT 会在你停用插件后消失。如果你确定长期用同一个 CPT 结构,我建议用插件生成的"迁移代码"标签页复制出注册代码,手动迁到子主题里——兼得可视化配置的安全感和代码方案的独立性。
四、ACF 自定义字段组:给 CPT 装上数据引擎
CPT 自身只有一个标题和一个编辑器。产品型号、尺寸、价格、PDF 下载——这些信息需要 ACF 来提供输入界面。
🧩 安装 ACF
# 免费版已足够
wp plugin install advanced-custom-fields --activate
或直接在后台 插件 > 安装插件 搜索 "Advanced Custom Fields" 安装。
📋 B2B 产品字段组设计
去 后台 > ACF > 字段分组 > 添加新分组,新建一个叫"产品详情"的字段组。
| 字段标签 | 字段类型 | 字段名称 | 必填 | 说明 |
|---|---|---|---|---|
| 产品型号 | 文本 | product_model |
是 | SKU / 型号编号 |
| 产品规格 | 所见即所得编辑器 | product_specs |
否 | 多行规格参数 |
| 参考价格 | 数字 | product_price |
否 | 美元,前端按需显示 |
| 产品图册 | 文件 | product_catalog |
否 | PDF 上传,限制 .pdf |
| 产品状态 | 选择 | product_status |
否 | 在售 / 停产 / 预发布 |
| 关联案例 | 文章对象 | related_cases |
否 | 关联 case 类型文章 |
然后拉到底部位置规则设置:
- 文章类型 等于
product
这样这个字段组只出现在产品编辑页。保存后,打开任意一个产品编辑页,编辑器下方就会出现这些字段。
🖼️ B2C 案例字段组设计
同理,创建"案例详情"字段组:
| 字段标签 | 字段类型 | 字段名称 | 必填 | 说明 |
|---|---|---|---|---|
| 客户名称 | 文本 | client_name |
是 | 企业名称 |
| 客户Logo | 图片 | client_logo |
否 | 返回图片 URL |
| 所属行业 | 选择 | industry |
否 | 预设:制造/医疗/IT/零售/物流 |
| 交付周期 | 文本 | delivery_time |
否 | 如 "45 天" |
| 效果数据 | 重复器 | results |
否 | 名称+数值带单位 |
| 客户评价 | 文本域 | testimonial |
否 | 简短引用语 |
位置规则:文章类型 等于 case。

🔁 ACF 重复器字段使用说明
重复器(Repeater)字段需要 ACF Pro,$49/年一个站点授权。如果你暂时不想付费 —— 用免费的 Meta Box 替代(见下一节)。
重复器的典型用法:案例的"效果数据"可以有多行,每行两个字段:
metric_name(文本):如 "询盘转化率"metric_value(文本):如 "提升 230%"
前端输出时用 get_field( 'results' ) 拿到数组,foreach 循环渲染即可。
五、Meta Box 方案对比:免费的 ACF Pro 替代
如果 ACF Pro 的重复器/灵活内容/画廊字段你都需要,但 $49/年觉得不想花,Meta Box 的免费版 + 扩展是一个值得考虑的方案。
- 基础字段(文本/图片/选择):ACF Free 和 Meta Box Free 均支持
- 重复器 / 灵活内容:ACF Free 不支持,ACF Pro 支持,Meta Box 需单独装扩展(免费)
- 条件逻辑:ACF Pro 支持,Meta Box 免费扩展支持
- 与 Elementor 集成:两者均原生兼容
- 价格:ACF Free 免费,ACF Pro $49/年,Meta Box Free 免费
💡 我的建议:站点预算允许直接上 ACF Pro,省心。预算紧张用 Meta Box Free + 扩展,不花钱也能覆盖所有需求。两者在功能上没有不可逾越的差距。
Meta Box 安装方式:
# 基础框架
wp plugin install meta-box --activate
# 重复器扩展(也是免费插件)
wp plugin install meta-box-group --activate
字段创建的 UI 风格略有不同,但逻辑流程跟 ACF 高度一致——建字段组、配字段、绑 CPT。
六、前端模板:让 CPT 数据真正"显示出来"
后台数据录得再多,前端看不到等于白做。WordPress 的模板层级会自动查找 CPT 对应的模板文件。
📂 模板文件命名规则
single-product.php → 产品详情页
archive-product.php → 产品列表/归档页
single-case.php → 案例详情页
archive-case.php → 案例列表/归档页
把这些文件放在子主题根目录下即可自动生效。
🖥️ 产品详情页模板示例
<?php
// single-product.php — 放在子主题根目录
get_header();
?>
<div class="product-detail">
<h1><?php the_title(); ?></h1>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php if ( has_post_thumbnail() ) : ?>
<div class="product-image">
<?php the_post_thumbnail( 'large' ); ?>
</div>
<?php endif; ?>
<div class="product-content">
<?php the_content(); ?>
</div>
<table class="product-meta">
<tr>
<th>产品型号:</th>
<td><?php echo esc_html( get_field( 'product_model' ) ); ?></td>
</tr>
<tr>
<th>参考价格:</th>
<td>
<?php
$price = get_field( 'product_price' );
echo $price ? 'USD ' . esc_html( number_format( $price, 2 ) ) : '请联系获取报价';
?>
</td>
</tr>
<tr>
<th>产品状态:</th>
<td><?php echo esc_html( get_field( 'product_status' ) ?: '在售' ); ?></td>
</tr>
</table>
<?php
// 输出规格参数(WYSIWYG 字段)
$specs = get_field( 'product_specs' );
if ( $specs ) :
?>
<div class="product-specs">
<h3>产品规格</h3>
<?php echo wp_kses_post( $specs ); ?>
</div>
<?php endif; ?>
<?php
// 输出 PDF 产品图册下载链接
$catalog = get_field( 'product_catalog' );
if ( $catalog ) :
?>
<p>
<a href="<?php echo esc_url( $catalog['url'] ); ?>" class="btn-download" target="_blank">
下载产品图册 (PDF)
</a>
</p>
<?php endif; ?>
<?php endwhile; endif; ?>
</div>
<?php get_footer(); ?>
📋 产品归档页(列表页)关键片段
<?php
// archive-product.php 核心循环
while ( have_posts() ) : the_post();
?>
<article class="product-card">
<?php the_post_thumbnail( 'medium' ); ?>
<h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
<p class="model">型号:<?php echo esc_html( get_field( 'product_model' ) ); ?></p>
<p class="excerpt"><?php echo get_the_excerpt(); ?></p>
</article>
<?php
endwhile;
⚠️ 模板修改后也要去"设置 > 固定链接"点一次保存。CPT 模板不生效的 90% 原因都是 rewrite 规则没刷新。
🎨 在 Elementor 中调用 ACF 字段
如果你用 Elementor 建站,不需要手写 PHP 模板。ACF 字段在 Elementor 中可以直接作为动态数据标签调用:
- 拖入一个"标题"组件
- 点击字段左侧的动态标签图标
- 选择"ACF 字段" → 选对应字段名(如
product_model) - 文本/图片/WYSIWYG/URL 四种字段类型全支持
Gutenberg 同理——安装免费的 "ACF Blocks" 或依赖 ACF 自身的 acf_register_block_type() 函数,把字段组注册为自定义区块,编辑页面时直接插入。

七、实战架构:两张典型的 CPT 数据模型
🏭 B2B 产品库架构
product (CPT)
├── title —— 产品名称(CPT自带)
├── content —— 产品描述(CPT自带)
├── product_category —— 产品分类(自定义分类法)
├── product_model —— 产品型号(ACF 文本)
├── product_specs —— 产品规格(ACF WYSIWYG)
├── product_price —— 参考价格(ACF 数字)
├── product_catalog —— 产品图册 PDF(ACF 文件)
├── product_status —— 产品状态(ACF 选择)
└── related_cases —— 关联案例(ACF 文章对象 → case)
这个模型覆盖了:产品展示、参数规格、文件下载、案例关联 —— 一个外贸产品单页需要的全部结构化数据。
🛍️ B2C 案例库架构
case (CPT)
├── title —— 案例标题(CPT自带)
├── content —— 案例正文(CPT自带)
├── client_name —— 客户名称(ACF 文本)
├── client_logo —— 客户Logo(ACF 图片)
├── industry —— 所属行业(ACF 选择)
├── delivery_time —— 交付周期(ACF 文本)
├── results —— 效果数据(ACF 重复器)
│ ├── metric_name —— 指标名称(文本)
│ └── metric_value —— 指标数值(文本)
└── testimonial —— 客户评价(ACF 文本域)
案例库里最关键的是 results 重复器——每个交付项目都有不同的衡量维度(转化率/交付周期/成本节省),没法用固定字段穷举。重复器完美解决了这个"字段数量不确定"的问题。

八、常见故障排查
❌ 问题一:CPT 归档页 404
刷新固定链接(后台 > 设置 > 固定链接 > 保存更改)。如果还不行,检查 has_archive 参数是否为 true,以及 rewrite['slug'] 不与现有页面/文章 slug 冲突。
❌ 问题二:ACF 字段在前端不显示
三条排查路径:
- 确认 ACF 位置规则正确绑定了 CPT(文章类型 是否等于目标类型)
- 确认模板中
get_field( 'field_name' )拼写与 ACF 字段名称完全一致 - 在模板中临时加一行
var_dump( get_field( 'field_name' ) );看返回值是否为 null
❌ 问题三:字段分组在 CPT 编辑页不出现
检查 ACF 的"设置"标签 —— 确认"位置规则"中未选中"仅在符合规则时显示此字段组"。先排查位置规则本身是否匹配,最后再排查是否有其他插件通过 acf/get_field_group 钩子隐藏了字段组。
总结
CPT + ACF 是 WordPress 从 CMS 走向"应用开发框架"的核心能力。掌握这两样,你再也不需要把产品参数塞在编辑器正文里、不需要为每个业务建不同的子站点。
- CPT 定义数据容器的形状:product、case、faq,按业务来
- ACF 填充字段:文本、图片、文件、选择器、重复器,按需来
- 前端呈现分两条路:手写模板文件(single-{cpt}.php)或 Elementor/Gutenberg 动态标签调用
- B2B 产品库和 B2C 案例库的 CPT 架构可以直接从这篇文章复制、改成自己的业务名称、投入使用
如有问题,官方求助路径:
WordPress 独立站学院 · 技术教程 #32
分类:内容与数据 · CPT / ACF / Meta Box



老站已经有几百篇产品文章,迁到CPT会不会很麻烦😭
这套拿来做FAQ库应该也顺手吧,有人试过没?