Rich-Text Lanjutan
Selain markdown dasar (bold, italic, link, list, blockquote, semuanya otomatis dirender lewat <TinaMarkdown>), nuxt-tina juga support diagram Mermaid di field rich-text.
Diagram Mermaid
Tambahin 'mermaid' ke toolbar field rich-text-nya:
{
type: 'rich-text',
name: 'body',
isBody: true,
overrides: {
toolbar: ['heading', 'link', 'bold', 'italic', 'mermaid', 'codeBlock', /* ... */],
},
}
TinaMarkdown nggak render diagram Mermaid secara default. mermaid itu dependency yang gede, jadi sifatnya opt-in:
npm install mermaid
<TinaMarkdown :content="post.body" :components="{ 'tina-mermaid': TinaMermaid }" />
TinaMermaid udah auto-import sama module-nya, jadi nggak perlu import manual. Kalau prop components-nya udah disambungkan, code block mermaid dirender jadi diagram SVG lewat mermaid.render() (di-import secara dinamis cuma pas diagramnya beneran ke-mount, jadi nggak nambah bundle kalau nggak dipakai). Tanpa prop itu, code block mermaid cuma dirender sebagai kode biasa.
Custom template
Field rich-text bisa punya template sendiri (syntax {{ shortcode }} Tina atau embed ala MDX):
{
type: 'rich-text',
name: 'body',
isBody: true,
templates: [
{
name: 'callout',
label: 'Callout',
match: { start: '{{', end: '}}' },
fields: [
{ name: '_value', type: 'string', label: 'Text', required: true },
],
},
],
}
nuxt-tina nggak nyediain komponen buat custom template tertentu: semuanya dirender lewat <TinaMarkdown> sebagai wrapper generic: <div data-tina-type="callout">...</div>. Style atau target-in pakai attribute itu di CSS kamu sendiri. Beda sama Mermaid, sekarang belum ada hook prop components buat nukar custom template tertentu jadi komponen Vue kamu sendiri: nambahin coverage itu masih di roadmap, ditrack di source adapter-nya sendiri (comark-adapter.ts).
⚠️ Gotcha: template nggak keparse kalau format: 'md'
Collection dengan format: 'md' otomatis dapat parser: { type: 'markdown' } di field rich-text-nya, dan mode parser itu sama sekali ngeskip logic template-matching (templates[].match) di dalam @tinacms/mdx. Tanpa override, {{ callout "..." }} cuma jadi teks biasa, bukan node yang keparse.
Fix-nya: override parser field-nya secara eksplisit:
{
type: 'rich-text',
name: 'body',
isBody: true,
parser: {
type: 'mdx', // paksa lewat jalur yang beneran preprocess template
},
templates: [ /* ... */ ],
}
Ini berlaku buat shortcode custom ({{ }}) maupun embed MDX ala JSX yang beneran (<Cta ... />).
Bentuk custom template di AST
Kalau kamu mau bikin render adapter sendiri, node custom template muncul di AST kayak gini:
{
"type": "mdxJsxFlowElement",
"name": "callout",
"props": { "_value": "Ini contoh callout." },
"children": [{ "type": "text", "text": "" }]
}
comark-adapter.ts udah nangani shape ini: lihat case mdxJsxFlowElement/mdxJsxTextElement di file itu buat contoh pattern-nya kalau kamu mau extend.