hand Inicio

SERVICIOS

Salir

nochedía

Plugin para Gutenberg con React

2400 palabras
9 minutos
July 22, 2020

El desarrollo con React en WordPress es un poco lioso al tener que combinar dos entornos de trabajo en uno, pero una vez te acostumbras lo cierto es que la experiencia resulta muy agradable

Aquí vamos a verlo con un plugin para programar un bloque de Gutenberg

Prólogo

WordPress en su intento por sobrevivir y continuar con su hegemonía ha iniciado su transformación de php a React

De momento esta transformación se limita al frontend, pero la potencia que te da el poder desarrollar con React precisamente en el frontend es enorme

Cómo se hace? Cómo se integra un entorno de desarrollo React dentro de un entorno de desarrollo php?

Lo vemos en un contexto de crear un plugin para WordPress que nos defina un bloque de Gutenberg

Vamos allá

  1. Prólogo
  2. Preparando el entorno de trabajo
  3. Creando el plugin, parte php
  4. Creando el plugin, parte JS con NodeJS
  5. Desarrollando el bloque de Gutenberg
  6. Preparando el bloque Imgur
  7. Comentario

Preparando el entorno de trabajo

Entorno de trabajo

Por el lado de WP ya lo tenemos todo listo si hemos instalado WordPress en local (tienes el curso aquí)

Por el lado de React también lo tenemos todo listo si nos hemos pasado por el curso correspondiente (aquí)

Flujo de trabajo

Por flujo de trabajo me refiero a cómo funcionará un desarrollo de este tipo, porque al mezclar dos tecnologías es algo peculiar

  1. Lo primero es tener el servidor de WordPress funcionando

  2. Lo segundo es tener el entorno con NodeJS preparado, que estará también funcionando para que veamos los cambios en tiempo real

  3. Trabajaremos con php y este nos mostrará la aplicación React que a su vez estará compilada con WebPack

Más sencillo de lo que parece

Creando el plugin, parte php

Creando el plugin

Lo primero que tenemos que hacer es configurar un plugin en WP

Nada más sencillo

  • Si nos vamos a laragon y apretamos el botón ROOT se nos abrirá el explorador de archivos en la carpeta donde laragon almacena las instalaciones WP

  • Allí nos vamos a la carpeta /wp-content/plugins y creamos una carpeta que yo le diré kw-gutenberg-imgur y dentro un archivo php con el mismo nombre kw-gutenberg-imgur.php

Abrimos ese archivo con vscode y añadimos (cambia el texto a lo que te parezca)

Con esto ya tenemos el plugin configurado y si nos vamos al dashboard de WP ya lo veremos listado y listo para ser activado

Ahora simplemente vamos a incrustar nuestro JavaScript

Con add_action le decimos a WP que ejecute la función kw_gutenberg_imgur_enqueue cuando esté preparando la interfaz de Gutenberg, esto es, en el hook enqueue_block_editor_assets

Y la función nos inserta el script con wp_enqueue_script que nos pide un nombre único para el script y la ruta del script (la función plugins_url nos devuelve la ruta de los plugins de forma más cómoda)

Añadiendo React

Ahora ya tenemos nuestro JavaScript incrustado, pero React no nos aparece por ningún lado

Para que nos aparezca necesitamos añadirlo como dependencia en el archivo anterior

Le hemos añadido un array de dependencias que contiene wp-element, que no es más que React en versión WordPress

Ahora, si creamos el archivo kw-gutenberg-imgur.js ya tendremos la dependencia de React y ya podremos utilizarlo tan tranquilamente

Pero en lugar de hacerlo así, lo haremos con wp-scripts

Una de las ventajas de utilizar wp-scripts es que con el proceso de compilación también nos generará el archivo build/index.asset.php que nos indicará las dependencias y la versión de nuestra compilación

Esto, que puede parecer nimio, nos facilita la vida como verás en el código final

  • El nombre del archivo js ya no es kw-gutenberg-imgur.js sino build/index.js
  • Las dependencias ya no las ponemos de forma manual sino que nos vienen dadas (cortesía de wp-scripts)
  • Lo mismo con la versión, que nos permite solventar posibles problemas de caché

Con esto ya tenemos la parte php lista

