WEM(Web Enterprise Management)Content Model 是一款面向新建外贸企业官网与 B2B 产品展示站的轻量级 WordPress 原生内容模型插件。
当前版本: v1.1.0
WordPress: 7.0+
PHP: 8.3+
许可证: MIT
WEM Content Model 用于统一外贸企业站中长期重复出现的内容模型:Product、Download、FAQ,以及按需启用的 Solution。
它只负责稳定的数据层,不承担页面设计、SEO、询盘、电商或大型字段管理功能。
WEM Content Model
→ CPT / Taxonomy / 少量结构化 Meta
Elementor
→ Product / Solution 的复杂营销正文
Theme
→ Archive / Single / 查询 / 响应式 / 前端展示
核心原则:
- 数据结构稳定,页面表现自由
- 优先使用 WordPress 原生能力
- 只结构化真正需要程序调用的数据
- 复杂图文内容交给 Elementor
- 不为单个项目需求不断扩充 Core
- 不重复开发 ACF、Meta Box、WooCommerce 已有能力
适合:
- 外贸企业官网
- B2B 产品展示站
- 建材、家居、五金、机械、工业品等企业产品站
- 需要 Product + Download + FAQ 的企业站
- 少量需要 Solution 内容体系的项目
- 希望长期使用自有 CPT / Taxonomy / Meta,而不过度依赖通用字段插件的项目
不以这些场景为目标:
- 完整 B2C 商城
- 复杂库存、价格、Variation、订单系统
- 通用 ACF / Meta Box 替代品
- Headless CMS 平台
- CRM / SMTP / 询盘管理系统
- 大型内容关系引擎
| 模块 | 默认状态 | 主要用途 | Elementor |
|---|---|---|---|
| Product | ON | 产品、分类及核心产品数据 | ✅ |
| Download | ON | Catalog、Color Card、Technical Data、Guide 等资料 | ❌ |
| FAQ | ON | 标准一问一答内容 | ❌ |
| Solution | OFF | 产品组合、空间设计、装饰方案等内容 | ✅ |
当前暂不包含 Case、Application、Team、Certificate、Video 等独立模块。
只有当某类需求在多个新站中反复出现,并且进入 WEM 能明显降低长期维护成本时,才考虑继续扩展。
将插件目录上传到:
/wp-content/plugins/wem-content-model/
然后在 WordPress 后台启用:
Plugins → Installed Plugins → WEM Content Model
默认会启用:
Products
Downloads
FAQs
插件激活时会注册相关 CPT / Taxonomy 并刷新 Rewrite Rules。
模块配置文件:
config/modules.php
默认:
return array(
'product' => true,
'download' => true,
'faq' => true,
'solution' => false,
);需要 Solution 时改为:
'solution' => true,也可以通过 Filter 在项目代码中开启,而不修改插件源码:
add_filter( 'wem_enabled_modules', function ( array $modules ): array {
$modules['solution'] = true;
return $modules;
} );修改模块状态后,建议进入:
Settings → Permalinks
重新保存一次固定链接。
Product 是 WEM 的核心内容模型。
直接使用 WordPress 原生能力:
- Title
- Editor
- Excerpt
- Featured Image
- Page Attributes /
menu_order - Product Categories
复杂产品正文推荐使用 Elementor 编辑。
Taxonomy:
wem_product_category
采用层级结构,例如:
WPC Wall Panel
├── Fluted Wall Panel
├── Integrated Panels
├── Wood Veneer Sheet
└── Curved Wall Panels
不默认注册 Product Tags,也不提前增加 Material、Surface、Industry 等行业型 Taxonomy。
| 后台名称 | Meta Key | 类型 |
|---|---|---|
| Product Badge | wem_product_badge |
text |
| Product Model | wem_product_model |
text |
| Product Dimensions | wem_product_dimensions |
text |
| Product Image 01~08 | wem_product_image_01 ~ wem_product_image_08 |
media:image |
| 3D / VR URL | wem_product_vr_url |
text |
| 3D / VR QR Code | wem_product_vr_qr_code |
media:image |
| Product Video | wem_product_video |
media:video |
| Related Download IDs | wem_product_download_ids |
text |
| Product Custom HTML | wem_product_custom_html |
html |
Material、Surface、Length、Weight、Power、Voltage 等参数高度依赖行业,不默认加入 Core。
判断规则:
需要筛选 / 排序 / 查询 / 多页面复用
→ 再考虑结构化
只是参数表 / 产品介绍 / 图文营销内容
→ Elementor 或 Product Custom HTML
这样可以避免插件随着项目增加逐渐变成难以维护的行业数据系统。
wem_get_product_badge( $post_id );
wem_get_product_model( $post_id );
wem_get_product_dimensions( $post_id );
wem_get_product_image_id( $post_id, 1 );
wem_get_product_image_url( $post_id, 1, 'large' );
wem_get_product_vr_url( $post_id );
wem_get_product_vr_qr_code_id( $post_id );
wem_get_product_video_id( $post_id );
wem_get_product_download_ids( $post_id );
wem_get_product_custom_html( $post_id );图片推荐通过 Attachment ID 输出:
$image_id = wem_get_product_image_id( get_the_ID(), 1 );
if ( $image_id ) {
echo wp_get_attachment_image( $image_id, 'large' );
}HTML 字段输出:
echo wp_kses_post(
wem_get_product_custom_html( get_the_ID() )
);推荐页面分层:
产品顶部固定信息
→ WEM + Theme
Overview 以下复杂正文
→ Elementor
适合由 Elementor 管理:
- Overview
- Description
- Product Features
- Color & Surface
- Installation
- Applications
- Inspiration
- Gallery / Video Layout
- CTA
不要因为某项信息出现在页面上,就自动把它开发成新的 Meta Field。
Download 用于独立管理可被多个页面复用的下载资料。
常见内容:
Catalog
Brochure
Color Card
Technical Data
Installation Guide
Certificate
Drawing
Other
- Title
- Editor
- Featured Image(可选)
- Page Attributes /
menu_order - Download Categories
Editor 可以保存说明文字、Shortcode 或 Flipbook 内容。
Download 只增加一个自定义字段:
| 后台名称 | Meta Key | 类型 |
|---|---|---|
| Download File | wem_download_file |
media:file |
统一保存 WordPress Attachment ID,不保存完整媒体 URL。
Helpers:
wem_get_download_file_id( $post_id );
wem_get_download_file_url( $post_id );文件名、MIME Type、扩展名、文件大小等信息应尽可能从 Attachment 自动读取,避免重复维护。
Download Category 推荐描述:
这个资源是什么。
例如:
Catalog
Brochure
Color Card
Technical Data
Installation Guide
Certificate
Drawing
Other
Product 与 Download 的具体关系通过 Related Download IDs 表达,而不是依靠 Download Category 表达。
FAQ 不需要任何自定义 Meta,也不需要 Elementor。
Title
→ Question
Editor
→ Answer
FAQ Category
→ 分类
Page Attributes
→ 排序
Taxonomy:
wem_faq_category
FAQ Categories 采用层级结构,可按项目组织为:
General
Products
Installation
Maintenance
Shipping
Samples
前端 Accordion 完全由 Theme 负责。简单场景可以直接使用:
<details>
<summary>Question</summary>
<div>Answer</div>
</details>因此同一组 FAQ 可以在 FAQ 页面、产品页、分类页或其他位置重复调用,而不会与具体前端样式绑定。
Solution 与 Product 的工作方式相似,但并不是所有外贸网站都需要,因此默认关闭。
适合:
- Interior Decoration Solution
- Product Combination Solution
- Wall Decoration Solution
- Space Design Solution
- 其他多个产品组合形成的方案型内容
- Title
- Editor
- Excerpt
- Featured Image
- Page Attributes /
menu_order - Solution Categories
复杂空间设计、组合产品说明、热点图和营销图文继续使用 Elementor。
| 后台名称 | Meta Key | 类型 |
|---|---|---|
| Solution Badge | wem_solution_badge |
text |
| Featured Product Model | wem_solution_product_model |
text |
| Featured Product Dimensions | wem_solution_product_dimensions |
text |
| Related Product URL | wem_solution_product_url |
text |
| Solution Image 01~05 | wem_solution_image_01 ~ wem_solution_image_05 |
media:image |
| 3D / VR URL | wem_solution_vr_url |
text |
| 3D / VR QR Code | wem_solution_vr_qr_code |
media:image |
| Related Download IDs | wem_solution_download_ids |
text |
Helpers:
wem_get_solution_badge( $post_id );
wem_get_solution_product_model( $post_id );
wem_get_solution_product_dimensions( $post_id );
wem_get_solution_product_url( $post_id );
wem_get_solution_image_id( $post_id, 1 );
wem_get_solution_vr_url( $post_id );
wem_get_solution_vr_qr_code_id( $post_id );
wem_get_solution_download_ids( $post_id );WEM 不做通用字段生成器,只维护三种长期实际需要的字段类型:
text
media
html
| 类型 | 用途 | 存储方式 | Sanitization |
|---|---|---|---|
text |
单行文本、URL、ID 列表等 | string | sanitize_text_field() 或字段指定回调 |
media |
图片、视频、文件 | Attachment ID | absint() + 服务端附件验证 |
html |
参数表、小型 HTML 片段 | string | wp_kses_post() |
当前不提供:
Select
Checkbox
Radio
Repeater
Group
Color Picker
Date
Range
Relationship Builder
如果 WordPress Editor 或 Elementor 已经可以合理解决,就不在 WEM 中重复开发。
html字段使用wp_kses_post()过滤,因此适合参数表和安全 HTML 片段,不适合保存<script>等任意可执行代码。
| 内容 | WEM | Elementor | Theme |
|---|---|---|---|
| CPT / Taxonomy | ✅ | ||
| Model / Dimensions | ✅ | ||
| Media Attachment | ✅ | ||
| Related Download IDs | ✅ | ||
| Overview / Features | ✅ | ||
| Installation / Inspiration | ✅ | ||
| 复杂营销正文 | ✅ | ||
| Archive / Single Template | ✅ | ||
| Query / Load More | ✅ | ||
| Responsive Layout | 部分 | ✅ | |
| SEO | 专业 SEO 插件 | ||
| Inquiry / SMTP / CRM | 独立处理 |
一句话概括:
WEM 管数据,Elementor 管内容,Theme 管表现。
WEM 不内置前端页面模板。
主题可以根据项目需要创建:
archive-wem_product.php
single-wem_product.php
taxonomy-wem_product_category.php
archive-wem_download.php
single-wem_download.php
archive-wem_faq.php
archive-wem_solution.php
single-wem_solution.php
例如读取 Product 数据:
$post_id = get_the_ID();
$model = wem_get_product_model( $post_id );
$dimensions = wem_get_product_dimensions( $post_id );
$image_id = wem_get_product_image_id( $post_id, 1 );读取 Product 关联 Downloads:
$download_ids = wem_get_product_download_ids( get_the_ID() );
foreach ( $download_ids as $download_id ) {
$file_url = wem_get_download_file_url( $download_id );
if ( ! $file_url ) {
continue;
}
printf(
'<a href="%s">%s</a>',
esc_url( $file_url ),
esc_html( get_the_title( $download_id ) )
);
}WEM 对公开 Helper、CPT、Taxonomy 和 Meta Key 统一使用 wem_ 前缀,其中 wem 来自项目名称 Web Enterprise Management。例如:
wem_get_product_model()
wem_product
wem_product_category
wem_product_model
这是有意保留的命名规范:WordPress 插件中的普通 PHP 函数和大量标识符共享全局环境,wem_ 可以降低与主题、WooCommerce 或其他插件发生命名冲突的风险,同时也能让代码来源一目了然,方便后期搜索、调试和 IDE 自动补全。
因此不建议为了缩短函数名而去掉 wem_。可以简单理解为:
wem_ → WEM 提供
get_ → 获取数据
product_ → Product 模块
model → 具体数据
例如 wem_get_product_model() 的含义非常明确:从 WEM 获取 Product Model。
WEM 保持轻量,但保留必要 Filter 供项目级调整。
wem_enabled_modules
wem_product_post_type_args
wem_download_post_type_args
wem_faq_post_type_args
wem_solution_post_type_args
wem_product_category_args
wem_download_category_args
wem_faq_category_args
wem_solution_category_args
wem_media_field_post_types
项目级差异优先通过 Filter 处理,而不是直接修改共享 Core。
CPT 与 Taxonomy 默认:
show_in_rest => trueWEM 自定义 Meta 默认:
show_in_rest => false只有明确需要 Block、Headless 或外部 API 调用时,再有选择地开放对应 Meta。
Meta 保存流程统一包含:
- Nonce 验证
- Capability 验证
- Autosave 防护
- Revision 防护
wp_unslash()- 类型对应 Sanitization
- Media Attachment 服务端验证
- 空字段删除无意义 Meta
Media Library 的前端筛选只用于改善编辑体验,不作为安全边界。
PHP 保存阶段会再次验证:
image
→ 必须是真实图片 Attachment
video
→ MIME Type 必须为 video/*
file
→ 必须是真实 Attachment
wem-content-model/
├── wem-content-model.php
├── config/
│ └── modules.php
│
├── includes/
│ ├── core/
│ │ ├── modules.php
│ │ ├── fields.php
│ │ ├── helpers.php
│ │ └── admin-assets.php
│ │
│ └── modules/
│ ├── product/
│ ├── download/
│ ├── faq/
│ └── solution/
│
├── assets/
│ ├── css/admin.css
│ └── js/media-fields.js
│
├── languages/
├── README.md
├── readme.txt
├── CHANGELOG.md
└── LICENSE
项目没有引入 Composer、Service Container、大型 OOP 框架或复杂构建流程,重点保持源码可读性与长期维护成本可控。
发布前建议至少执行:
find . -name "*.php" -print0 | xargs -0 -n1 php -l
node --check assets/js/media-fields.jsWordPress 中重点检查:
- 插件激活 / 停用无 Fatal Error
- Product / Download / FAQ 正常创建、保存、更新和清空
- Media Select / Replace / Remove 正常
- 非法 Attachment ID 会被过滤
- Product Custom HTML 保存正常
- Related Download IDs 正确规范化
- FAQ
menu_order排序正常 - CPT / Taxonomy REST Endpoint 正常
- Elementor 可以编辑 Product
- 启用 Solution 后 Elementor 可以编辑 Solution
- 修改模块状态后 Rewrite 正常
wp-content/debug.log无新增 Warning / Notice / Deprecated
未来新增 Core 功能前,先判断:
这个需求是否在多个新建外贸网站中反复出现,并且由 WEM 统一解决能够明显降低长期维护成本?
如果答案不是明确的“是”,优先留在项目层。
例如:
单个网站需要 Team
→ 项目层处理
偶尔需要 Case
→ 暂不进入 Core
大量新站都开始需要 Case
→ 再增加 Optional Case Module
尤其避免:
- 为单个项目增加新的通用字段类型
- 双向重复保存 Relationship
- 保存完整媒体 URL
- 把 Elementor 可以完成的内容再次 Meta 化
- 提前加入大量暂时用不到的 CPT / Taxonomy
- 为增加功能而引入不必要的工程复杂度
v1.1.0 重点不是单纯增加功能,而是正式统一 WEM 的长期架构:
Product
Download
FAQ
+
Optional Solution
并统一:
- CPT / Taxonomy 命名
- Meta Box / Meta Key 命名
text/media/htmlField Core- Attachment ID 媒体存储方式
- 数据保存与安全校验
- WEM / Elementor / Theme 职责边界
后续继续坚持:
轻量、稳定、容易理解、容易复用、容易维护,并且只根据真实需求扩展。
MIT License,详见 LICENSE。