CMS后端前端插件系统【免费下载链接】emdashEmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress项目地址https://gitcode.com/gh_mirrors/emdas/emdash点击查看免费下载EmDashtemplates/marketing-cloudflare 等模板内置的 Astro CMS提供了面向 Agent 的 CLI 编辑链路让你完全脱离后台界面用 Markdown 写富文本、用_rev令牌安全地更新条目并在读写后立即获得一致结果。读完本文你将掌握 EmDash CLI 的 Portable Text 自动转换规则、--raw原样模式、--draft/自动发布语义、_rev乐观并发控制与ENTRY_LOCKED编辑锁的处理方法并能在脚本与 CI 中安全地批量编辑内容。本文的主体基于仓库内 EDITING-FLOW.md 与 SKILL.md并辅以 CLI 命令实现 content.ts 与转换层 portable-text.ts 的源码佐证。一、Portable Text 与 Markdown双向自动转换EmDash 将富文本以 Portable TextPT格式存储——这是一种结构化的 JSON 数组格式。为了让 Agent 和脚本以熟悉的纯文本工作CLI 会在读取与写入时自动完成 PT 与 Markdown 之间的转换。1.1 自动转换的方向与规则读取时On readportableText字段中的 PT 数组会被转换为 Markdown 字符串写入时On writeportableText字段中的 Markdown 字符串会被转换回 PT 数组非 PT 字段string、text、number 等原样透传不做任何转换。关键在于CLI 并不是盲目转换而是先获取集合的字段 schema只对声明为portableText类型的字段执行转换。这在源码中有直接体现——转换层提供了两个 schema 感知的辅助函数convertDataForRead(data, fields, raw)仅当field.type portableText且字段值为数组时才调用portableTextToMarkdownportable-text.tsconvertDataForWrite(data, fields)仅当field.type portableText且字段值为字符串时才调用markdownToPortableTextportable-text.ts。1.2 支持的 Markdown 语法标准块级语法可以无损往返round-tripMarkdownPT block# Heading至######h1–h6 blocks普通段落normal block Quoteblockquote- item/* itembullet list用 2 空格缩进实现嵌套1. itemnumbered list用 2 空格缩进实现嵌套langcode block带语言标记altimage block行内标记inline marksMarkdownPT mark**bold**strong_italic_emcodecode~~strike~~strikethroughtextlink annotation源码中的解析正则印证了上述能力HEADING_PATTERN^(#{1,6})\s(.)$、UNORDERED_LIST_PATTERN、ORDERED_LIST_PATTERN、IMAGE_PATTERN、INLINE_MARKDOWN_PATTERN覆盖**bold**、_italic_、code、text、~~strike~~全部定义在 portable-text.ts。列表嵌套的实现方式是按缩进空格数整除 2 计算levelMath.floor(indent.length / 2) 1序列化时再按level反推两空格缩进portable-text.ts。1.3 未知块Opaque Fences不透明围栏转换器无法识别的块自定义块、embed 等会被序列化为 HTML 注释形式的围栏!--ec:block {_type:callout,level:warning,text:Be careful} --这些围栏能无损地存活于往返转换中你可以看到它、移动它但直接编辑其中的 JSON 有损坏风险。写入时CLI 会通过OPAQUE_FENCE_PATTERN/^!--ec:block (.) --$/识别并反序列化将原始 PT 块原样拼接回内容数组portable-text.ts。转换层注释将其定位为Tier 3未知块 → 不透明围栏保留不可编辑与标准块Tier 1和未来的 Markdown 指令Tier 2区分开。1.4 Raw Mode跳过转换直取 PT JSON当你需要完全掌控 PT 结构时用--raw跳过 Markdown 转换npx emdash content get posts 01ABC123 --raw建议使用 raw mode 的场景需要对 PT 结构做精确控制正在处理自定义块类型需要在条目之间原样复制 PT不做任何变换。注意--raw只作用于get且从源码看当存在待发布草稿且未加--published时get会用compare接口把草稿数据叠加到返回结果上并重新应用 PT→Markdown 转换除非--rawcontent.ts。1.5 写入内容的字段检查创建或更新内容时每个字段都会按如下规则检查portableText字段 字符串值→ 写入前把 Markdown 转换为 PTportableText字段 数组值→ 视为原始 PT直接发送、不做转换其他任何字段类型→ 原样发送。# Markdown 字符串 —— 自动转换为 PT npx emdash content create posts --data {title: Hello, body: # Welcome\n\nThis is **bold**.} # 原始 PT 数组 —— 原样透传 npx emdash content create posts --data {title: Hello, body: [{_type: block, children: [{_type: span, text: Welcome}]}]}二、Auto-Publishing为 Agent 设计的读写一致性EmDash CLI 的设计初衷是服务于自动化 Agentcreate与update默认自动发布让 Agent 获得读写后一致性read-after-write consistency无需自己管理草稿/发布生命周期。2.1 各命令的自动发布行为create—— 创建条目后立即发布返回的条目处于published状态。源码实现是client.create之后若未传--draft随即调用client.publish再重新get一次返回当前状态content.tsupdate—— 更新条目。如果集合启用了 revisions 且更新产生了草稿修订draft revision则自动发布以将草稿提升到内容表返回的条目反映更新后的数据。源码中的条件是if (!args.draft updated.draftRevisionId)——只有真的产生了草稿修订才发布未启用修订的集合不会多做一次无谓发布content.tsget—— 返回最新状态。如果存在待发布草稿例如有人在后台管理界面编辑过但未发布则返回草稿数据而不是已发布数据加--published可只看已发布数据。使用--draft可以跳过自动发布# 创建后保留为草稿 npx emdash content create posts --draft --data {title: Draft post, body: ...} # 更新后保留为草稿 npx emdash content update posts 01ABC123 --rev MToyMDI2... --draft --data {title: Draft update}2.2 为什么要自动发布EmDash 集合可以支持草稿修订draft revisions。一旦启用update写入的是草稿修订而非内容表。如果没有自动发布Agent 更新完条目后紧接着get看到的将是陈旧的已发布数据——自己刚刚做的修改消失了。自动发布从根本上消除了这种读写不一致的困惑。需要注意的是草稿修订的底层机制对 Agent 是透明的无论集合是否使用 revisionsAgent 都不需要感知差异CLI 会自动处理SKILL.md。三、Read-Before-Write_rev令牌与乐观并发控制更新操作使用_rev令牌实现乐观并发控制optimistic concurrency——原理与文件编辑工具要求你先读文件才能编辑完全相同你必须先看到你要覆盖的内容。3.1 类比像编辑文件一样编辑内容可以把这想象成文件系统编辑工具你读取文件看到当前内容你决定要改什么你写入并带上你读到的版本引用。如果在你读取和写入之间别人修改了文件写入就会失败——你不能覆盖自己没见过的更改。_rev令牌就是你已见过当前状态的证明。3.2 工作机制content get返回条目输出中带有_rev令牌把该_rev通过--rev传给content update服务端校验如果条目自你读取后发生过变化返回409 Conflict更新成功后会返回一个新的_rev供后续编辑使用。3.3_rev令牌是什么一段不透明的 base64 字符串。不要解析它原样回传即可。它在源码中的角色是client.update(collection, id, { data, _rev: args.rev, ... })的入参content.ts。3.4 CLI 工作流CLI 在update命令上强制要求--rev参数声明为required: true描述为Revision token from get (prevents overwriting unseen changes)见 content.ts。典型流程# 1. 读取条目 —— 记下输出中的 _rev npx emdash content get posts 01ABC123 # 输出包含: _rev: MToyMDI2LTAyLTE0... # 2. 用收到的 _rev 更新 —— 默认自动发布 npx emdash content update posts 01ABC123 \ --rev MToyMDI2LTAyLTE0... \ --data {title: New Title} # 输出显示更新后的条目及新的 _rev如果你尝试不带--rev更新CLI 会直接拒绝该命令。这确保你永远清楚自己在覆盖什么。3.5 冲突处理如果在读取与写入之间条目被他人更新你会看到EmDashApiError: Content has been modified since last read (version conflict) status: 409 code: CONFLICT解决方式用get重新读取检查新状态然后用新的_rev再次update。相关错误码定义在 errors.ts 中CONFLICT与ENTRY_LOCKED共同出现在 mutation 冲突 schema 的code示例里schemas/entry-lock.ts。四、Locked EntriesENTRY_LOCKED与--override-lock收到 409 并不总是意味着内容被修改。如果有人在后台打开了该条目编辑锁定开启时写入会被拒绝并返回不同的错误码EmDashApiError: Ada is holding this entry status: 409 code: ENTRY_LOCKED重新读取无法解决这个错误——条目本身没有变化所以拿到的新_rev依然会被拒绝。重试前务必先检查code。两种处理方式等待编辑者关闭条目后锁即释放强制写入加--override-lock参数忽略锁继续写。4.1 锁的生命周期编辑者关闭条目时释放锁崩溃标签页遗留的锁在最后一次心跳后 7 分钟自动过期。这个常量在服务端源码中有明确定义ENTRY_LOCK_LEASE_MS 7 * 60 * 1000注释说明足够长以扛过打字停顿足够短以让关闭的标签页在喝杯咖啡的工夫内释放条目handlers/entry-lock.ts。4.2 覆盖锁的注意事项覆盖写入不会拿走锁。编辑者仍然持有它因此他下一次保存会被当作版本冲突拒绝。所以除非你确定对方已经离开否则请等待。4.3--override-lock的适用范围--override-lock被以下命令接受content update、content delete、content publish、content unpublish和content schedule。从 content.ts 可以看到这五个子命令都声明了该布尔参数并透传到对应的客户端方法。反之关闭了编辑锁定的集合永远不会返回ENTRY_LOCKED——锁的启用与否由集合的edit_locking字段控制handlers/entry-lock.ts。五、哪些操作需要_rev只有update需要。其余操作要么幂等、要么非破坏性Command--rev需要原因content create否尚不存在任何内容content update是覆盖已存在的数据content delete否软删除可恢复content publish否幂等的状态变更content unpublish否幂等的状态变更content schedule否只修改元数据content restore否从回收站恢复六、在脚本与 CI 中的实战组合结合 SKILL.md 的补充能力可以把上述编辑流程编排成可靠的自动化脚本。6.1 用--json输出驱动脚本所有远程命令都支持--json机器可读输出stdout 被管道接管时自动启用# 读取后用 jq 提取 _rev 再更新 REV$(npx emdash content get posts 01ABC123 --json | jq -r ._rev) npx emdash content update posts 01ABC123 --rev $REV \ --data {title: Scripted title} --json # 创建后立即拿到 id 继续后续操作 ID$(npx emdash content create posts --data {title:Hello} --json | jq -r .id)6.2 冲突重试模式在并发环境下多个 Agent 或人机协作更新前先读取、冲突后重读重试# 简化示例失败后重新读取最新状态 npx emdash content get posts 01ABC123 --json state.json REV$(jq -r ._rev state.json) npx emdash content update posts 01ABC123 --rev $REV --data {title:v2} \ || { echo 409 conflict — re-read and retry; }6.3 判断 409 的错误码再决定策略脚本中遇到 409 时务必区分codeCONFLICT→ 重读、取新_rev、重试ENTRY_LOCKED→ 重读没用需等待锁过期最多约 7 分钟或携带--override-lock强制写入。七、小结EmDash CLI 的编辑流程围绕三个设计支柱展开schema 感知的 Portable Text ↔ Markdown 双向转换含--raw原样模式与 opaque fence 无损保真、面向 Agent 的自动发布配合--draft保留草稿、以_rev为核心的读-写前校验配合ENTRY_LOCKED编辑锁与--override-lock强制写入。这些机制让脚本化、Agent 化的内容编辑既保持了对富文本结构的完整控制又通过乐观并发避免了覆盖未见过更改的数据丢失风险。想深入底层实现可以继续阅读转换层完整实现portable-text.tsCLIcontent子命令全部参数与自动发布逻辑content.ts编辑锁的服务端租期与 holder 逻辑handlers/entry-lock.ts编辑锁相关 schema 与错误结构schemas/entry-lock.ts编辑锁集成测试entry-lock.test.tsCLI 完整命令参考与认证方式SKILL.md赞分享CMS后端前端插件系统【免费下载链接】emdashEmDash is a full-stack TypeScript CMS based on Astro; the spiritual successor to WordPress项目地址https://gitcode.com/gh_mirrors/emdas/emdash点击查看免费下载相关推荐EmDash CLI 内容编辑流程详解Portable Text 转换、_rev 乐观并发与自动发布机制EmDash CLI 内容编辑流程详解Portable Text 转换、 _rev 乐观并发与自动发布机制 本文围绕 EmDash 仓库中 EDITING FCMS后端前端插件系统EmDash CLI 内容编辑流程全解Portable Text 转换、_rev 乐观并发与自动发布机制EmDash CLI 内容编辑流程全解Portable Text 转换、 _rev 乐观并发与自动发布机制 EmDash 是一个基于 Astro 的全栈 TyCMS后端前端插件系统EmDash CLI 内容编辑流程完全指南Portable Text 转换、_rev 乐观并发与自动发布机制EmDash CLI 内容编辑流程完全指南Portable Text 转换、 _rev 乐观并发与自动发布机制 本文以 EmDash 仓库中 EDITINGCMS后端前端插件系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
机械工程控制基础课件制作:从传递函数到仿真配图的完整路径 简介:这是一份面向机械工程及相关专业学生和初学者的《机械工程控制基础》课程PPT,源自三峡大学机械与材料学院方子帆教授的课堂讲义,聚焦控制理论的基本概念、系统工作原理与组成,并通过恒温箱温度控制、钢铁轧制等案例讲解自动控… · 2026/9/23 22:09:58
美赛特等奖论文的建模思维解剖与工程化复用 简介:本资源为2021年美国大学生数学建模竞赛(MCM)特等奖论文合辑,面向数学建模参赛者、高校理工科学生及科研入门者,提供高水准建模思路、跨学科方法融合与完整赛题解决方案的权威范本。合辑以一篇聚焦真菌分解过程的特… · 2026/9/23 22:09:52
ChatBI+Agent实战:从NL2SQL到六层架构与落地评测 简介:《2024 ChatBI与智能体实战手册(八大案例,共一百三十四页)》是一份面向数据分析、大模型应用和商业智能从业者的实战资料,汇集平安人寿、滴滴、喜马拉雅、腾讯、快手、阿里巴巴、网易等多个企业团队的落地实践&am… · 2026/9/23 22:41:35
欧盟车牌图像数据集VOC格式解析:从VOTT标注到YOLO训练的完整流程 简介:这份资源是面向计算机视觉入门及进阶学习者的欧盟车牌图像数据集,包含534张真实行车场景下的车辆图片,均使用VOTT工具完成标注并输出VOC格式的XML标签文件,适用于目标检测、车牌识别、OCR等模型的训练与效果验证。数据采集覆… · 2026/9/23 22:41:34
药品板蓝根颗粒检测数据集110张VOC+YOLO格式:小样本目标检测实践指南 简介:面向目标检测入门与药品包装识别场景的板蓝根颗粒检测数据集,提供了111张袋装药品实拍图,并已按Pascal VOC与YOLO双格式完成标注。包内共335个文件,以jpg原图、xml标注和txt标注为主,其中111张图片对应111个xml文… · 2026/9/23 22:41:28
MMSE均衡原理与FPGA工程落地实战指南 简介:本资源是一份面向通信工程与数字信号处理初学者的MATLAB实践教学材料,聚焦多径信道下符号间干扰(ISI)的抑制问题,系统实现最小均方差(MMSE)均衡算法。资源包含2个核心MATLAB脚本文件&#… · 2026/9/23 22:41:28
基于PyQt5与OpenPose的姿态识别可视化:从骨架提取到关节角度分析 简介:基于PyQt5与OpenPose实现的太极拳姿态识别可视化系统,是一份完整可运行的毕业设计项目源码包,面向计算机相关专业正在准备毕设、课程设计或期末大作业的学生,也适合需要项目实战练习的Python学习者,可作为课程模板… · 2026/9/23 22:41:28
IEEE802.15.3a UWB信道模型:从参数解析到链路仿真避坑指南 简介:这份资源面向超宽带(UWB)通信方向的研究生、工程师与仿真开发者,聚焦IEEE 802.15.3a标准下的信道建模与冲击响应分析,帮助读者理解多径环境中的信号传播规律,为系统仿真、均衡同步与解调算法设计提供参… · 2026/9/23 22:41:22
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29