Creando el plugin, parte JS con NodeJS

Ahora que ya tenemos el anclaje entre WP y React, vamos a seguir con React

Asumo que tienes el entorno de NodeJS preparado, lo tienes en este curso

Se trata de ir al directorio del plugin que en mi caso es kuworking/wp-content/plugins/kw-gutenberg-imgur y allí creo el archivo package.json con el siguiente contenido cambiando lo que te parezca

Con esto nos vamos con el terminal de vscode al directorio de trabajo (simplemente abriendo la carpeta del plugin con vscode) e instalamos wp-script

Y aprovechamos para instalar @emotion y toda una ristra de extensiones que nos vienen muy bien

Todos los paquetes los instalaremos en el entorno de desarrollo --dev excepto la librería @emotion, que la necesitaremos en la aplicación en sí

También verás que no estamos instalando React, esto es porque utilizaremos el que ya nos viene incluido en WordPress

Te comento algunos algunos extras que son opcionales, pero que muy posiblemente te serán de utilidad:

  • Si planeas subir el código en un repositorio, crea el archivo .gitignore y vuelca el siguiente contenido para evitar sincronizar estos archivos / carpetas
  • Y para vscode, aparte de las extensiones que ya tienes instaladas del curso del entorno de trabajo, añade las propias de php (aunque yo al menos aún no he conseguido tener un entorno satisfactorio al 100%)
  • Format HTML in PHP
  • PHP Debug
  • PHP Extension Pack
  • PHP Intelephense (y aquí en settings añade en stubs el stub wordpress)
  • PHP IntelliSense
  • PHP Sniffer & Beautifier

Desarrollando el bloque de Gutenberg

Una vez ya tenemos toda la infraestructura necesaria, ya podemos entrar en materia

Registrando el bloque

En el código de antes apuntábamos al archivo /build/index.js

Este archivo nos lo dará webpack a partir del archivo /src/index.js

Creamos la carpeta src y dentro de esta creamos el archivo /src/index.js y volcamos lo siguiente

Primero importamos registerBlockType que nos servirá para registrar un nuevo bloque en Gutenberg

Después importamos React.Fragment, pero en lugar de hacerlo desde react lo hacemos desde el react que WordPress nos ofrece (que a efectos prácticos es el mismo)

Y luego importamos el styled de @emotion, para poder utilizar styled-components de los que he hablado en cursos anteriores de Gatsby

Luego pasamos ya a la función para registrar el bloque registerBlockType, una función que nos pide 2 argumentos:

  • un nombre
  • un objeto

Para el nombre utiliza el nombre de tu plugin para evitar colisiones con otros plugins

Y en el objeto es donde hay la chicha, con las siguientes propiedades

  • title: el nombre de bloque
  • icon: puedo escoger entre unos básicos (que es lo que hago ahora para salir del paso) o utilizar un archivo aparte (que sería lo suyo)
  • category: te permite posicionar tu bloque en la categoría que quieras del editor Gutenberg
  • attributes: los datos de tu bloque, el estado que modificarás con el contenido que añada el usuario

Attributes

Esta propiedad es de las importantes

Aquí lo defino como un objeto que tiene asimismo la propiedad content, y esa propiedad (le podría haber puesto el nombre que quisiese) le digo que será sí o sí del type: 'string'

Lo que pongamos en attributes puede ser lo que he puesto arriba, que es simplemente definir contents y añadirle una validación que es opcional

O puede ser algo más sofisticado, como directamente guardar el contenido que se escriba en un elemento particular

Digo sofisticado porque esa gestión del contenido ya nos la estaría haciendo Gutenberg, pero aquí lo haremos nosotros mismos

(puedes ver las posibilidades en la documentación oficial)

Edit y Save

Siguiendo con las propiedades del objeto en registerBlockType, después de los attributes tenemos las dos opciones troncales edit y el save

El edit se refiere a lo que veremos en el editor

El save se refiere a lo que veremos en el frontend

Y aquí viene un gran qué

En el edit tenemos a nuestra disposición React, por lo que si queremos utilizar @emotion podemos hacerlo sin problema

Pero en el save NO tenemos React, con lo que si utilizamos cualquier cosa que trabaje sobre React no nos va a funcionar

