表单定义与组件速查
从 Halo 2.0 开始,Console 端的表单使用 FormKit 构建。FormKit 既支持 Vue 组件,也支持可序列化的 Schema。Halo 的主题设置、插件设置和元数据表单都可以复用 FormKit Schema 和本文列出的扩展输入组件。
本文是通用速查,只说明 Setting 结构、Schema 约束和输入组件契约。如何关联资源、读取配置以及处理场景特有的限制,请先进入对应指南。
选择正确的使用场景
FormKit 相关文档:
- Form Schema: https://formkit.com/essentials/schema
- FormKit Inputs: https://formkit.com/inputs
Halo 使用 FormKit 开源版本提供的默认输入组件,不支持 FormKit Pro 输入组件。Halo 额外提供的组件将在下文列出。
常用 FormKit 原生输入
Halo 已经注册 FormKit 开源版本的原生输入。以下是 Setting Schema 中常用的类型,具体参数和验证规则以 FormKit 官方文档为准。
Halo 已覆盖原生 select,请使用本文的 select 参数。附件应优先使用 attachment,不要使用 FormKit 原生文件上传自行实现附件管理。
插件需要注册自定义输入类型时,通过 UI 入口文件的 formkit.inputs 注册,详细文档请参考 插件 FormKit 扩展。
Setting 资源定义方式
Setting 的值最终保存在 ConfigMap 中。password 输入类型只会隐藏界面上的输入内容,并不会加密保存的数据。密码、Token、API Key 等敏感信息应保存在 Halo 的 Secret 资源中,并通过 secret 组件选择对应资源。
主题设置不应重复定义 Logo、favicon、全局代码注入和系统级 SEO,具体边界请参考主题设置选项。插件设置也应只包含插件自身的业务配置,不要为 Halo 已有的系统设置增加第二个配置入口。
FormKit Schema 是可 JSON 序列化的数据结构,Setting 使用 YAML 只是资源文件的表示形式,不需要手动进行 JSON 与 YAML 转换。可以将 FormKit 文档中的对象结构改写为等价的 YAML,但不能直接在 YAML 中定义 JavaScript 函数。只有渲染端通过 Schema data 提供的函数才能在表达式中调用。
字段说明:
metadata.name:设置资源的名称,建议以-setting结尾。spec.forms:必填的表单定义列表,至少包含一个表单分组。spec.forms[].group:必填的分组名称,同时也是 ConfigMap 中保存该组数据的键。发布后应保持稳定,并且不能与同一 Setting 中的其他分组重复。spec.forms[].label:可选的表单标题。spec.forms[].formSchema:必填的 FormKit Schema 节点列表。
每个需要持久化的输入项都应设置唯一的 name。保存后,该 name 将作为表单数据对象中的字段名。
Halo 只会从 formSchema 的直接子节点中提取同时具有 name 和 value 的节点,用于初始化对应 ConfigMap。嵌套在 children 中的节点不会被递归提取;list、array 等容器需要在容器节点上设置完整的默认 value。
Halo 扩展组件速查
verificationForm需要可访问的服务端验证接口,通常由插件或其他服务端扩展提供。secret只保存 Secret 资源名称,Secret 内容必须由服务端读取,主题模板不能通过设置值直接获得凭据。multiple: true会让部分选择器返回数组,不适用于只允许字符串值的 AnnotationSetting。- 组件涉及的附件、用户、角色、分类、标签等资源仍受当前用户权限限制。
组件类型
除了 FormKit 官方提供的常用输入组件之外,Halo 还额外提供了一些输入组件,这些输入组件可以在 Form Schema 中使用。
select
描述
自定义的选择器组件,支持静态和动态数据源,支持多选等功能。
选项对象至少需要包含 label 与 value。除此之外,还可以提供 icon 与 description 用于增强下拉选项展示(引入版本:2.25.0,远程动态数据源可通过 requestOption.iconField 与 requestOption.descriptionField 映射响应字段):
icon:图标图片地址,会以<img>渲染。description:显示在label下方的说明文字,同时参与本地静态选项搜索。
选中后的单选展示和多选标签仍然只显示 label,提交值保持为选项的 value,多选时提交 value 数组。
参数
options:静态数据源。当action存在时,此参数无效。action:远程动态数据源的接口地址。requestOption:动态数据源的请求参数,可以通过此参数来指定如何获取数据,适配不同的接口。当action存在时,此参数有效。remoteOptimize:是否开启远程数据源优化,默认为true。开启后,将会对远程数据源进行优化,减少请求次数。仅在动态数据源下有效。allowCreate:是否允许把搜索关键词作为新选项值,默认为false,需要同时开启searchable。此选项不会在远程服务中创建对应资源。clearable:是否允许清空选项,默认为false。multiple:是否多选,默认为false。maxCount:多选时最大可选数量,默认为Infinity。仅在多选时有效。sortable:是否支持拖动排序,默认为true。仅在多选时有效。searchable: 是否支持搜索,默认为false。autoSelect:当初始值不存在且未设置placeholder时,是否自动选择第一个选项,默认为true。仅在单选时有效。
参数类型定义
PropertyPath 表示响应对象中的属性路径,例如 post.spec.title。
静态数据示例
远程动态数据示例
支持远程动态数据源,通过 action 和 requestOption 参数来指定如何获取数据。
请求的接口将会自动拼接 page、size 与 keyword 参数,其中 keyword 为搜索关键词。
action 使用 Halo Console 提供的 Axios 实例和当前登录会话发起请求,因此应指向当前用户有权访问的同源 Halo API。如果需要访问第三方服务,应由插件后端代理请求并向 Console 暴露受权限保护的接口。
当远程数据具有分页时,可能会出现默认选项不在第一页的情况,此时 Select 组件将会发送另一个查询请求,以获取默认选项的数据。此接口会携带如下参数:
其中,value1, value2, value3 为默认选项的值。返回值与查询一致,通过 requestOption 解析。
list
描述
列表类型的输入组件,支持动态添加、删除数据项。
list 组件与 array 组件功能类似,但它们的用途不同。list 组件适合展示基本类型的数据,而 array 组件更适合于展示复杂类型的数据。
参数
itemType:数据项的数据类型,用于初始化数据。可选参数string、number、boolean、object,默认为stringmin:数组最小要求数量,默认为0max:数组最大容量,默认为Infinity,即无限制addButton:是否显示添加按钮addLabel:添加按钮的文本upControl:是否显示上移按钮downControl:是否显示下移按钮insertControl:是否显示插入按钮removeControl:是否显示移除按钮
示例
list 组件有且只有一个子节点,并且必须为子节点传递 index 属性。若想提供多个字段组成对象,则建议改为使用 array 组件。
最终保存表单之后得到的值为以下形式:
verificationForm
描述
用于远程验证一组数据是否符合要求的组件。
参数
action:对目标数据进行验证的接口地址label:验证按钮文本buttonAttrs:验证按钮的属性,例如通过disabled禁用按钮
示例
尽管 verificationForm 本身是一个输入组件,但与其他输入组件不同的是,它仅仅用于包装待验证的数据,所以并不会破坏原始数据的格式。例如上述示例中的值在保存后为:
而不是
示例中发送至验证地址的值为如下格式:
当验证接口返回成功响应时,则验证通过,否则验证失败。
若用户在验证失败时想显示错误信息,可以在验证接口返回错误信息,该错误信息的结构定义需遵循 RFC 7807 - Problem Details for HTTP APIs。例如:
UI 效果:
repeater(已过时)
repeater 组件已不再推荐使用,请使用 array 组件代替。
描述
一组重复的输入组件,可以用于定义一组数据,最终得到的数据为一个对象的数组,可以方便地让使用者对其进行增加、移除、排序等操作。
参数
min:数组最小要求数量,默认为0max:数组最大容量,默认为Infinity,即无限制addButton:是否显示添加按钮addLabel:添加按钮的文本upControl:是否显示上移按钮downControl:是否显示下移按钮insertControl:是否显示插入按钮removeControl:是否显示移除按钮
示例
使用 repeater 类型时,一定要设置默认值,如果不需要默认有任何元素,可以设置为 []。
其中 name 和 url 即数组对象的属性,最终保存表单之后得到的值为以下形式:
UI 效果:
attachment
描述
在 Halo 2.22 中,我们重构了原有的 attachment 表单类型,支持了预览和直接上传文件,并将旧版的表单类型更名为了 attachmentInput。
附件类型的输入框,支持预览附件、直接上传文件、从附件库选择。
参数
accepts:允许选择的文件类型,数据类型为string[],默认为["*"]width:预览区域宽度,默认为5remaspectRatio:预览区域长宽比,默认为1/1,也可以设置为16/9等比例multiple:是否支持多选,默认为false。设置为true后,值为字符串数组
示例
附件上传和附件库入口会根据当前用户权限显示;用户也可以输入可访问的附件链接。
attachmentInput
描述
附件类型的输入框,支持直接调用附件库弹框选择附件。
参数
accepts:文件类型,数据类型为string[]
示例
attachmentGroupSelect
附件分组选择器,用于选择系统中未被隐藏的附件分组,保存值为分组资源的 metadata.name。
引入版本:2.4.0
attachmentPolicySelect
附件存储策略选择器,用于选择系统中的附件存储策略,保存值为策略资源的 metadata.name。
引入版本:2.4.0
code
描述
代码编辑器的输入组件,集成了 Codemirror。
参数
language:代码语言,目前支持yaml、html、javascript、css、json、markdown。其中markdown从 Halo 2.22.0 开始支持。height:代码编辑器的高度。
示例
color
颜色选择器,支持通过拾色器或文本输入颜色,保存值为指定格式的字符串。
引入版本:2.22.0
参数
format:颜色格式,可选值为hex、hex8、rgb、hsl,默认为hex
menuSelect
描述
菜单选择器,用于选择系统内的导航菜单,支持单选、多选、排序。
示例
menuSelect 基于 select,并兼容 select 的参数。
menuItemSelect
菜单项选择器,用于从指定的菜单项资源中选择一项,保存值为菜单项资源的 metadata.name。
引入版本:2.4.0
参数
menuItems:必填的菜单项资源名称数组,用于限定可选范围
menuCheckbox
描述
菜单复选框,用于选择系统内的导航菜单。其中选择的值为菜单资源 metadata.name 的集合。
示例
menuRadio
描述
菜单单选框,用于选择系统内的导航菜单。其中选择的值为菜单资源 metadata.name。
示例
postSelect
描述
文章选择器,用于选择系统内已发布且未删除的文章。其中选择的值为文章资源 metadata.name。
示例
singlePageSelect
描述
单页选择器,用于选择系统内已发布且未删除的独立页面。其中选择的值为独立页面资源 metadata.name。
示例
categorySelect
描述
文章分类选择器,用于选择系统内的文章分类。其中选择的值为文章分类资源 metadata.name;开启多选后,值为资源名称数组。
参数
multiple:是否支持多选,默认为falseexcludedNames:需要排除的分类资源名称数组(引入版本:2.26.0)allowCreate:是否允许创建新分类,默认为true(引入版本:2.26.0)
示例
创建分类需要当前用户具有文章管理权限。如果设置表单只应选择现有分类,请显式设置 allowCreate: false。
categoryCheckbox
描述
文章分类复选框,用于选择系统内的文章分类。其中选择的值为文章分类资源 metadata.name 的集合。
示例
tagSelect
描述
文章标签选择器,用于选择系统内的文章标签。其中选择的值为文章标签资源 metadata.name;开启多选后,值为资源名称数组。
参数
multiple:是否支持多选,默认为false
示例
当用户输入不存在的标签且具有文章管理权限时,选择器可以创建新标签。使用方不应假定该组件只会读取已有资源。
tagCheckbox
描述
文章标签复选框,用于选择系统内的文章标签。其中选择的值为文章标签资源 metadata.name 的集合。
示例
roleSelect
角色选择器,用于选择系统中的非模板角色,保存值为角色资源的 metadata.name。
引入版本:2.4.0
userSelect
用户选择器,支持远程搜索,并排除匿名用户和已删除用户,保存值为用户资源的 metadata.name。
引入版本:2.4.0
iconify
统一的图标选择器,基于 Iconify。
引入版本: 2.22.0
示例
参数
format:图标格式,默认为svgsvg:svg 字符串dataurl:经过 URI 编码的 SVG Data URL,可以直接用于img标签url:Iconify 的 CDN 链接name:Iconify 的图标名称,需要在使用的地方自行加载图标
value-only:是否仅返回图标数据,默认为falsepopper-placement:图标选择弹窗的打开位置,默认为auto,可以为:auto、auto-end、auto-start、bottom、bottom-end、bottom-start、left、left-end、left-start、right、right-end、right-start、top、top-end、top-startsizing:图标尺寸配置对象(引入版本:2.23.0),包含以下属性:enabled:是否显示图标尺寸配置,默认为falsedefault:默认尺寸,字符串类型,默认为"24"presets:预设尺寸,字符串数组类型
值类型
当 value-only 参数为 true 时,此表单项的值为 string 类型,比如当 format 为 svg 时,返回值数据形如 <svg>...</svg>
当 value-only 参数不填写或为 false 时,表单类型的值为对象,包含以下属性:
value: 图标数据,当format参数不同时,value 的形式也不同,具体如下:svg:value 的值为 svg 字符串,可以直接放置在 HTML 中使用dataurl/url:可以使用img标签加载name:Iconify 对应的图标名称,需要在前端加载 Iconify 的依赖配合使用
name:Iconify 对应的图标名称,保留这个字段的目的是为了在 Console 中回显图标信息,通常不需要使用此字段width:用户在选择图标时设置的图标大小,此字段的目的是为了在 Console 中再次编辑时回显,通常不需要使用此字段color:用户在选择图标时设置的图标颜色,此字段的目的是为了在 Console 中再次编辑时回显,通常不需要使用此字段
在主题模板中的使用示例:
开发者可根据具体使用情况自行选择图标格式,通常推荐 svg 或者 dataurl,因为这样无需任何网络请求,确保图标可以稳定地正常加载。
UI 效果:
array
一组重复的输入组件,展示为列表形式,可以用于定义一组数据。最终得到的数据为一个对象的数组,方便使用者对此数组进行增加、删除、排序等操作。
引入版本: 2.22.0(计划用于替换已过时的 repeater 组件)
参数
min:数组最小要求数量,默认为0max:数组最大容量,默认为Infinity,即无限制removeControl:是否允许移除元素addButton:是否显示添加按钮addLabel:添加按钮上显示的文本addAttrs:添加按钮的额外属性emptyText: 当数组为空时显示的文本itemLabels: 列表元素上显示的内容,数据类型为{ type: "image" | "text" | "iconify" | "color"; label: string }[]
强烈建议为 array 设置 itemLabels 属性,以便于更直观的展示元素内容,设置的元素内容将按照设置顺序展示在列表元素上。
在 itemLabels 中定义 label 时,可以使用 $value 指向当前项的值,也可以使用 $value.name、$value.profile.name 等路径读取嵌套字段。
示例
switch
开关组件,提供两个值之间的选择;当您想使用户切换功能开或关时,这是一个很好的选项
引入版本: 2.22.1
参数
onValue:开关打开时的值,默认为trueoffValue:开关关闭时的值,默认为falsedisabled:是否禁用开关,默认为false
示例
如果需要开关的值为其他值,可以设置 onValue 和 offValue 参数。
toggle
切换组件,用于对一组图片、颜色或文字等选择切换,支持单选与多选。它的功能与 select 组件类似,但相较于 select 组件,toggle 组件可以更直观的展示选项。
引入版本: 2.22.8
参数:
renderType:当前组件的渲染类型,可选参数为image、color、text,默认为text。options:一组同类型的数据源,数据类型为{ label?: string; value: string; render?: string }[],其中label为选项的文本,value为选项的值。render为选项的渲染展示内容,与renderType参数配合使用。- 当
renderType为image时,render参数为图片的 URL。 - 当
renderType为color时,render参数为颜色的十六进制代码。例如#000000。 - 当
renderType为text时,render参数为文字内容。
- 当
multiple:可选,是否支持多选,默认为false。size:可选,渲染内容的尺寸,number类型,单位为px。gap:可选,渲染内容之间的间距,number类型,单位为px。value: 可选初始值,数据类型为string | number | boolean | (string | number | boolean)[]。
示例
UI 效果
secret
密钥输入组件,用于选择一个密钥资源。
引入版本:2.17.0
在 Halo 中,我们提供了一种更加安全的数据存储模型,即 Secret,通常我们使用 Secret 来存储敏感数据,比如密码、token、密钥等。
需要注意的是,此表单类型保存的是 Secret 资源名称,需要服务端根据该名称查询 Secret 资源。主题模板不能通过该设置值直接获取 Secret 内容。
参数
requiredKeys:所需的密钥字段,用于说明所选 Secret 应包含的字段(引入版本:2.22.10)。此字段为对象数组类型,对象包含以下属性:key:密钥字段名称help:可选的密钥字段说明
descriptionPreset:创建密钥时的备注预设(引入版本:2.25.0)。打开创建密钥弹窗时,备注字段会预填为<descriptionPreset> - <当前时间>,用户仍可在保存前编辑。
requiredKeys 只用于 Console 中的创建提示和缺失提醒,不会阻止服务端读取到字段缺失或值为空的 Secret。使用 Secret 的服务端代码必须自行校验所需字段,并返回清晰的错误信息。