ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

如何用 @tiptap/static-renderer 在不创建 Editor 实例的情况下渲染 Tiptap JSON 内容?

如何用 @tiptap/static-renderer 在不创建 Editor 实例的情况下渲染 Tiptap JSON 内容? 如何用 tiptap/static-renderer 在不创建 Editor 实例的情况下渲染 Tiptap JSON 内容【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap当你手里已经有一份 Tiptap JSON 文档JSONContent只想把它以只读形式展示成 HTML、转成 HTML 字符串或导出为 Markdown而不需要可编辑的编辑器时tiptap 的tiptap/static-renderer包可以直接完成这件事。它会根据你传入的扩展数组构建 ProseMirror schema并逐个执行扩展的renderHTML方法整个过程中不会实例化Editor。本文按安装依赖 → 准备入参 → 选择渲染目标 → 定制渲染 → 处理已知限制的顺序给出可执行的路径。准备条件安装与依赖包名为tiptap/static-renderer仓库中 package.json 记录的当前版本为3.30.3描述为 statically render Tiptap JSON。按 npm 常规方式安装npm install tiptap/static-rendererpeerDependencies 声明了tiptap/core、tiptap/pm需要与 tiptap 其他包同版本以及react/react-dom^17.0.0 || ^18.0.0 || ^19.0.0。注意区分渲染目标只用renderToHTMLString/renderToMarkdown时实际依赖就是tiptap/core和tiptap/pm见 html-string.ts 的 import。要用renderToReactElement则额外需要 React 17/18/19 环境。该包的exports提供主入口和子路径两种用法主入口tiptap/static-renderer同时导出 HTML 字符串、React、Markdown 三个方向的函数见 src/index.ts也可以按子路径单独引入如tiptap/static-renderer/pm/html-string、tiptap/static-renderer/pm/react、tiptap/static-renderer/pm/markdown以及对应的./json/*入口。仓库文档和示例中两种写法都有出现README 使用子路径演示代码 使用主入口。第一步准备content与extensions两个必需入参三个渲染函数renderToHTMLString、renderToReactElement、renderToMarkdown的签名一致核心入参只有两个contentNode | JSONContent。最常见的来源是编辑器实例的editor.getJSON()仓库演示就是在onUpdate回调里setJSON(editor.getJSON())也可以是直接存储的 JSON 文档形如{ type: doc, content: [ { type: heading, attrs: { level: 2 }, content: [{ type: text, text: Hi there, }] }, { type: paragraph, content: [ { type: text, text: this is a }, { type: text, marks: [{ type: bold }], text: Tiptap } ] } ] }extensions构建内容时使用的同一组扩展演示中使用const extensions [StarterKit]。渲染器依据这组扩展生成 schema再按每个 Node/Mark 的renderHTML输出对应结构。JSON 中出现的节点/标记类型必须在这组扩展里能解析出来否则后续会走到unhandledNode/unhandledMark回退逻辑或直接报错。第二步选择渲染目标并执行import type { JSONContent } from tiptap/core import StarterKit from tiptap/starter-kit import { renderToHTMLString, renderToReactElement, renderToMarkdown, } from tiptap/static-renderer const extensions [StarterKit] const doc: JSONContent { /* 上面示例的 doc JSON例如 editor.getJSON() 的结果 */ } // 1. 渲染为 HTML 字符串 const html: string renderToHTMLString({ content: doc, extensions }) // 2. 渲染为 React 元素 const element renderToReactElement({ content: doc, extensions }) // 3. 渲染为 Markdown 字符串 const markdown: string renderToMarkdown({ content: doc, extensions })把 HTML 字符串放进 DOM仓库演示的做法是直接交给dangerouslySetInnerHTMLdiv classNametiptap dangerouslySetInnerHTML{{ __html: renderToHTMLString({ content: doc, extensions }), }} /div三个函数的第三个参数staticEditorOptions是EditorOptions的一个窄子集目前只接受textDirection: ltr | rtl | auto源码注释明确说明这个对象刻意保持很窄只放不依赖Editor实例也能复现效果的选项const html renderToHTMLString({ content: doc, extensions, staticEditorOptions: { textDirection: auto }, })其他依赖运行时 view 或 transaction 流的编辑器选项不在支持范围内不要往staticEditorOptions里传。第三步替换单个节点/标记的渲染方式不想完全按扩展默认renderHTML输出时通过options.nodeMapping/options.markMapping按节点名、标记名替换渲染这是完全可控的定制点仓库演示的原始注释You have complete control over the rendering process. And can replace how each Node/Mark is rendered.const output renderToReactElement({ content: doc, extensions, options: { nodeMapping: { // 替换 heading 的渲染在这里可以正常使用 React hooks heading({ node, children }) { const [show, setShow] React.useState(false) return ( h1 {...node.attrs} onClick{() setShow(true)} {show ? 100% you can use React hooks! : Can you use React hooks? Click to find out!}{ } {children} /h1 ) }, }, }, })两个补充规则来自 extensionRenderer.ts 和 进阶演示Node views 在静态渲染器中不受支持。如果某节点在编辑端是用ReactNodeViewRenderer定义的静态渲染时你必须自己在nodeMapping里提供该组件需要渲染其富文本子内容时用tiptap/react的ReactNodeViewContentProvider包裹并传入content{children}。JSON 中出现 schema 里没有的类型时可以在options.unhandledNode/options.unhandledMark提供兜底渲染函数。渲染器会把未知类型换成内部占位类型继续转换走到兜底函数时再还原出原始的type与attrsnode.type.name、node.attrs、node.toJSON()均为原始值。没有提供兜底的未知类型会照常抛出错误。已知限制不跑 Editor 生命周期钩子这是使用静态渲染器前必须核对的一条README 的 Limitations workarounds 一节三个渲染函数的源码注释同样重复了该限制静态渲染器只构建 schema 并执行各扩展的renderHTML不会运行addProseMirrorPlugins、onCreate、onUpdate和任何 transaction 钩子。因此依赖这些机制写入属性的扩展——如UniqueIDdata-id和TableOfContentsid、data-toc-id——在静态渲染结果中不会自动生成这些属性。官方给出的处理方式是在渲染前预处理 JSONimport { generateUniqueIds } from tiptap/extension-unique-id import { generateTocIds } from tiptap/extension-table-of-contents import { renderToHTMLString } from tiptap/static-renderer/pm/html-string let doc sourceJson doc generateUniqueIds(doc, extensions) // 若使用 UniqueID doc generateTocIds(doc, extensions) // 若使用 TableOfContents const html renderToHTMLString({ content: doc, extensions, staticEditorOptions: { textDirection: auto }, // mirrors a subset of EditorOptions })另一条边界renderToMarkdown内置了 bulletList / orderedList / heading / codeBlock / blockquote / table 等节点的 Markdown 映射但源码注释明确说明 This is not a full implementation of a markdown renderer不要把它当作完整 Markdown 序列化方案。结果验证验证方式与文档中演示的用法一致StaticRendering 演示拿到同一份docJSON分别调用renderToHTMLString、renderToReactElement、renderToMarkdown。HTML 字符串返回值是一个string直接放入pre或打印即可看到由扩展renderHTML生成的标签结构例如示例内容中的标题、加粗、列表、代码块都会出现在字符串里。HTML 元素通过dangerouslySetInnerHTML注入后页面显示与编辑器中内容一致的只读排版。React 元素返回React.ReactNode渲染到页面上即可如果配置了nodeMapping页面上应出现你替换后的自定义结构。Markdown返回字符串中包含#标题、-/1.列表项、**bold**、代码块等语法。出错时的判断方法错误文案来自 html-string.ts 与 extensionRenderer.ts[tiptap error]: Node name cannot be rendered, it is missing a renderToHTML method...—— 该节点扩展没有renderHTML需要自行实现或在nodeMapping中提供对应渲染。[tiptap error]: Unsupported DomOutputSpec type, check the renderHTML method output or implement a node mapping—— 扩展renderHTML返回了渲染器无法处理的结构渲染器只处理字符串和DOMOutputSpecArray不支持直接返回 DOM 元素检查该扩展的renderHTML输出或改用 node mapping。参考文件packages/static-renderer/README.md限制、预处理方案与staticEditorOptions说明packages/static-renderer/src/pm/html-string/html-string.tsrenderToHTMLString实现packages/static-renderer/src/pm/react/react.tsrenderToReactElement实现packages/static-renderer/src/pm/extensionRenderer.tsschema 构建、nodeMapping/unhandledNode路由逻辑demos/src/Examples/StaticRendering/React/index.tsx同一份 JSON 的四种渲染演示demos/src/Examples/StaticRenderingAdvanced/React/index.tsxnodeMapping与 NodeView 组件的静态渲染替代写法【免费下载链接】tiptapThe headless rich text editor framework for web artisans.项目地址: https://gitcode.com/GitHub_Trending/ti/tiptap创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表