WordPress nos da React sólo en el frontend, pero sólo en el frontend del backend 😵, es decir en el frontend de las páginas que vemos como administrador

Nos ocupamos del save en unos momentos, para el edit necesitamos una entrada de datos para que el usuario escriba los tags de las imágenes y vídeos que quiera ver

Esto lo hacemos poniendo un <input> que estilamos con @emotion, el cual gestionamos con un onChange que lo que hace es actualizar un estado

(repito el código anterior)

Pero de qué estado estamos hablando, si no hemos utilizado ningún useState?

No nos hace falta, recibimos el estado en los argumentos de la función edit, donde lo vemos con attributes y setAttributes

*El className aquí no nos sirve para nada, pero tampoco nos hace daño ponerlo

Añadiendo un ancla para React en save

Y ahora sí, vamos con el save donde te decía que aunque pueda parecer que sí, en save NO tenemos acceso a React

Si pruebas a utilizar algún componente con emotion en save verás que no te funciona

Pero que WordPress no nos dé acceso de forma directa no quiere decir que no lo podamos utilizar, sólo que será un tanto más indirecto

Cómo?

Añadiendo un elemento que luego utilizaremos para renderizar nuestra aplicación React, una ancla

Pero también necesitamos poder comunicarnos con la aplicación, en concreto necesitaremos que esa aplicación sepa qué contenido ha puesto nuestro usuario en nuestro bloque de Gutenberg

Para hacerlo crearemos una variable global en JavaScript

Pero no podemos crearla allí mismo porque el frontend no la verá (es otra página, no se comparte información entre páginas)

Necesitamos crear el código que creará la variable en el mismo frontend, y eso lo hacemos con un tag de <script>, y pasando el objeto attributes en formato JSON

Podríamos hacerlo de otras maneras, pero esta me parece la más sencilla y directa

(repito el código anterior)

El ancla es el elemento con id="kw_gutenberg_imgur" y el <script> genera una variable global que es un objeto que contiene los datos guardados del usuario en forma de string, que creamos con JSON.stringify

Pero qué nos falta? Nos falta que en el frontend (esto es, la página que estamos editando con Gutenberg y que tendrá lo que acabamos de escribir en save) tengamos en efecto acceso a React

Añadiendo React en el frontend

Para tener acceso a React en el frontend necesitamos insertar la librería

Lo hacemos en el archivo del plugin kw-gutenberg-imgur.php, al cual le añadimos lo siguiente

Es decir, antes habíamos añadido el script con el hook enqueue_block_editor_assets, que nos estaba añadiendo un bloque de Gutenberg

Ahora, aparte de esto también estamos añadiendo un script con wp_enqueue_scripts que lo veremos en el frontend

Estamos apuntando build/imgur.js que como antes se corresponderá a su versión no compilada src/imgur.js

Por lo tanto, creamos este archivo src/imgur.js y añadimos lo siguiente

Y con esto estamos consiguiendo tener acceso a React también en el frontend

Estamos utilizando el componente <Imgur>, por lo que creamos la carpeta components y allí creamos el archivo ./components/imgur.js y le volcamos lo siguiente

Y con esto ya tenemos el todo el esqueleto completo del bloque Gutenberg 🙌🙌🙌

Extendiendo WebPack

Pero nos falta una última cosa

Webpack lo que hace es coger todo el código moderno de JavaScript y generar un único archivo con código JavaScript más común

Pero lo que queremos es que

  • Transforme /src/index.js a /build/index.js
  • Transforme /src/imgur.js a /build/imgur.js

Esto lo podemos especificar extendiendo el webpack que nos viene con wp-scripts

Tan fácil como irnos a la raíz de la carpeta (donde tenemos package.json) y creamos el archivo webpack.config.js y allí importamos el archivo que ya nos da wp-script y lo complementamos de la siguiente manera

Le hemos añadido dos objetos nuevos a la configuración de webpack, y con esto conseguimos dos cosas:

  • Generar dos archivos compilados, uno de index.js, y otro de imgur.js

  • Generar módulos de React y ReactDOM (me refiero a generar sinónimos) para que cualquier librería que utilicemos en nuestro componente encuentre esos módulos

