Recreación del bloque de inserción CodePen Gutenberg para Sanity.io

Índice
  1. Cómo poner en funcionamiento Sanity Studio localmente
  2. Agregar los esquemas para una inserción de CodePen
    1. Agregar el campo CodePen al editor de texto enriquecido
  3. Agregar la inserción de CodePen como vista previa
  4. Taking it further
  5. Conclusion

Chris lanzó recientemente un elegante bloque de inserción de CodePen para el editor Gutenberg en WordPress . Le permite incrustar un Pen simplemente ingresando su URL. Desde allí, obtienes acceso para controlar el tamaño, el tema y las pestañas predeterminadas que se muestran en la carga inicial. ¡Súper ordenado!

Pero me hizo pensar: ¿Qué tan difícil sería recrearlo con el editor de texto portátil de Sanity Studio ? (Spoiler: No es tan difícil). Como ya sabía cómo hacerlo, tardé menos de siete minutos de principio a fin. Este tutorial le explica cómo poner en marcha un estudio y cómo agregar los esquemas y el componente de vista previa personalizado para una inserción de CodePen.

Así que este soy yo recreando el bloque CodePen Gutenberg de @chriscoyier para el editor de texto enriquecido de @sanity_io en menos de 7 minutos (video 3x). Lo mejor es que en realidad simplemente almacena los datos estructurados, lo que los hace consultables, preparados para el futuro y fáciles de integrar con cualquier interfaz que prefiera. https://t.co/psPn6NtPjz pic.twitter.com/6aSGKerHfO

– knut (en SF ) (@kmelve) 18 de enero de 2020

Me sentí tan bien que quiero enseñarte cómo hacerlo también. Profundicemos en ello.

Cómo poner en funcionamiento Sanity Studio localmente

Primero, necesitarás instalar Sanity Studio localmente en tu máquina. En este tutorial usaremos el estudio de blog que puede iniciar desde la línea de comandos, pero también puede consultar los diferentes iniciadores en sanity.io/create . Deberías poder acompañar a uno de esos también.

Este tutorial asume que tienes un poco de conocimiento de JavaScript. Utilizará un poco de React, pero solo una pequeña parte. Deberías haber instalado node y npm si aún no lo has hecho.

Ah, y querrás la CLI de Sanity, que puedes activar con la línea de comando:

npm install --global @sanity/cli

Una vez finalizada la instalación, puede iniciar un nuevo Sanity Studio con un nuevo proyecto ejecutando el comando sanity init. Le permitirá iniciar sesión con su cuenta de Google o GitHub (o crear una nueva cuenta con un correo electrónico/contraseña). Dale un nombre a tu proyecto y sigue las instrucciones. Cuando se le presenten las opciones para una plantilla de proyecto, elija la de blog:

? Select project template  Movie project (schema + sample data)  E-commerce (schema + sample data)❯ Blog (schema)  Clean project with no predefined schemas

Después de completar los pasos, cambie el directorio ( cd) a la nueva carpeta del proyecto y ábralo en su editor de código favorito. Para iniciar el servidor de desarrollador que también recargará en caliente su estudio cuando realice cambios, ejecute sanity start. Para detener este servidor, presiona ctrl + Cen la mayoría de las herramientas de línea de comando.

Agregar los esquemas para una inserción de CodePen

Los esquemas definen qué tipos de documentos están disponibles en Studio y qué campos de entrada tienen. Estos esquemas se definen en objetos JavaScript que importa al schemas.jsarchivo, donde se exportan como una función que Studio traduce a su interfaz de usuario. Hay muchas cosas que puedes hacer con estos esquemas, pero en este tutorial lo mantendremos razonablemente simple.

Comience agregando un nuevo archivo dentro /yourproject/schemasllamado codepen.js. Luego escribe este código:

export default {  name: "codepen",  type: "object",  title: "CodePen Embed",  fields: [    {      name: "url",      type: "url",      title: "CodePen URL"    }  ]};

Luego puede ir /yourproject/schemas/schema.jsy agregarle las siguientes dos líneas de código:

import createSchema from "part:@sanity/base/schema-creator";import schemaTypes from "all:part:@sanity/base/schema-type";import blockContent from "./blockContent";import category from "./category";import post from "./post";import author from "./author";import codepen from "/codepen.js"; // = first import the objectexport default createSchema({  name: "default",  types: schemaTypes.concat([    post,    author,    category,    blockContent,    codepen // = add it to the schema types array  ])});  

