Qué son los schemas en Prosemirror, cómo configurar el schema al crear un nuevo editor. Cómo podemos usar packages adicionales para poder implementar schemas de uso común en editores personalizados.
Los schemas en ProseMirror nos sirven para indicar los tipos de nodos que se podrían encontrar en los documentos editables y sus propiedades disponibles. Por ejemplo si habrá párrafos, listas, tablas o cómo se podrán anidar unos nodos en otros, qué tipo de bloques podremos encontrar dentro de los nodos y que marcas podrían aceptar (como negritas o itálicas).
Además, en los schemas también se define algo muy importante que es la manera en la que los distintos nodos se van a renderizar una vez realicemos el paso de serialización del contenido del editor.
Hasta el momento en el Manual de ProseMirror hemos usado siempre un paquete de schema básico que nos ha servido para evitar tener que escribirlo por nosotros mismos y evitar algunas de las complejidades de la definición de los esquemas. Sin embargo, una de las principales ventajas y posibilidades de ProseMirror es que somos capaces de personalizar al máximo los editores, por lo que nosotros podemos crear cualquier tipo de schema personalizado con las utilidades que sean necesarias para nuestros casos particulares.
En este artículo vamos a abordar los schemas de una manera más detallada y ofrecer soluciones a necesidades comunes.
Cómo definir un schema
Un schema es una instancia de la clase Schema
y para definirlo necesitamos alimentar el constructor con un objeto que define los nodos y sus particularidades.
En la documentación de ProseMirror tenemos un primer ejemplo de schema para ver cómo se realizaría esa instanciación.
const miSchema = new Schema({
nodes: {
doc: {content: "paragraph+"},
paragraph: {content: "text*"},
text: {inline: true},
/* otras declaraciones del schema que consideres necesarias */
}
})
El schema lo usamos para diversas cosas cuando programamos un editor personalizado, pero el lugar más importante es en la definición del estado inicial del editor.
let state = EditorState.create({
miSchema,
});
La definición del schema se realiza mediante toda una cantidad de códigos, banderas y sub-definiciones que se pueden reutilizar. En realidad es una especie de lenguaje bastante sofisticado, por lo que requiere un estudio detallado. Nosotros no tenemos la intención de explicar todas las particularidades de creación de los schemas, porque preferimos que, si necesitas hacer tus propios schemas, consultes todos los detalles en la documentación de Schemas. En cambio, la idea de este artículo es ofrecer algunas ideas y sugerencias sobre schemas y cómo utilizar algunos que ya están realizados en packages de ProseMirror.
Schema básico
En los pasados artículos de este manual hemos usado siempre un schema básico que nos ofrece el paquete prosemirror-schema-basic
. Lo importamos siempre así:
import { schema } from "prosemirror-schema-basic";
La mayor carencia que habíamos detectado ya sobre este esquema es que no soportaba listas de elementos.
Schema de listas
En el caso que queramos que nuestros editores también sean capaces de usar listas, podemos usar el paquete prosemirror-schema-list
, el cual tiene una utilidad que justamente nos sirve para extender el schema básico.
Primero tendríamos que instalar en nuestro proyecto el package de npm prosemirror-schema-list
, con el siguiente comando:
npm i prosemirror-schema-list
Entendemos que a estas alturas, si has venido leyendo el Manual de ProseMirror tendrás ya instalados todos los otros packages que vamos a usar en este ejemplo.
A continuación debemos importar tanto el schema básico como el schema list
, además de la clase Schema
:
import { Schema } from "prosemirror-model"
import { schema } from "prosemirror-schema-basic"
import { addListNodes } from "prosemirror-schema-list"
Como puedes ver, del módulo prosemirror-schema-list
estamos importando solamente la utilidad addListNodes
que nos permite añadir los nodos de lista. El código para realizar esta operación es el siguiente:
const schemaExtendido = new Schema({
nodes: addListNodes(schema.spec.nodes, "paragraph block*", "block"),
marks: schema.spec.marks
});
Ahora podemos usar ese schemaExtendido
al realizar la creación del estado del editor, como hemos visto antes, o de la siguiente manera, en la que realizamos la especificación del schema a partir de la clase DOMParser
, que nos permitía inicializar el editor a partir del contenido de un elemento de la página.
let state = EditorState.create({
plugins: [
keymap(baseKeymap),
],
doc: DOMParser.fromSchema(schemaExtendido).parse(content)
});
Esta alternativa de inicialización la vimos en el artículo: Inicialización del contenido en el editor de texto con ProseMirror.
Gracias a estos cambios apreciaremos que ahora el editor soporta las listas de elementos, algo que casi siempre vamos a necesitar.
Esquema para Markdown
Si deseamos crear un editor de texto que permita obtener el código en el lenguaje Markdown. tenemos un schema disponible en el package prosemirror-markdown
.
Si lo necesitamos tendremos que instalarlo.
npm install prosemirror-markdown
Este paquete de npm contiene diversas utilidades para trabajar con editores de Markdown, a los cuales les vamos a prestar más atención en breve.
Luego vamos a importar el schema de esta manera:
import { schema } from "prosemirror-markdown"
Este schema ya soporta listas por lo que no tenemos que hacer el paso anterior para poder añadir los nodos de listas necesarios para trabajar con ellas. El uso del schema es igual que el que hemos visto en este artículo.
Recuerda que tenemos un repositorio con código de los ejemplos de ProseMirror que estamos utilizando para redactar este manual. En ellos encontrarás los códigos completos de personalización de los schemas en los archivos src/ejemplos/08-schema-list.html y src/ejemplos/09-schema-markdown.html.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...