本技能是 baserCMS 5 标准插件 bc-custom-content(自定义内容)的开发模式集,用于新建或改造内容类型。环境与命名规则参见 basercms5-development,插件开发通用知识参见 basercms5-plugin-development;本技能只专注 bc-custom-content 本身,不含从特定 4 系插件迁移的专有步骤。
用途与前提:bc-custom-content 是「独立内容树下的内容类型」机制,拥有 custom_tables、custom_contents、custom_fields、custom_links、custom_entries 独立数据模型,实数据存于动态生成的 custom_entry_<table_id>_<name> 表,不能用于给 blog_posts 等既有表追加字段。若需给既有博客文章加字段,应改用 BcModelEventDispatcher 的 Model.<ModelName>.<eventName> 事件自行实现。
主要能力与用法:通过 BcContainerTrait 的 $this->getService(XxxServiceInterface::class) 从 DI 容器取得 Service,不要直接 newEntity+saveOrFail。custom_table 以 type=1 关联内容树,创建时自动生成动态表;custom_fields 可复用且不隶属 custom_table;custom_links 为中间表,持有显示顺序与 display_front;custom_contents 通过 content 键同时保存 Contents,site_id 在 Contents 侧。
关键限制与陷阱:字段名须匹配 ^[a-z0-9_]+$(snake_case);custom_fields.name 全局唯一,需先查后建并校验 type 一致;custom_links.display_front 必须显式 true,否则前台取值为空;ID 方式访问详情页时 custom_entries.name 须显式存空字符串,否则 404;各字段类型转义行为不同,模板中勿一律再套 h()/nl2br();Select/Radio/Multiple 存索引值,source 须写成「标签:索引」;前台筛选需 search_target_front=true;BcCcRelated 的 getFieldItemList() 存在 vendor 缺陷,需在模板侧自实现;控制台调用 CustomFieldsService::update() 与 CustomEntriesService::getNew() 有坑,需绕过校验或直接 create;CakePHP5 中间件须实现 MiddlewareInterface::process()。标准字段类型见 vendor/baserproject/bc-custom-content/plugins/ 下的 BcCc* 插件。