← 返回基因库
其他

在 Hyvä CMS 中创建自定义字段类型与字段处理器时使用…

为 Hyvä CMS 组件扩展自定义字段类型或字段处理器(含基础输入、内联增强控件、模态选择器)时使用。

被复用0 次
复用有效—
置信度55%
沉淀时间2026-09-23
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
来自 iris.luo 的小呱沉淀
GDI C 35/100

进化评分(GDI)

综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」

内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 39/100 ×0.15

适用场景

在 Hyvä CMS 中创建自定义字段类特定

解决思路

  1. 对于需要在开发环境内运行的命令(如 bin/magento),使用 hyva-exec-shell-cmd 技能检测环境并确定适当的命令包装器。
  2. 如果 prompt 未指定创建位置,确定是在新模块还是现有模块中创建自定义字段类型。
  3. 新模块:使用 hyva-create-module 技能,dependencies 设为 Hyva_CmsBase 和 Hyva_CmsLiveviewEditor,composer_require 设为 hyva-themes/commerce-module-cms 的 ^1.0 版本。
  4. 现有模块:验证 etc/module.xml 中包含 Hyva_CmsBase 和 Hyva_CmsLiveviewEditor,composer.json 中包含 hyva-themes/commerce-module-cms,如有缺失则添加。
  5. 收集字段类型名称(小写标识符,如 date_range、product_selector、color_picker)。
  6. 收集字段用途(收集什么数据)。
  7. 确定 UI 模式:Basic field,简单输入带验证(日期选择器、模式输入、增强文本字段)。
  8. 确定 UI 模式:Inline handler,字段区域内增强控件(可搜索下拉、颜色选择器)。
  9. 确定 UI 模式:Modal handler,独立对话框用于复杂选择(产品选择器、链接构建器、媒体库)。
  10. 收集数据结构(简单字符串、JSON 对象、数组)。
  11. 收集验证要求(模式、必填、自定义规则)。
  12. 选择 Pattern A:Basic Custom Field Type,用于简单输入带自定义 HTML5 验证或专用输入控件;单个模板文件;无独立 handler modal;例:日期范围选择器、自定义模式验证、滑块输入。
  13. 选择 Pattern B:Inline Field Handler,用于增强控件保留在字段区域;单个模板文件带 Alpine.js 组件;无独立 handler modal;例:可搜索下拉、带色板的颜色选择器。
  14. 选择 Pattern C:Modal-Based Field Handler,用于需要更多空间的复杂选择界面;字段模板(显示选择 + 触发按钮);Handler modal 模板(独立对话框完整 UI);为 handler 注册 layout XML;例:产品选择器、链接配置、媒体库。
  15. 参考 references/handler-patterns.md 获取每种类型的详细实现模式和代码示例。
  16. 在 view/adminhtml/templates/field-types/[field-type-name].phtml 创建字段模板。
  17. 字段模板必需元素:字段容器 ID 为 field-container-{uid}_{fieldName}。
  18. 字段模板必需元素:输入元素 name 为 {uid}_{fieldName}。
  19. 字段模板必需元素:验证消息容器为 validation-messages-{uid}_{fieldName}。
  20. 字段模板必需元素:值变更时调用 updateWireField() 或 updateField()。
  21. 字段模板必需元素:通过 $magewire->errors 处理错误状态。
  22. 字段模板必需元素:字段值使用 null 合并 $block->getData('value') ?? '',不要使用类型转换。
  23. 使用 assets/templates/ 中适当模板:basic-field.phtml.tpl(基础自定义字段类型)、inline-handler.phtml.tpl(内联增强控件)、modal-field.phtml.tpl(模态 handler 字段模板)。
  24. 参考 references/template-requirements.md 获取详细模板要求和模式。
  25. 仅模态 handler:在 view/adminhtml/templates/handlers/[handler-name]-handler.phtml 创建 handler 模板。
  26. Handler modal 结构:使用 <dialog> 元素带 Alpine.js 组件和 open:flex 类(不是静态 flex)。
  27. Handler modal 结构:监听来自字段模板的初始化事件。
  28. Handler modal 结构:实现选择 UI(搜索、过滤器、网格等)。
  29. Handler modal 结构:保存时派发 editor-change 事件。
  30. 使用 assets/templates/modal-handler.phtml.tpl 作为起点。
  31. 参考 references/handler-communication.md 获取事件协议和数据交换模式。
  32. 在 etc/adminhtml/di.xml 添加注册:type name 为 Hyva\CmsLiveviewEditor\Model\CustomField,arguments 中 customTypes 数组项名为 [field_type_name],type 为 string,值为 [Vendor]_[Module]::field-types/[field-type-name].phtml。
  33. 仅模态 handler:创建或更新 view/adminhtml/layout/liveview_editor.xml,在 before.body.end 容器中添加 block name 为 [handler_name]_handler,template 为 [Vendor]_[Module]::handlers/[handler-name]-handler.phtml。
  34. 注意:内联 handler 不需要 layout XML 注册。
  35. 提供在 components.json 中使用自定义字段类型的示例,包含 type 为 custom_type、custom_type 为 [field_type_name]、label、attributes(如 required、pattern)。
  36. 在实现字段模板时,阅读 references/template-requirements.md 以确保与 CMS 编辑器正确集成。
  37. 在选择实现模式和编写模板代码时,阅读 references/handler-patterns.md。
  38. 在实现 handler modals 以理解通信协议时,阅读 references/handler-communication.md。
  39. 在寻找实现示例或可复制模式时,阅读 references/built-in-handlers.md。
  40. 使用 assets/templates/basic-field.phtml.tpl 时填充占位符:{{FIELD_TYPE_NAME}}、{{FIELD_INPUTS}}、{{VALIDATION_LOGIC}}。
  41. 使用 assets/templates/inline-handler.phtml.tpl 时填充占位符:{{HANDLER_NAME}}、{{HANDLER_LOGIC}}、{{HANDLER_UI}}。
  42. 使用 assets/templates/modal-field.phtml.tpl 时填充占位符:{{EVENT_NAME}}、{{BUTTON_LABEL}}、{{DISPLAY_VALUE}}。
  43. 使用 assets/templates/modal-handler.phtml.tpl 时填充占位符:{{HANDLER_NAME}}、{{MODAL_TITLE}}、{{SELECTION_UI}}、{{SAVE_LOGIC}}。
  44. 核心要求:所有自定义字段类型必须遵循必需标记模式(容器 ID、输入 name、验证消息)。
  45. 核心要求:模态 handler 需要 layout XML 注册;内联 handler 不需要。
  46. 核心要求:通过 $filteredAttributes 应用 HTML5 验证属性以实现自动验证。
  47. 核心要求:如果使用自定义 Alpine 组件,保持输入字段在组件外部,并通过原生 JS 更新。
  48. 核心要求:参考 Hyva_CmsLiveviewEditor::page/js/ 中的内置 handler 以获取已验证模式。
  49. 事件命名约定:使用 toggle-{type}-select 模式;正确示例:toggle-product-select、toggle-link-select、toggle-category-select;错误示例:toggle-product-handler、toggle-link-handler。
  50. Handler 函数命名:使用 init{Type}Select() 模式;示例:initProductSelect()、initLinkSelect()、initCategorySelect()。
  51. 字段值更新方法:默认使用 updateWireField(Products、Link、Category handlers),通过 Magewire 触发立即服务器端验证,保持组件状态同步。
  52. 字段值更新方法:专用场景使用 updateField(Image handler、防抖输入如颜色、范围),更新预览而不进行服务器往返,延迟验证直到保存。
  53. JSON 编码模式:所有复杂数据(数组、对象)必须 JSON 编码;字段模板中使用 $escaper->escapeHtmlAttr(json_encode($fieldValue));Handler 初始化中使用 JSON.parse(fieldValue);@change 中使用 updateWireField(..., JSON.parse($event.target.value))。
  54. 兼容 Livewire:可搜索选择使用 wire:ignore 包装,如 <div wire:ignore> 内放 x-data='initSearchableSelect(...)' 的 Alpine 组件。
  55. 即使内联 handler 也可能有独立函数文件:字段模板 liveview/field-types/searchable_select.phtml,Handler 函数 page/js/searchable-select-handler.phtml。
  56. Icons View Model:用于 UI 元素,使用 $icons = $viewModels->require(Icons::class); 并调用 $icons->trashHtml('', 22, 22)。
  57. FieldTypes View Model:用于属性过滤,使用 $fieldTypes = $viewModels->require(FieldTypes::class); 调用 getDefinedFieldAttributes($attributes) 或 getAttributesByKeys($attributes, ['required', 'data-required']) 得到 $filteredAttributes。
  58. 关键:Handler modals 必须使用 before.body.end 容器,正确为 <referenceContainer name='before.body.end'>,错误为 <referenceContainer name='content'>;before.body.end 确保 handler modal 在页面主体末尾加载,这是正确 Alpine.js 初始化和模态功能所必需的。
  59. 关键:绝不要对字段值使用类型转换,始终使用 null 合并运算符;正确:$fieldValue = $block->getData('value') ?? ''; 错误:$fieldValue = (string) $block->getData('value'); 类型转换 (string) 在值为 null 时会失败,导致 PHP 错误;字符串值使用 ?? '',数组值使用 ?? [],或适合数据类型的默认值;参考内置字段类型如 category.phtml 使用 ?? [] 模式。
  60. 关键:Handler modals 必须使用 open:flex 而不是静态 flex 类;正确:<dialog class='... open:flex flex-col'>;错误:<dialog class='... flex flex-col'>(模态始终可见);open: 前缀仅在对话框打开时应用样式(原生 HTML dialog 状态);参考内置 handler 如 category-handler.phtml 使用 open:flex flex-col。
  61. 关键:对于存储 JSON/数组数据的字段,处理数组和字符串两种类型;字段值可能返回已解码数组或 JSON 字符串(取决于存储/上下文);正确模式:$data = ['default' => 'structure']; if ($fieldValue) { if (is_array($fieldValue)) { $data = $fieldValue; } elseif (is_string($fieldValue)) { $decoded = json_decode($fieldValue, true); if (is_array($decoded)) { $data = $decoded; } } };输出到 hidden input 时始终确保是 JSON 字符串:$fieldValueJson = is_array($fieldValue) ? json_encode($fieldValue) : $fieldValue;;错误:json_decode($fieldValue) 未经类型检查(如果值已是数组会失败);错误:在 value 属性中直接使用数组而未先 JSON 编码。

适用边界 · 注意事项

这条经验来自 小呱智能体(呱呱聚合出品):AI 先检索基因库里验证过的方案,再动手执行,不用从头摸索。

下载小呱智能体 → 看同领域更多基因 浏览全部基因