Sérialisation
9 min
le modèle de données de slate a été conçu en pensant à la sérialisation plus précisément, ses nœuds de texte sont définis de manière à être plus faciles à lire d’un coup d’œil, mais aussi faciles à sérialiser vers des formats courants comme html et markdown et, comme slate utilise du simple json pour ses données, vous pouvez écrire très facilement une logique de sérialisation texte brut par exemple, en prenant la valeur d’un éditeur et en renvoyant du texte brut import { node } from 'slate' const serialize = nodes => { return nodes map(n => node string(n)) join('\n') } ici, nous prenons les nœuds enfants d’un éditeur en tant qu’argument nœuds , et nous renvoyons une représentation en texte brut où chaque nœud de premier niveau est séparé par un seul caractère de nouvelle ligne pour une entrée de const nodes = \[ { type 'paragraph', children \[{ text 'an opening paragraph ' }], }, { type 'quote', children \[{ text 'a wise quote ' }], }, { type 'paragraph', children \[{ text 'a closing paragraph!' }], }, ] vous obtiendriez an opening paragraph a wise quote a closing paragraph! notez que le bloc de citation n’est distinguable d’aucune manière, car nous parlons de texte brut mais vous pouvez sérialiser les données vers tout ce que vous voulez — après tout, ce n’est que du json html par exemple, voici une fonction sérialiser similaire pour html import escapehtml from 'escape html' import { text } from 'slate' const serialize = node => { if (text istext(node)) { let string = escapehtml(node text) if (node bold) { string = `\<strong>${string}\</strong>` } return string } const children = node children map(n => serialize(n)) join('') switch (node type) { case 'quote' return `\<blockquote>\<p>${children}\</p>\</blockquote>` case 'paragraph' return `\<p>${children}\</p>` case 'link' return `\<a href="${escapehtml(node url)}">${children}\</a>` default return children } } celle ci est un peu plus avancée que la sérialisation en texte brut ci dessus elle est en fait récursive afin de pouvoir continuer à itérer plus profondément dans les enfants d’un nœud jusqu’à atteindre les nœuds de texte feuilles et pour chaque nœud reçu, elle le convertit en une chaîne html elle prend également un seul nœud en entrée au lieu d’un tableau, donc si vous passez un éditeur comme const editor = { children \[ { type 'paragraph', children \[ { text 'an opening paragraph with a ' }, { type 'link', url 'https //example com', children \[{ text 'link' }], }, { text ' in it ' }, ], }, { type 'quote', children \[{ text 'a wise quote ' }], }, { type 'paragraph', children \[{ text 'a closing paragraph!' }], }, ], // `editor` objects also have other properties that are omitted here } vous obtiendriez (sauts de ligne ajoutés pour la lisibilité) \<p>an opening paragraph with a \<a href="https //example com">link\</a> in it \</p> \<blockquote>\<p>a wise quote \</p>\</blockquote> \<p>a closing paragraph!\</p> c’est vraiment aussi simple ! désérialisation un autre cas d’usage courant dans slate est de faire l’inverse — désérialiser cela se produit lorsque vous avez une entrée arbitraire et que vous voulez la convertir en une structure json compatible avec slate par exemple, lorsque quelqu’un colle du html dans votre éditeur et que vous voulez vous assurer qu’il est analysé avec le bon formatage pour votre éditeur slate possède un utilitaire intégré pour cela le paquet slate hyperscript la manière la plus courante d’utiliser slate hyperscript est pour écrire des documents jsx, par exemple lors de l’écriture de tests vous pourriez l’utiliser ainsi / @jsx jsx / import { jsx } from 'slate hyperscript' const input = ( \<fragment> \<element type="paragraph">a line of text \</element> \</fragment> ) et la fonctionnalité jsx de votre compilateur (babel, typescript, etc ) transformerait cette variable entrée en const input = \[ { type 'paragraph', children \[{ text 'a line of text ' }], }, ] c’est idéal pour les cas de test, ou les situations où vous voulez pouvoir écrire de nombreux objets slate sous une forme très lisible cependant ! cela n’aide pas pour la désérialisation mais slate hyperscript n’est pas seulement destiné à jsx c’est simplement un moyen de construire des arbres de contenu slate ce qui est exactement ce que vous voulez faire lorsque vous désérialisez quelque chose comme du html par exemple, voici une fonction désérialiser pour html import { jsx } from 'slate hyperscript' const deserialize = (el, markattributes = {}) => { if (el nodetype === node text node) { return jsx('text', markattributes, el textcontent) } else if (el nodetype !== node element node) { return null } const nodeattributes = { markattributes } // define attibutes for text nodes switch (el nodename) { case 'strong' nodeattributes bold = true } const children = array from(el childnodes) map(node => deserialize(el, nodeattributes)) flat() if (children length === 0) { children push(jsx('text', nodeattributes, '')) } switch (el nodename) { case 'body' return jsx('fragment', {}, children) case 'br' return '\n' case 'blockquote' return jsx('element', { type 'quote' }, children) case 'p' return jsx('element', { type 'paragraph' }, children) case 'a' return jsx( 'element', { type 'link', url el getattribute('href') }, children ) default return children } } il prend un objet d’élément html el et renvoie un fragment slate donc si vous avez une chaîne html, vous pouvez l’analyser et la désérialiser comme suit const html = ' ' const document = new domparser() parsefromstring(html, 'text/html') deserialize(document body) avec cette entrée \<p>an opening paragraph with a \<a href="https //example com">link\</a> in it \</p> \<blockquote>\<p>a wise quote \</p>\</blockquote> \<p>a closing paragraph!\</p> vous obtiendrez cette sortie const fragment = \[ { type 'paragraph', children \[ { text 'an opening paragraph with a ' }, { type 'link', url 'https //example com', children \[{ text 'link' }], }, { text ' in it ' }, ], }, { type 'quote', children \[ { type 'paragraph', children \[{ text 'a wise quote ' }], }, ], }, { type 'paragraph', children \[{ text 'a closing paragraph!' }], }, ] et tout comme la fonction de sérialisation, vous pouvez l’étendre pour l’adapter aux besoins exacts de votre modèle de domaine