Y ahora ya sí, ya tenemos el esqueleto básico para poder desarrollar un bloque de Gutenberg con React tanto en el editor como en el frontend 👏👏

Preparando el bloque Imgur

Ahora que ya tenemos la estructura preparada, ahora sólo nos falta implementar la funcionalidad que queremos

El objetivo era

  • El usuario escoge el bloque y añade los tags que quiera, separados por una coma
  • El bloque cuando se ejecuta en el frontend muestra una lista de las imágenes/videos de Imgur más recientes con esos tags

Imgur nos ofrece esa posibilidad mediante una API aunque nos pide que nos registremos (aquí)

Seguimos las indicaciones (que encuentras aquí) y tendremos nuestro CLIENT ID y CLIENT SECRET, a mi me ha llevado menos de 1 minuto

Para acceder tendremos que configurar el funcionamiento para la autentificación, y esto sucede en 2 fases

  • El primero para pedir un token
  • El segundo para con ese token hacer la petición

Pero afortunadamente, si sólo queremos mostrar imágenes sólo necesitamos identificarnos con el CLIENT ID, lo cual simplifica enormemente el desarrollo

Este desarrollo ya es puramente con React

Entonces, pedimos una galería de la siguiente manera

En definitiva lo que estamos haciendo es

  • Pedir las imágenes a imgur con nuestro CLIENT_ID
  • Lo hacemos una única vez con useEffect
  • Lo hacemos con una función anónima para que pueda ser async y así esperar a tener cada respuesta antes de ir al siguiente paso
  • Almacenamos los datos recibidos con useState
  • Y así en cuando se actualiza este estado, automáticamente se re-renderiza el tema y se muestran las imágenes o vídeos de imgur

El código dentro del componente <Display> es solamente para averiguar si lo que nos da imgur es una imagen o un vídeo

Y luego tenemos el componente Grid que simplemente define un css-grid básico

El useEffect tal y como está arriba, al tener funciones que no son inmediatas (los fetch), si el usuario se va de la página antes de que estos hayan acabado, este código intentará seguir y nos dará un warning por posibles fugas de memoria

Lo suyo sería evitarlo (no está incluido en el código)

Hay mucho margen de mejoras

Por ejemplo se puede implementar un lazy loading de las imágenes, que esto a nivel de navegadores modernos lo podemos hacer con loading="lazy", pero a nivel de video necesitaríamos buscar alguna librería o hacerlo nosotros mismos (yo utilizo la librería react-intersection-observer)

Pero esto ya se escapa de lo que quería enseñarte en este curso

Y evidentemente también tenemos la estética, que tal y como está ahora presenta un problema:

En móvil se ve bien

móvil

Pero en escritorio tenemos un ancho de columna que está definido por encima de la aplicación de React

desktop

Cómo podemos modificar ese ancho para que nos ocupe una mayor parte del espacio disponible?

No lo podemos definir desde nuestra aplicación de React

Necesitamos modificar nuestro theme de WordPress

Esto no lo veremos aquí, pero sí que nos sirve para ver que no estamos desarrollando una aplicación en React sino que estamos añadiendo una aplicación React a un desarrollo WordPress, que es distinto

Comentario

Ya tenemos listo cómo desarrollar un bloque con Gutenberg y además cómo integrar React también en el frontend de nuestro WordPress

Las ventajas de hacer esto son básicamente las de poder prescindir del ecosistema de desarrollo tradicional de WordPress para frontend y disfrutar de un desarrollo en React

Pero el nivel de integración entre React y WordPress (php) no es todo lo fluido que podría ser si el backend también estuviera en JavaScript

En mi caso estoy muy expectante para ver los próximos movimientos del desarrollo de WordPress en este sentido

🙋‍♂️

Qué tal el curso?
👌 Bien 🙌🙌
👍 Bien, pero algunas cosas podrían explicarse mejor 😬
🤷‍♂️ Da por sentadas demasiadas cosas 😒
🤷‍♂️ A ver, hay poca chicha 😬
🤷‍♂️ Los ejemplos no son muy claros 🙇‍♂️
🤷‍♂️ No se entiende, está mal escrito 👎
✍️ Hay errores, revísalo en cuanto puedas 🙏

Quizá te interese

Privacidad
by kuworking.com
[ 2020 >> kuworking ]