Entonces, ¿qué acabamos de hacer? Bueno, ahora hemos hecho que este objeto CodePen esté disponible como typeen otros esquemas en Studio. En otras palabras, ahora puede agregar type: 'codepen'para obtener esos campos en cualquier otro lugar del código del esquema donde agrega campos. Agregar este tipo al campo de texto enriquecido también es nuestro siguiente paso. ¡Aférrate!

Agregar el campo CodePen al editor de texto enriquecido

Antes de profundizar en el código, demos un paso atrás y veamos lo que está sucediendo en términos de los formatos de datos con los que operamos y en qué se diferencian ligeramente WordPress y Sanity.

Si bien Gutenberg almacena texto enriquecido como JSON en su tiempo de ejecución (¡lo cual es genial!), lo que los desarrolladores terminan tratando es principalmente con este contenido como objetos HTML y JSON dentro de los comentarios HTML.

Sanity almacena y distribuye contenido de texto enriquecido como texto portátil , que luego los desarrolladores serializan en sus interfaces. Eso significa que obtienes un control detallado sobre cómo se representa el contenido de texto enriquecido al permitirte usar componentes personalizados para tu marco favorito, ya sea React , Vue , Svelte o .NET , PHP o incluso Markdown .

En otras palabras, almacena su contenido como datos estructurados en el backend de Sanity y luego decide cómo desea utilizar los datos dentro de los componentes de su frontend. Pero basta de exposición, ¡volvamos al código!

Abre /schemas/blockContent.jsy observa que es del tipo array. Sí, el texto enriquecido es una matriz de diferentes tipos, donde uno de ellos tiene que ser del blocktipo (en el que se almacenan los párrafos de texto). Entonces, la forma más sencilla de crear texto enriquecido es la siguiente definición de esquema:

export default {  name: "body",  type: "array",  title: "Body",  of: [    {      type: "block"    }  ]};

Ahora blockContent.jstiene muchas más cosas. Puedes ver styles, lists, marks, etc. Todo define qué propiedades deberían estar disponibles para el autor. En la matriz superior, hay dos tipos blocky image. Vamos a agregar el tercero codepen:

