可视化编辑设置 (Astro)
Astro 的可视化编辑路径不使用 useTina();该钩子是 React 特有的。相反,Astro 站点使用 @tinacms/astro,这是一个原生的 Astro 渲染器,加上一个小的 postMessage 桥,仅在编辑器 iframe 内加载。
流程:
tina()集成的请求范围中间件缓冲每个 HTML 响应,并在编辑模式请求时,将桥接引导和每个 TinaCMS 查询页面消耗的一个<div data-tina-form>负载拼接到<head>中。- 桥接器(从
/admin/bridge.js加载)读取这些负载,向父管理窗口发送open,并在内存数据存储中播种。 - 当编辑器输入时,管理端将
updateData回传给 iframe。桥接器存储它。 - 页面中的每个可编辑区域都包装在
<TinaIsland>中,它发出一个<… data-tina-island="/tina-island/<name>?<params>">标记。在每次存储更新时,桥接器将当前覆盖层 POST 到该端点。 - 该端点根据覆盖数据重新渲染匹配的 Astro 组件并返回一个 HTML 片段。桥接器将其替换到实时 DOM 中。
在生产环境中(没有管理父级),中间件不注入任何内容,init() 立即退出——生产 HTML 与无 TinaCMS 的 Astro 应用字节相同。(例外:使用 <TinaIsland> 的页面携带一行内联引导,因此当页面静态构建时编辑仍然有效。)
您需要一个 SSR 适配器。 每个岛屿的刷新端点 (
/tina-island/[name]) 在每次按键时运行。将adapter设置在astro.config.mjs中为@astrojs/node、@astrojs/vercel、@astrojs/netlify或@astrojs/cloudflare。output: 'server'是最简单的选择;output: 'static'也可以,只要您将可编辑区域包装在<TinaIsland />中。
安装
如果您的集合使用 MDX 正文,请添加 @astrojs/mdx。如果您是自托管(没有 TinaCloud),请添加 @tinacms/datalayer。
集成连接
在 astro.config.mjs 中添加一次 tina()。这一调用连接中间件(解析 Astro.locals.tinaEdit 并在编辑模式响应中注入桥接线)并将原生 JS 桥接作为静态资产放置在 /admin/bridge.js。
tinaAdminDevRedirect() 是一个仅用于开发的 Vite 插件,将 /admin 和 /admin/ 重定向到 /admin/index.html,以便在 astro dev 期间可以从裸 URL 访问管理 SPA。
没有共享的 <head> 连接组件,没有需要传递的 forms 属性,没有手动 init() 调用。集成处理所有这些。
数据加载器 — 用 requestWithMetadata 包装每个查询
每个路由的数据加载器调用生成的 TinaCMS 客户端,并通过 requestWithMetadata() 管道传递结果。这个调用:
- 将
{ query, variables }哈希化为桥接用于定位表单的稳定形式 ID。 - 从请求范围存储中读取桥接的覆盖层,并在页面在管理 iframe 内渲染时将
data替换为未保存的覆盖层。 - 使用
tinaField()需要的元数据标记结果以便点击聚焦。 - 记录中间件将在编辑模式请求中拼接到
<head>的表单负载。
priority: 'primary' 将表单标记为页面的主要文档,因此编辑器在加载时打开它,而不是停留在布局级别的全局(例如页眉/页脚配置)。它反映了 useTina() 的 experimental___selectFormByFormId。在 SSR 页面上,第一个 requestWithMetadata() 调用自动被视为主要;当您想要覆盖时,请显式传递。
返回的对象具有 { data, query, variables, id } — data 是您渲染的内容,哈希化的 id 是桥接用于将覆盖层匹配回表单的内容。
岛屿注册表
一个小型注册表将每个可编辑区域映射到一个获取器、一个组件、一个外部包装器和一个 propsFromData 投影。添加一个新的可编辑区域在这里是一个条目;动态路由会自动拾取它。
每个岛屿的端点 — 一个通用路由
桥接器在每次按键时 POST 到 /tina-island/<name>。一个动态路由,加上 experimental_createIslandRoute(),处理注册表中的每个条目:
这是桥接器需要的唯一文件。助手强制同源 POST 使用 TinaCMS-preview 内容类型,通过 Astro 的容器 API 渲染注册的组件,并将输出包装在注册的包装元素中——匹配页面侧的 <TinaIsland>,以便桥接器可以将其替换。
在页面中使用可编辑区域
将每个可编辑区域包装在 <TinaIsland> 中。wrapper 属性必须与注册表条目的包装器匹配(桥接器替换整个元素)。标记页面的主要区域为 primary,以便管理端在加载时打开该表单。
添加字段级点击编辑
tinaField() 返回一个字符串,用于标识 DOM 元素对应的表单字段。将其标记在您希望在编辑器中可点击的任何元素上:
从
@tinacms/astro/TinaMarkdown.astro(子路径)导入TinaMarkdown, 而不是从裸@tinacms/astro导入。Astro 的类型检查器通过子路径直接读取.astro文件;裸包默认通过types条件解析为一个占位符,Astro 不将其识别为可渲染组件。
粗粒度标记(整个 body)通常是正确的;点击内部的任何富文本节点都会将编辑器聚焦到该字段。请参阅 点击编辑 API 以获取完整的助手参考。
自定义 MDX 嵌入
要在富文本正文中渲染自定义组件(例如,YouTubeEmbed),请编写两个文件:一个描述编辑器 UI 的 schema Template,以及一个与模板同名的 Astro 渲染器。
1. schema Template:
2. Astro 渲染器:
在富文本字段的 templates 数组中注册模板:
并在 <TinaMarkdown components={…}> 映射中注册渲染器:
两个name字符串必须匹配。 模板的name: 'YouTubeEmbed'和组件映射键YouTubeEmbed是渲染器从富文本 AST 中调度mdxJsxFlowElement节点的方式。不匹配会将嵌入渲染为可见的占位符,以便您在开发期间发现缺失的注册。
默认标签覆盖
同一个 components 映射可以覆盖任何富文本节点的默认 HTML 标签,方便在不分叉渲染器的情况下进行样式设置:
支持的覆盖键:p、h1–h6、ul、ol、li、blockquote、lic、a、img、code_block、hr、break。请参阅 @tinacms/astro README 以获取完整的节点参考。
CMS 提供的 a 和 img 节点中的 URL 通过 sanitizeHref / sanitizeImageSrc,阻止 javascript:、data:、vbscript: 和协议相对 URL。两个助手都在 @tinacms/astro/sanitize 上公开,以便在您自己的组件中使用。
静态站点编辑
支持 output: 'static'。上述中间件仅在按需渲染的路由上运行,因此在预渲染页面上它从不注入任何内容——相反,<TinaIsland> 发出一个小的内嵌引导脚本,仅在页面在管理 iframe 内打开时加载 /admin/bridge.js。在启动时,桥接器获取每个岛屿的 /tina-island/[name] 端点(仍然是 prerender = false,因此适配器按需渲染它)以获取页面的表单负载,然后编辑工作与在 SSR 项目中完全相同。
静态编辑的要求:
- 将每个可编辑区域包装在具有注册岛屿的
<TinaIsland>中——这既是桥接器重新渲染区域的方式,也是引导程序进入页面的方式。 - 在页面的主要
<TinaIsland>上传递primary。在静态页面上,桥接器无法自动判断哪个岛屿是“页面”,因此没有这个,编辑器可能会停留在多文档选择器上。 - 保持
export const prerender = false在src/pages/tina-island/[name].ts上。
权衡:使用 <TinaIsland> 的页面在生产 HTML 中携带那一行内联引导——它不再与无 TinaCMS 的 Astro 应用字节相同。没有 <TinaIsland> 的页面保持不变。
跨域管理
如果您的管理在不同的域(Codespaces、独立域自托管),请在您的 .env 中设置:
用逗号分隔以允许多个(预览 + 生产)。中间件内嵌它,以便桥接器验证入站 postMessages。
子包导出
您需要的一切都在 @tinacms/astro 下:
子路径 | 提供的内容 |
|---|---|
|
|
|
|
|
|
|
|
| 集成自动连接的中间件 — 导出以防您需要手动组合 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
另请参阅
- Astro 启动模板:包含上述所有内容的参考实现
- 部署到 Cloudflare Workers:发布站点并在请求时保持此按需岛屿路由工作
- 点击编辑 API:
tinaField()语义 - 可视化编辑路由器:将深度链接管理 URL 连接到您的路由