tiptap/docs/src/docPages/guide/store-content.md

123 lines
4.9 KiB
Markdown
Raw Normal View History

2020-09-22 22:03:31 +08:00
# Store content
## toc
## Introduction
You can store your content as a JSON object or as a good old HTML string. Both work fine. And of course, you can pass both formats to the editor to restore your content. Here is an interactive example, that exports the content as HTML and JSON when the document is changed:
2020-08-12 18:16:58 +08:00
2020-11-30 22:58:05 +08:00
## Export
2020-08-12 18:16:58 +08:00
2020-11-30 22:58:05 +08:00
### Option 1: JSON
2020-09-22 22:03:31 +08:00
JSON is probably easier to loop through, for example to look for a mention and its more like what tiptap uses under the hood. Anyway, if you want to use JSON to store the content we provide a method to retrieve the content as JSON:
2020-08-12 18:16:58 +08:00
2020-09-16 23:01:47 +08:00
```js
const json = editor.getJSON()
2020-09-16 23:01:47 +08:00
```
2020-09-22 22:03:31 +08:00
You can store that in your database (or send it to an API) and restore the document initially like that:
2020-09-16 23:01:47 +08:00
```js
new Editor({
content: {
"type": "document",
"content": [
2020-11-30 22:58:05 +08:00
// …
2020-09-16 23:01:47 +08:00
]
},
})
```
Or if you need to wait for something, you can do it later through the editor instance:
```js
editor.setContent({
"type": "document",
"content": [
2020-11-30 22:58:05 +08:00
// …
2020-09-16 23:01:47 +08:00
]
})
```
2020-11-30 22:58:05 +08:00
Here is an interactive example where you can see that in action:
<demo name="Guide/StoreContent/ExportJSON" :show-source="false"/>
### Option 2: HTML
2020-09-16 23:01:47 +08:00
HTML can be easily rendered in other places, for example in emails and its wildly used, so its probably easier to switch the editor at some point. Anyway, every editor instance provides a method to get HTML from the current document:
```js
const html = editor.getHTML()
2020-09-16 23:01:47 +08:00
```
This can then be used to restore the document initially:
```js
new Editor({
content: `<p>Example Text</p>`,
})
```
Or if you want to restore the content later (e. g. after an API call has finished), you can do that too:
```js
2020-11-13 18:52:02 +08:00
editor.commands.setContent(`<p>Example Text</p>`)
2020-09-16 23:01:47 +08:00
```
2020-11-30 22:58:05 +08:00
Use this interactive example to fiddle around:
<demo name="Guide/StoreContent/ExportHTML" :show-source="false"/>
### Not an option: Markdown
2020-11-17 22:38:46 +08:00
Unfortunately, **tiptap doesnt support Markdown as an input or output format**. We considered to add support for it, but those are the reasons why we decided to not do it:
2020-08-12 18:16:58 +08:00
2020-11-17 22:38:46 +08:00
* Both, HTML and JSON, can have deeply nested structures, Markdown is flat.
* There are enough packages to convert HTML to Markdown and vice-versa.
* Markdown standards vary.
2021-01-21 19:35:06 +08:00
* tiptaps strength is cutomization, that doesnt work very well with Markdown
2020-08-12 18:16:58 +08:00
2020-09-22 22:03:31 +08:00
You should really consider to work with HTML or JSON to store your content, they are perfectly fine for most use cases.
2021-01-21 19:35:06 +08:00
If you still think you need Markdown, ProseMirror has an [example on how to deal with Markdown](https://prosemirror.net/examples/markdown/), [Nextcloud Text](https://github.com/nextcloud/text) uses tiptap 1 to work with Markdown. Maybe you can learn from them. Or if youre looking for a really good Markdown editor, try [CodeMirror](https://codemirror.net/).
2020-09-22 22:03:31 +08:00
2021-01-21 19:35:06 +08:00
That said, tiptap does support [Markdown shortcuts](/examples/markdown-shortcuts) to format your content. Also youre free to let your content look like Markdown, for example add a `#` before an `<h1>` with CSS.
2020-11-05 21:39:28 +08:00
2020-12-15 06:29:57 +08:00
## Listening for changes
If you want to continuously store the updated content while people write, you can [hook into events](/api/events). Here is an example how that could look like:
```js
const editor = new Editor({
// intial content
content: `<p>Example Content</p>`,
// triggered on every change
onUpdate() {
const json = this.getJSON()
// send the content to an API here
},
})
```
2020-11-30 22:58:05 +08:00
## Rendering
### Option 1: Read-only instance of tiptap
To render the saved content, set the editor to read-only. Thats how you can achieve the exact same rendering as its in the editor, without duplicating your CSS and other code.
<demo name="Guide/StoreContent/ReadOnly" highlight="3-6,22,28,41-47" />
### Option 2: Generate HTML from ProseMirror JSON
If you need to render the content on the server side, for example to generate the HTML for a blog post which has been written in tiptap, youll probably want to do just that without an actual editor instance.
2020-11-05 21:39:28 +08:00
2020-11-30 22:58:05 +08:00
Thats what the `generateHTML()` is for. Its a helper function which renders HTML without an actual editor instance.
2020-11-05 21:39:28 +08:00
:::info Browser-only rendering
2020-11-17 22:38:46 +08:00
Import a lightweight implementation of `generateHTML()` from `@tiptap/core` if youre using the function in a browser context only.
2020-11-05 21:39:28 +08:00
:::
2020-11-17 22:38:46 +08:00
<demo name="Api/Schema/GenerateHTML" highlight="6,43-48"/>
2021-01-21 19:35:06 +08:00
## Migration
If youre migrating existing content to tiptap we would recommend to get your existing output to HTML. Thats probably the best format to get your initial content into tiptap, because ProseMirror ensures there is nothing wrong with it. Even if there are some tags or attributes that arent allowed (based on your configuration), tiptap just throws them away quietly.
Were about to go through a few cases to help with that, for example we provide a PHP package to convert HTML to a compatible JSON structure: [ueberdosis/prosemirror-to-html](https://github.com/ueberdosis/html-to-prosemirror).
Share your experiences with us! Wed like to add more information here.