export default {  title: "Block Content",  name: "blockContent",  type: "array",  of: [    {      type: "block"      // ...    },    {      type: "image",      options: { hotspot: true }    },    {      type: "codepen"    }  ]};

Guarda el archivo y ¡listo! Si ahora ejecuta sanity startsu línea de comando (asumiendo que aún no lo ha hecho) y abre Studio en https://localhost:3333, debería poder encontrar su nuevo campo en el editor de texto enriquecido bajo el tipo “publicación”:

Si prueba el nuevo botón, obtendrá un modal con el campo URL que definió en la sección anterior. Siéntete libre de agregar la URL de un CodePen interesante que hayas encontrado. Usaremos este de la legendaria Sara Drasner; es genial.

Sin embargo, simplemente mostrar el valor de la URL en el editor no es especialmente inspirador. ¡Así que sigamos adelante y agreguemos la inserción de CodePen real para que podamos interactuar con él directamente en el editor!

Agregar la inserción de CodePen como vista previa

Abre /yourproject/schemas/codepen.jsde nuevo. Ahora vamos a crear un pequeño componente de React para nuestra vista previa. Comience importando React en la parte superior y el modelo estándar para el componente de React que convertiremos en el elemento insertado:

import React from "react";const CodePenPreview = ({ value }) = {  return pre{JSON.stringify(value, null, 2)}/pre;};export default {  name: "codepen",  type: "object",  title: "CodePen Embed",  fields: [    {      name: "url",      type: "url",      title: "CodePen URL"    }  ]};

Se JSON.stringifytrata de una pequeña forma temporal de generar los datos entrantes de forma legible. También puedes usar console.log(value), pero ¿quién tiene tiempo para abrir la consola de desarrollador?

Ahora debes decirle a Sanity cómo usar este componente para la vista previa. Además de cuál de los campos del objeto debería selectincluirse valueen el componente de vista previa.

import React from "react";const CodePenPreview = ({ value }) = {  return pre{JSON.stringify(value, null, 2)}/pre;};export default {  name: "codepen",  type: "object",  title: "CodePen Embed",  preview: {    select: {      url: "url"    },    component: CodePenPreview  },  fields: [    {      name: "url",      type: "url",      title: "CodePen URL"    }  ]};

El editor debería verse así después de guardar los cambios:

¡Fresco! Ahora queremos tomar el urlvalor e integrarlo de alguna manera con una inserción de CodePen. La forma más sencilla de hacerlo es ajustar el marcado para la inserción iFrame de CodePen y ajustarlo a nuestro componente de vista previa en React.

El elemento iFrame original se verá así:

iframe scrolling="no" src="https://codepen.io/sdras/embed/gWWQgb?height=265theme-id=darkdefault-tab=js,result" frameborder="no" allowtransparency="true" allowfullscreen="true"  See the Pen a href='https://codepen.io/sdras/pen/gWWQgb'React Animated Page Transitions/a by Sarah Drasner  (a href='https://codepen.io/sdras'@sdras/a) on a href='https://codepen.io'CodePen/a./iframe

Si pegamos este fragmento en nuestro componente de vista previa, casi funcionará. Para que sea compatible con JSX, deberá realizar algunos cambios en algunos de los atributos HTML. Asegúrate de cambiar:

  • style="width: 100%;"astyle={{width: "100%"}}
  • frameborder="no"aframeBorder="no"
  • allow-transparency="true"aallowTransparency
  • allow-fullscreen="true"aallowFullScreen

Puedes eliminar el contenido (enlaces, etc.) dentro del iframe, porque no es particularmente útil dentro del estudio. Lo que deberíamos terminar con algo como esto:

import React from "react";import Codepen from "react-codepen-embed";const CodePenPreview = ({ value }) = {  return (    iframe           style={{ width: '100%' }}      scrolling="no"           src="https://codepen.io/sdras/embed/gWWQgb?height=370theme-id=darkdefault-tab=js,result"      frameBorder="no"      allowTransparency      allowFullScreen    /);};// ...

Cuando lo guardemos, deberíamos poder ver la inserción de CodePen dentro del editor de texto enriquecido:

Observe que el iFrame tiene una URL para insertar con algunos parámetros sobre cómo debe mostrarse. Por supuesto, podríamos haberle pedido a alguien que se sumergiera en CodePen para obtener esta URL, pero probablemente sea mejor usar la normal. Haremos el esfuerzo de volver a ensamblar lo que necesitamos:

La última parte es tomar la URL del campo y sacar el hashy userde él.

We split the URL string on forward slashes into an array. Then we use array destructuring to assign the different array elements to a variable. Since we only need theuserand thehashwe leave the other positions empty. This method isn’t bulletproof, as it assumed a specific format for the URL, but it works for this example. Then we reassemble the embedUrl by using template literals.

import React from "react";const CodePenPreview = ({ value }) = {  const { url } = value;  if (!url) {    return (divAdd a CodePen URL/div)  }  const splitURL = url.split("/");  // [ 'https:', '', 'codepen.io', 'sdras', 'pen', 'gWWQgb' ]  const [, , , user, , hash] = splitURL;  const embedUrl = `https://codepen.io/${user}/embed/${hash}?height=370theme-id=darkdefault-tab=result`;  return (    iframe           style={{ width: '100%' }}      scrolling="no"           src={embedUrl}      frameBorder="no"      allowTransparency      allowFullScreen    /  );};// ...

Save the changes and voilá; we’re pretty much done with the custom CodePen block!

Taking it further

Now, you probably noticed that Chris had put more settings into his custom block. Nothing is stopping us from doing the same! If we look up the documentation for the React CodePen embed component that we installed, we’ll find a table of properties that it can take. We can add these as fields in the schema definition. For example, if we wanted to add thethemeId, we could do it as follows:

import React from "react";import Codepen from "react-codepen-embed";const CodePenPreview = ({ value }) = {  const { url, themeId = "dark" } = value; // = add themeId here, default it to "dark"  if (!url) {    return (divAdd a CodePen URL/div)  }  const splitURL = url.split("/");  // [ 'https:', '', 'codepen.io', 'sdras', 'pen', 'gWWQgb' ]  const [, , , user, , hash] = splitURL;  const embedUrl = `https://codepen.io/${user}/embed/${hash}?height=370theme-id=${themeId}default-tab=result`; // = add themeId here  return (    iframe           style={{ width: '100%' }}      scrolling="no"           src={embedUrl}      frameBorder="no"      allowTransparency      allowFullScreen    /  );};export default {  name: "codepen",  type: "object",  title: "CodePen Embed",  preview: {    select: {      url: "url",      themeId: "themeId" // = add themeId here    },    component: CodePenPreview  },  fields: [    {      name: "url",      type: "url",      title: "CodePen URL"    },    // Add the new field below    {      name: "themeId",      type: "string",      title: "Theme ID",      description: 'You can use "light" and "dark" also.'    }  ]};

Conclusion

We just looked at how schemas for Sanity Studio work, and learned how to make previews for custom components to boot! Hopefully, you now know enough to make pretty muchany custom component with a preview using these same principles. If you do, I would love to know about it either onTwitteror in the comments.

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion