关于 embed-creator
Embed Creator 是用于在分支上创建或编辑 Datex Studio iframe 嵌入组件的技能,涵盖外部 URL 或 HTML 预览的呈现,以及发布前的配置、验证和组件连接。
主要功能
- 01创建或编辑 Datex Studio 嵌入配置
- 02通过 iframe 呈现外部 URL 或 HTML
- 03发布前验证配置
- 04将嵌入参数连接到打开它的组件
- 05检查命名和配置要求
适用场景
- 01在对话框中显示托管地图或仪表板
- 02预览生成的邮件或报告 HTML
- 03更新现有嵌入配置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ datex/ skills --skill embed-creator安装后在 Claude Code 中输入/embed-creator确认已加载。
附带文件references/embeds.md
详细介绍
嵌入组件创建器
在分支上创建或修改 Datex Studio 嵌入组件(configurationTypeId=20)——这是一种轻量级 UI 组件,其全部界面只有一个 <iframe>。嵌入组件可渲染外部 URL(托管地图、仪表板、文档查看器)或内存中的 HTML 字符串(生成的邮件/报告预览),并且几乎总是通过 $shell.open<referenceName>Dialog(...) 作为对话框打开(如果嵌入组件注册在模块下,则会在前面加上该模块的名称)。
参考资料
- ../datex-studio-shared/branch-setup.md — 分支/连接选择(多个技能共用)
- references/embeds.md — 权威的嵌入组件编写参考:文件结构、最小有效骨架、仅限 iframe 的规则、
data:URI HTML 字符串模式、对话框接线、打印模式、CSP 注意事项、上线前检查清单 - ../datex-studio-conventions/file-format.md —
configurationTypeId表格和 TypeScript 表达式编码规则(适用于iframeConfig.href) - ../datex-studio-conventions/naming-conventions.md —
_embed/-embed后缀、文件名主体匹配规则、显示名称规则 - ../datex-studio-runtime/runtime-globals.md — 嵌入组件代码中可用的平台注入全局变量(
$embed、$shell、$datasources、$utils等) - ../form-creator/references/forms.md — 配套组件;如果需要在内容旁边放置字段控件/按钮,请选择表单(表单与嵌入组件的选择)
- ../component-wiring-check/references/component-wiring.md — 宿主引用约定、变量必须声明规则,以及打开嵌入组件的组件所需遵循的
moduleId规则
依赖项
requirements-gathering技能 — 如果当前对话上下文中还没有需求摘要,则调用此技能生成一份form-creator技能 — 如果需求确实需要在内容旁放置字段控件或工具栏,则调用此技能(嵌入组件仅限 iframe,没有按钮界面)component-wiring-check技能 — 推送前审计打开嵌入组件的组件上的configParameters↔inParams契约
CLI 生命周期
嵌入组件的编写通过 dxs configuration 完成——这是适用于所有平台配置类型的通用 CRUD 基元。没有 dxs embed 子命令,也不支持按字段修补;你需要构建(或获取并提取)完整的 JSON 请求体,编辑后再将整个请求体推送回去。CLI 中的类型标识符是 embed(小写),对应 configurationTypeId: 20。
创建新的嵌入组件:
# 1. Build body.json from scratch (see references/embeds.md → Minimal Valid Skeleton)
# 2. Validate — gates the push; exit 1 = errors found, not a broken CLI. Catches the "HREF is required" failure before push
dxs configuration validate embed -b <branchId> -D body.json
# 3. Create (upsert creates or updates by referenceName)
dxs configuration upsert embed -b <branchId> -D body.json
编辑现有嵌入组件:
# 1. Fetch — note the envelope wrapper
dxs configuration get embed <configId> -b <branchId> -O envelope.json
# 2. EXTRACT THE INNER BODY (round-trip footgun guard)
jq .json envelope.json > body.json
# 3. Edit body.json
# 4. Validate — gates the push. Exit 1 = errors found (read validation_errors, fix, re-run), not a broken CLI
dxs configuration validate embed -b <branchId> -D body.json
# 5. Push
dxs configuration upsert embed -b <branchId> -D body.json
往返规则(至关重要)
编辑现有配置时,绝不要将 envelope.json 直接通过管道传给 dxs configuration upsert——这会在不提示的情况下破坏配置内容。编辑前务必先执行 jq .json envelope.json > body.json。有关规范的往返流程和底层错误,请参阅 ../datex-studio-shared/configuration-roundtrip.md。
工作流
[Phase 1: Setup + Requirements]
Follow branch-setup.md for branch/connection selection
|
[requirements brief in context?] ── NO ─> invoke `requirements-gathering`
|
[Phase 2: Embed vs Form decision]
Consult references/embeds.md → "Purpose & When to Use":
- render a URL or an HTML blob, no controls needed -> embed
- needs field inputs, a toolbar, or a Print button
that lives outside the rendered content -> form (or put the
control inside the HTML)
If field controls/toolbar are required -> invoke `form-creator` and stop here.
|
[Phase 3: Pick the source — URL or HTML string]
URL -> iframeConfig.href points at the URL (directly or via a var
computed in on_init). Example: a hosted map.
HTML string -> on_init sets a var to a data:text/html URI built from the
HTML; iframeConfig.href points at that var.
|
[Phase 4: Author embed body]
Build body.json from references/embeds.md → Minimal Valid Skeleton:
- type: "iframe" (the only supported designer type)
- iframeConfig.href (REQUIRED — a TS expression, usually $embed.vars.<url>)
- inParams[] (the URL / HTML / id the host passes in)
- vars[] (the computed href var)
- onInitFlowConfig -> on_init flow that computes the href var
|
[Phase 5: Validate + push]
dxs configuration validate embed -b <branchId> -D body.json
dxs configuration upsert embed -b <branchId> -D body.json
|
[Phase 6: Wire the opener + verify]
Caller opens it: $shell.open<referenceName>Dialog(inParamsObj, 'flyout', EModalSize.Xlarge) (+ <Package>. segment if the embed is in a module)
Verify in Studio: iframe renders; if HTML preview, the in-document Print button works
|
[invoke `post-edit-verification`; then `component-validator`]
阶段详情
阶段 2:选择嵌入组件还是表单
嵌入组件的整个可见界面就是 iframe——没有字段控件、没有工具栏,也没有按钮界面。如果需求只是“在对话框或面板中渲染此 URL/HTML”,请选择嵌入组件。如果对话框需要输入项、先验证再确认的流程,或内容周围的界面元素(标题、工具栏),则改用表单。如果既需要按钮又需要渲染 HTML,实用的做法是将按钮放在 HTML 内部(参见打印模式),而不是选择表单——表单无法承载 iframe(没有 iframe 字段控件)。
第 3 阶段:选择来源 — URL 或 HTML 字符串
iframeConfig.href 是唯一的内容通道。没有 srcdoc,也没有内联 HTML 嵌入类型——对于此技能,type 始终为 iframe(枚举的另一个成员 powerBi 不受代码生成支持,且在 Studio UI 中受限;请参阅常见错误)。因此:
-
外部 URL — 在
on_init中计算 URL,或将其硬编码到 href 变量中。根据$embed.inParams构建查询参数。 -
内存中的 HTML 字符串 — 在
on_init中将字符串转换为data:URI:$embed.vars.ref_url = "data:text/html;charset=utf-8," + encodeURIComponent($embed.inParams.html);然后将
iframeConfig.href指向"$embed.vars.ref_url"。这是在对话框中呈现生成的 HTML(例如邮件预览、报告校样)的规范方式。请参阅 references/embeds.md → 呈现 HTML 字符串。
第 4 阶段:编写嵌入内容
根据 references/embeds.md → 最小有效骨架构建 body.json。要点如下:
- 文件基本要求。
configurationTypeId: 20,后缀为-embed.json,referenceName以_embed结尾,且与文件名主体一致。此外还需通过通用检查(../datex-studio-conventions/universal-checklist.md)——description不得为 null,且长度不得超过 100 个字符。 type: "iframe"。 这是唯一受代码生成支持的EEmbedDesignerType。枚举还定义了powerBi,但代码生成对其支持不完整,且在 Studio UI 中受限——切勿编写此类型。不属于枚举成员的值(html、script、content、code)会直接导致验证失败。iframeConfig.href为必填项,且是 TypeScript 表达式。 裸写的$embed.vars.ref_url是原始表达式(不会被包装)。字面 URL 必须是 TS 字符串字面量("'https://example.com'")——但更推荐在on_init中计算 URL 并绑定变量,因为 URL 几乎总是依赖于inParams。请参阅 ../datex-studio-conventions/file-format.md → 声明式字符串值是 TypeScript 表达式。- 声明你写入的每个
$embed.vars.<id>。 href 变量(以及任何其他变量)都必须出现在顶层vars[]中,否则写入会失败。规则与编辑器/表单相同。 on_init负责计算 href。onInitFlowConfig流(一个configurationTypeId: 9的嵌入式流)用于读取$embed.inParams、构建 URL 或data:URI,并为 href 变量赋值。
第 6 阶段:连接打开操作并验证
打开嵌入内容的组件(编辑器流、hub 工具栏按钮、网格行操作)会调用自动生成的 shell 方法:
// top-level embed (no package):
await $shell.opencustom_email_preview_embedDialog({ html: previewHtml }, 'flyout', EModalSize.Xlarge);
// embed registered under a package:
await $shell.<Package>.opencustom_email_preview_embedDialog({ html: previewHtml }, 'flyout', EModalSize.Xlarge);
该方法的名称由 open + 嵌入内容的 referenceName + Dialog 组成(保留 snake_case)。仅当嵌入内容注册在某个包/模块下时,方法名才包含包段——顶层应用嵌入内容的打开方式为 $shell.open<referenceName>Dialog(...),不带包段。若存在包,则 <Package> 指的是嵌入内容所属的模块,而非调用方所属的模块。inParam 对象由嵌入内容的 inParams 生成;宿主必须为这些 inParams 提供完整的 configParameters 契约(对于包中的嵌入内容,还必须将 moduleId 设置为该嵌入内容所属的包)——使用 component-wiring-check 进行审核。
在 Studio 中验证:iframe 能否呈现 URL/HTML;对于 HTML 预览,确认文档内的 Print 按钮只打印嵌入内容(请参阅 Print 模式及其注意事项)。
发布前检查清单
按照 references/embeds.md → 发布前检查清单 完整检查。快速版:
- 文件基础信息。
configurationTypeId: 20,后缀为-embed.json,referenceName以_embed结尾且与文件名主体一致,title是独特的句式标题显示名称——另需通过通用检查(../datex-studio-conventions/universal-checklist.md)。 type: "iframe"——代码生成唯一支持的类型;切勿编写powerBi(虽已定义,但不受支持)。- 必须提供
iframeConfig.href——省略会报错HREF is required。 - 声明 href 变量,在顶层
vars[]中声明,并在on_init中赋值。 - HTML 字符串嵌入需构建
data:text/html;charset=utf-8,+encodeURIComponent(...)URI;不能依赖srcdoc。 - **打印按钮(如为预览)**应位于 HTML 内部(
onclick="window.print()"),并通过@media print隐藏——切勿假设父级可以调用 iframe 内部内容。 - 宿主约定——宿主需为每个嵌入的
inParam声明一个configParameters条目;通过component-wiring-check检查。 description不得为 null 或空,且最多 100 个字符。
常见错误
权威的症状 → 原因 → 修复表见 references/embeds.md → 常见故障模式。编写时最常遇到的问题:
- 使用
srcdoc,或使用非iframe的type(html/script/content)以内联方式注入标记——这些方式均不受支持;应通过href上的data:text/htmlURI 渲染 HTML。 - 省略
iframeConfig.href——验证会报错HREF is required;它是唯一的内容通道。 - 未在
vars[]中声明就写入$embed.vars.<id>——写入会失败。 - 在
href中硬编码未加引号的 URL 字面值——href是 TS 表达式;应为其添加 TS 引号("'https://...'"),或在on_init中计算。 - 更新封装对象,而非内部的
.json——会静默破坏配置内容;先运行jq .json envelope.json > body.json。
编辑后,请调用 post-edit-verification,以发现描述、JSON 或架构违规。最终审核时,请调用 component-validator。