Mucha gente se queja de las dificultades para empezar a construir bloques y aplicaciones de Gutenberg. La curva de aprendizaje es empinada, principalmente debido a la dificultad de instalar y configurar el entorno de desarrollo. Además, un sólido conocimiento de JavaScript, Node.js, React y Redux son ingredientes imprescindibles para esta receta bastante compleja.
El manual oficial del editor de bloques de WordPress proporciona a los desarrolladores una enorme cantidad de información, pero puede que te encuentres perdido en ese mar de detalles.
Y vale la pena mencionar lo que Matías Ventura, arquitecto principal del proyecto Gutenberg, dijó en su entrevista en WP Tavern:
Aunque hay gente que puede aprenderlo rápidamente, sigue siendo una gran barrera para la gente. Creo que existen diversas claves; la documentación podría mejorar en gran medida, tanto en organización como en presentación. Espero que podamos hacer mucho más en este sentido.
Con esto en mente, hemos decidido crear un tutorial paso a paso destinado a ayudar a nuestros lectores a iniciarse en el desarrollo de bloques de Gutenberg.
¿Te parece interesante? Vamos a sumergirnos en el tema.
Requisitos previos para el desarrollo de bloques de Gutenberg
Para este tutorial, las únicas habilidades requeridas son un buen conocimiento del desarrollo de plugins de WordPress y al menos una comprensión básica de HTML, CSS, JavaScript y React.
¿Es un proyecto ambicioso? Por supuesto que sí.
No fue fácil encontrar el compromiso adecuado entre la exhaustividad y la sencillez, ni decidir qué temas incluir y cuáles dejar fuera.
Esperemos que los lectores intermedios y avanzados nos perdonen por no profundizar en ciertos conceptos como el estado de React, el almacén Redux, los high order components, etc. Estos temas requieren espacio y atención adicionales y son probablemente demasiado avanzados para el desarrollo de bloques principiante (a menos que seas un desarrollador de React).
Por la misma razón, no cubriremos algunos de los temas más avanzados relacionados con el desarrollo de bloques de Gutenberg, como los bloques dinámicos y los meta boxes.
Con los conocimientos que obtendrás al final de este artículo, podrás empezar a divertirte y ser productivo de inmediato.
Una vez que te pongas en marcha con la construcción de bloques, estarás preparado para mejorar tus habilidades y construir bloques Gutenberg aún más avanzados por tu cuenta.
¿Qué es un bloque Gutenberg?
Desde que se lanzó por primera vez en diciembre de 2018, el editor de bloques ha mejorado mucho en todos los aspectos: APIs más potentes, una interfaz de usuario más avanzada, una usabilidad mejorada, una tonelada de bloques nuevos, las primeras implementaciones de Full Site Editing y mucho más.
En resumen, aunque Gutenberg sigue en pleno desarrollo, ha recorrido un largo camino – y hoy, el editor de bloques es un candidato de pleno derecho como constructor de páginas y sitios fiables y funcionales.
Desde el punto de vista del desarrollador, Gutenberg es una single-page application (SPA) basada en React que permite a los usuarios de WordPress crear, editar y eliminar contenido en WordPress. Sin embargo, esto no debe hacer pensar en una versión mejorada del editor de contenidos tradicional.
Queremos dejar esto claro:
En Gutenberg, el contenido se divide en bloques, que son «ladrillos» que los usuarios pueden utilizar para crear entradas y páginas o sus sitios web completos.
Pero, ¿qué es técnicamente un bloque?
Nos gusta la definición de WordPress:
«Bloque» es el término abstracto utilizado para describir las unidades de marcado que, compuestas juntas, forman el contenido o el diseño de una página web. La idea combina conceptos de lo que en WordPress conseguimos hoy con los shortcodes, el HTML personalizado y el embed discovery en una única y consistente API y experiencia de usuario.
Los títulos, los párrafos, las columnas, las imágenes, las galerías y todos los elementos que componen la interfaz del editor, desde los paneles de la barra lateral hasta los controles de la barra de herramientas de los bloques, son componentes React.
Entonces, ¿qué son los componentes React? W3Schools ofrece la siguiente definición:
Los componentes son fragmentos de código independientes y reutilizables. Sirven para el mismo propósito que las funciones de JavaScript, pero funcionan de forma aislada y devuelven HTML a través de una función
render()
.
Aunque la experiencia de edición que ofrece Gutenberg es nueva en comparación con el editor clásico de WordPress, la forma en que WordPress almacena sus piezas de contenido en la base de datos no cambia en absoluto. Esto se debe a que Gutenberg es una aplicación que funciona dentro de WordPress pero no cambia la forma en que el CMS funciona en su núcleo.
Las entradas (y esto incluye entradas, páginas y tipos de entradas personalizadas) creadas con Gutenberg siguen almacenándose en la tabla wp_posts
, exactamente igual que con el editor clásico.
Pero en un post creado con Gutenberg, encontrarás trozos de información adicionales en la tabla que representan una diferencia fundamental entre los posts creados a través del Editor Clásico vs Gutenberg.
Estas piezas de información se parecen a los comentarios HTML, y tienen una función específica: delimitar bloques:
Los delimitadores de bloque le indican a WordPress qué bloque se va a mostrar en la pantalla. También proporcionan valores para las propiedades del bloque en un objeto JSON. Esas propiedades dictan la forma en que el bloque debe ser renderizado en la pantalla:
Configuración del entorno de desarrollo de WordPress
La configuración de un entorno de desarrollo JavaScript moderno requiere un sólido conocimiento de tecnologías avanzadas como Webpack, React y JSX, Babel, ESLint, etc.
¿Intimidado? No lo estés. La comunidad de WordPress ya ha acudido al rescate proporcionando potentes herramientas que te permiten evitar un engorroso proceso de configuración manual.
Para simplificar las cosas, no cubriremos la transpilación en este artículo (que, sin embargo, recomendamos que te familiarices con ella una vez que hayas aprendido los fundamentos del desarrollo en bloque). En su lugar, presentaremos dos herramientas alternativas que puedes utilizar para configurar rápida y fácilmente un entorno de desarrollo de JavaScript moderno en pocos minutos. Depende de ti elegir la que te resulte más conveniente para tu proyecto.
Configurar un entorno de desarrollo de JavaScript para construir bloques de Gutenberg es un proceso de tres pasos:
Empecemos.
1. Instalar Node.js y npm
Antes de instalar tu entorno de desarrollo y registrar tu primer bloque, necesitarás instalar Node.js y el gestor de paquetes Node (npm).
Puedes instalar Node.js y npm de diferentes maneras. Pero primero, es posible que quieras comprobar si el software ya está instalado en tu máquina.
Para ello, inicia el terminal y ejecute el siguiente comando:
node -v
Si el resultado es command not found
, entonces Node.js no está instalado en tu ordenador, y puedes proceder con la instalación.
Para este artículo, hemos elegido la opción de instalación más sencilla, que es el instalador de Node. Lo único que tienes que hacer es descargar la versión correspondiente a tu sistema operativo e iniciar el asistente de instalación:
Una vez que hayas instalado Node.js, ejecuta el comando node -v
en tu terminal de nuevo. También puedes ejecutar el comando npm -v
para confirmar que tienes el paquete.
Ahora estás equipado con las siguientes herramientas:
- El corredor de paquetes
npx
Node.js (ver docs). Esto te permite ejecutar un comandonpm
sin instalarlo primero. - El gestor de paquetes
npm
Node.js (ver docs). Se utiliza para instalar dependencias y ejecutar scripts.
El siguiente paso es instalar el entorno de desarrollo.
2. Configurar el entorno de desarrollo
Una vez que tengas las últimas versiones de Node.js y npm en tu máquina local, necesitarás un entorno de desarrollo para WordPress.
Puedes utilizar un entorno de desarrollo local como DevKinsta o utilizar la herramienta oficial de WordPress. Vamos a echar un vistazo a ambas opciones.
Opción 1: Entorno de desarrollo local (DevKinsta)
Con solo unos pocos clics, puedes instalar WordPress localmente usando DevKinsta, nuestra moderna herramienta de desarrollo local de WordPress. O puedes optar por otra herramienta de desarrollo local, como MAMP o XAMPP:
Opción 2: wp-env
También puedes optar por la wp-env
herramienta oficial, que proporciona un entorno de desarrollo local de WordPress que puedes lanzar directamente desde la línea de comandos. Noah Alen lo define así:
Los entornos locales de WordPress son ahora tan sencillos como ejecutar un único comando.
wp-env
es una herramienta de configuración cero para entornos locales de WordPress sin complicaciones. Proporciona decisiones sobre las opciones para que los usuarios puedan poner en marcha rápidamente WordPress sin perder tiempo. De hecho, el objetivo es hacer que estos entornos sean fácilmente accesibles para todos, ya seas un desarrollador, un diseñador, un gestor o cualquier otra persona.
Si decides probarlo, la instalación de wp-env
requiere un esfuerzo mínimo. Solo tienes que seguir estos pasos:
Paso 1: Confirmar la instalación de Docker y Node.js
Para cumplir con los requisitos técnicos, primero tendrás que tener Docker y Node.js instalados en tu ordenador. Esto se debe a que wp-env
crea una instancia Docker que ejecuta un sitio web de WordPress. Cualquier cambio realizado en el código se refleja inmediatamente en la instancia de WordPress.
Paso 2: Instalar @wordpress/env
desde la línea de comandos
Con Docker y Node.js funcionando en tu ordenador, puedes pasar a instalar el entorno de desarrollo de WordPress.
Puede instalar wp-env
de forma global o local. Para hacerlo de forma global, tendrás que ejecutar el siguiente comando desde el directorio de plugins (más información sobre esto en el cuadro de aviso «Importante» más abajo):
npm install -g @wordpress/env
Vamos a desglosar eso:
npm install
instala el paquete.- La opción
-g
añadida al comando instala el paquete especificado de forma global. @wordpress/env
es el paquete que vas a instalar.
Para confirmar que wp-env
se ha instalado correctamente, ejecuta el siguiente comando:
wp-env --version
Deberías ver la versión actual de wp-env
, lo que significa que ahora puedes lanzar el entorno utilizando el siguiente comando desde la carpeta de su plugin:
wp-env start
Puedes acceder al panel de control de WordPress utilizando la siguiente dirección:
- http://localhost:8888/wp-admin/
Las credenciales por defecto son las siguientes:
- Nombre de usuario:
admin
- Contraseña:
password
Configurar el plugin de bloqueo
Ahora necesitas un plugin de bloques de inicio sobre el que construir. Pero en lugar de crear manualmente un plugin de desarrollo de bloques con todos los archivos y carpetas necesarios, puedes simplemente ejecutar una herramienta de desarrollo que te proporcione todos los archivos y configuraciones que necesitas para empezar a desarrollar bloques.
De nuevo, tienes un par de opciones para elegir. Veamos cada una de ellas.
Opción 1: Configurar un plugin de bloque con @wordpress/create-block
@wordpress/create-block es la herramienta oficial de configuración cero para crear bloques Gutenberg:
Create Block es una forma oficial de crear bloques para registrar un bloque para un plugin de WordPress. Ofrece una configuración de construcción moderna sin configuración. Genera código PHP, JS, CSS y todo lo que necesitas para iniciar el proyecto.
Se inspira en gran medida en create-react-app. Un gran reconocimiento a @gaearon, a todo el equipo de Facebook y a la comunidad React.
Una vez que tu entorno local esté en funcionamiento, puedes configurar un bloque inicial simplemente ejecutando el comando npx @wordpress/create-block
, y te proporcionará todos los archivos y carpetas que necesita para crear el andamiaje del plugin y registrar un nuevo bloque.
Hagamos una prueba para ver cómo funciona.
Desde tu herramienta de línea de comandos, navega hasta el directorio /wp-content/plugins/ y ejecuta el siguiente comando:
npx @wordpress/create-block my-first-block
Cuando te le pida que confirma, introduce y
para continuar:
El proceso dura unos instantes. Cuando se haya completado, deberías obtener la siguiente respuesta:
¡Y ya está!
Ahora inicia tu entorno de desarrollo de WordPress y dirígete a la pantalla de plugins en el panel de control de WordPress. Un nuevo plugin llamado «My First Block» debería haber sido añadido a tu lista de plugins:
Activa el plugin si es necesario, crea una nueva entrada de blog, desplázate por el insertador de bloques hasta la sección de Widgets y selecciona tu nuevo bloque:
Ahora vuelve al terminal y cambia el directorio actual a mi-primer-bloque:
cd my-first-block
A continuación, ejecuta el siguiente comando:
npm start
Esto te permite ejecutar el plugin en modo de desarrollo. Para crear el código de producción, debes utilizar el siguiente comando:
npm run build
Opción 2: Configurar un plugin de bloque con create-guten-block
create-guten-block
es una herramienta de desarrollo de terceros para construir bloques Gutenberg:
create-guten-block
es un dev-toolkit de configuración cero (#0CJS) para desarrollar bloques de WordPress Gutenberg en cuestión de minutos sin configurar React, webpack, ES6/7/8/Next, ESLint, Babel, etc.
Al igual que la herramienta oficial de create-block
, create-guten-block
se basa en create-react-app y puede ayudarte a generar tu primer plugin de bloques sin problemas.
El kit de herramientas proporciona todo lo necesario para crear un moderno plugin de WordPress, incluyendo lo siguiente:
- Soporte de sintaxis React, JSX y ES6.
- proceso de construcción de webpack para desarrollo/producción detrás de la escena.
- Extras del lenguaje más allá de ES6 como el operador de propagación de objetos.
- CSS autoprefijado, por lo que no se necesita -webkit u otros prefijos.
- Un script de construcción para empaquetar JS, CSS e imágenes para la producción con mapas de origen.
- Actualizaciones sin problemas para las herramientas anteriores con una sola dependencia cgb-scripts.
Ten en cuenta la siguiente advertencia:
La contrapartida es que estas herramientas están preconfiguradas para funcionar de una manera específica. Si tu proyecto necesita más personalización, puedes «expulsar» y personalizarlo, pero entonces tendrás que mantener esta configuración.
Una vez que tengas a mano un sitio web local de WordPress, inicie tu herramienta de línea de comandos, navega hasta la carpeta /wp-content/plugins de su instalación y ejecuta el siguiente comando:
npx create-guten-block my-first-block
Tendrás que esperar uno o dos minutos mientras se crea la estructura del proyecto y se descargan las dependencias:
Cuando el proceso se haya completado, deberías ver la siguiente pantalla:
La siguiente imagen muestra la estructura del proyecto con el terminal ejecutado en Visual Studio Code:
Ahora vuelve a tu panel de control de WordPress. Debería aparecer un nuevo elemento en la pantalla de plugins: es el plugin my-first-block:
Activa el plugin y vuelve a la terminal. Cambia el directorio actual a mi-primer-bloque, luego ejecuta npm start
:
cd my-first-block
npm start
Deberías obtener la siguiente respuesta:
De nuevo, esto te permite ejecutar el plugin en modo de desarrollo. Para crear el código de producción, debes utilizar:
npm run build
Activa el plugin y crea un nuevo post o página, luego explora tus bloques y selecciona tu flamante bloque Gutenberg:
Para una visión más profunda o en caso de errores, consulta la documentación proporcionada por Ahmad Awais.
Un recorrido por el andamiaje del bloque inicial
Cualquiera de las dos herramientas de desarrollo create-block
o create-guten-block
que elijas, ahora tendrás un andamiaje de bloques que puedes usar como punto de partida para construir un plugin de bloques.
Pero, ¿qué es exactamente un andamio de bloques?
El andamio de bloques es un término abreviado que describe la estructura de directorios de soporte que necesita WordPress para reconocer un bloque. Normalmente ese directorio incluye archivos como index.php, index.js, style.css y otros, que a su vez contienen llamadas como
register_block_type
.
Hemos optado por la herramienta oficial de creación de bloques, ya que se utiliza en el manual del editor de bloques. Pero incluso si te decides por una herramienta de terceros como create-guten-block
, tu experiencia no será muy diferente.
Dicho esto, vamos a profundizar en la create-block
herramienta.
Una mirada más cercana a la herramienta de creación de bloques
Como hemos mencionado anteriormente, Create Block es la herramienta oficial de línea de comandos para crear bloques de Gutenberg. Ejecutar @wordpress/create-block
en tu terminal genera los archivos PHP, JS y SCSS y el código necesario para registrar un nuevo tipo de bloque:
npx @wordpress/create-block [options] [slug]
[slug]
(opcional) – se utiliza para asignar el slug del bloque e instalar el plugin[options]
(opcional) – opciones disponibles
Por defecto, se asigna una plantilla ESNext. Esto significa que obtendrás la siguiente versión de JavaScript, con la adición de la sintaxis JSX.
Si omites el nombre del bloque, el comando se ejecuta en modo interactivo, lo que te permite personalizar varias opciones antes de generar los archivos:
npx @wordpress/create-block
La imagen siguiente muestra la estructura de archivos de un plugin de bloque creado con la herramienta oficial Create Block:
Dicho esto, vamos a repasar los principales archivos y carpetas de nuestro nuevo plugin de bloques.
El archivo del plugin
Con el archivo principal del plugin se registra el bloque en el servidor:
<?php
/**
* Plugin Name: Kinsta Academy Block
* Plugin URI: https://kinsta.com/
* Description: An example block for Kinsta Academy students
* Requires at least: 5.9
* Requires PHP: 7.0
* Version: 0.1.0
* Author: Kinsta Students
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: ka-example-block
*
* @package ka-example-block
*/
/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function ka_example_block_ka_example_block_block_init() {
register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'ka_example_block_ka_example_block_block_init' );
La función register_block_type
registra un tipo de bloque en el servidor utilizando los metadatos almacenados en el archivo block.json.
La función toma dos parámetros:
- El nombre del tipo de bloque incluyendo el espacio de nombres, o una ruta a la carpeta donde se encuentra el archivo block.json, o un objeto
WP_Block_Type
completo - Una matriz de argumentos de tipo de bloque
En el código anterior, la constante mágica __DIR__
devuelve la carpeta actual. Eso significa que el archivo block.json reside en la subcarpeta /build.
El archivo package.json
El archivo package.json define las propiedades y scripts de JavaScript para tu proyecto. Aquí es donde puedes instalar las dependencias de tu proyecto.
Para entender mejor para qué sirve este archivo, ábrelo con tu editor de código favorito:
{
"name": "ka-example-block",
"version": "0.1.0",
"description": "An example block for Kinsta Academy students",
"author": "Kinsta Students",
"license": "GPL-2.0-or-later",
"homepage": "https://kinsta.com/",
"main": "build/index.js",
"scripts": {
"build": "wp-scripts build",
"format": "wp-scripts format",
"lint:css": "wp-scripts lint-style",
"lint:js": "wp-scripts lint-js",
"packages-update": "wp-scripts packages-update",
"plugin-zip": "wp-scripts plugin-zip",
"start": "wp-scripts start"
},
"devDependencies": {
"@wordpress/scripts": "^24.1.0"
},
"dependencies": {
"classnames": "^2.3.2"
}
}
La propiedad scripts
es un diccionario que contiene comandos que se ejecutan en varios momentos del ciclo de vida de un paquete utilizando npm run [cmd]
.
En este artículo vamos a utilizar los siguientes comandos:
npm run build
— crea una compilación de producción (comprimida)npm run start
onpm start
— crea una compilación de desarrollo (sin comprimir)
Las dependencies
y las devDependencies
son dos objetos que asignan un nombre de paquete a una versión. Las dependencies
son necesarias en producción, mientras que las devDependences
solo son necesarias para el desarrollo local (leer más).
La única dependencia de desarrollo por defecto es el paquete @wordpress/scripts
que se define como «una colección de scripts reutilizables adaptados al desarrollo de WordPress».
El archivo block.json
A partir de WordPress 5.8, el archivo de metadatos block.json es la forma canónica de registrar los tipos de bloque.
Tener un archivo block.json proporciona varios beneficios, incluyendo un mejor rendimiento y una mejor visibilidad en el directorio de plugins de WordPress:
Desde el punto de vista del rendimiento, cuando los temas admiten activos de carga lenta, los bloques registrados con block.json tendrán una cola de espera de activos optimizada de forma inmediata. Los activos CSS y JavaScript del frontend que aparecen en las propiedades de
style
o descript
solo se pondrán en cola cuando el bloque esté presente en la página, lo que reducirá el tamaño de la misma.
La ejecución del comando @wordpress/create-block
genera el siguiente archivo block.json:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "ka-example-block/ka-example-block",
"version": "0.1.0",
"title": "Kinsta Academy Block",
"category": "widgets",
"icon": "superhero-alt",
"description": "An example block for Kinsta Academy students",
"supports": {
"html": false
},
"textdomain": "ka-example-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
Aquí está la lista completa de propiedades por defecto:
apiVersion
—la versión de la API utilizada por el bloque (la versión actual es la 2)name
— un identificador único para un bloque que incluye un espacio de nombresversion
– la versión actual de un bloquetitle
– un título para mostrar un bloquecategory
—una categoría de bloqueicon
– un slug de Dashicon o un icono SVG personalizadodescription
– una breve descripción visible en el inspector de bloquessupports
– un conjunto de opciones para controlar las características utilizadas en el editortextdomain
– el plugin text-domaineditorScript
— definición de script del editoreditorStyle
— definición del estilo del editorstyle
— proporciona estilos alternativos para un bloque
Además de las propiedades enumeradas anteriormente, puedes (y probablemente lo harás) definir un objeto de attributes
que proporcione información sobre los datos almacenados por tu bloque. En tu block.json puedes establecer cualquier número de atributos en pares clave/valor, donde la clave es el nombre del atributo y el valor es la definición del mismo.
Observa el siguiente ejemplo de definición de atributos:
"attributes": {
"content": {
"type": "array",
"source": "children",
"selector": "p"
},
"align": {
"type": "string",
"default": "none"
},
"link": {
"type": "string",
"default": "https://kinsta.com"
}
},
Más adelante profundizaremos en el archivo block.json, pero también puedes consultar el Manual del Editor de Bloques para obtener información más detallada sobre los metadatos y atributos de block.json.
La carpeta src
La carpeta src
es donde ocurre el desarrollo. En esa carpeta, encontrarás los siguientes archivos:
- index.js
- edit.js
- save.js
- editor.scss
- style.scss
index.js
El archivo index.js es tu punto de partida. Aquí importarás las dependencias y registrarás el tipo de bloque en el servidor:
import { registerBlockType } from '@wordpress/blocks';
import './style.scss';
import Edit from './edit';
import save from './save';
import metadata from './block.json';
registerBlockType( metadata.name, {
/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./save.js
*/
save,
} );
La primera sentencia importa la función registerBlockType
del paquete @wordpress/blocks
. Las siguientes declaraciones de importación importan la hoja de estilos junto con las funciones Edit
y save
, y un objeto de metadatos del archivo block.json.
La función registerBlockType
registra el componente en el cliente. La función toma dos parámetros: un nombre de bloque y un objeto de configuración de bloque.
La función Edit
proporciona la interfaz del bloque tal y como se muestra en el editor de bloques, mientras que la función save
proporciona la estructura que se serializará y guardará en la base de datos (leer más).
edit.js
edit.js es donde construirás la interfaz de administración del bloque:
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<p {...useBlockProps()}>
{__('My First Block – hello from the editor!', 'my-first-block')}
</p>
);
}
En primer lugar, importa la función __
del paquete @wordpress/i18n
(este paquete contiene una versión JavaScript de las funciones de traducción), el hook useBlockProps
React y el archivo editor.scss
.
A continuación, exporta el componente React (lee más sobre las declaraciones de importación y exportación).
save.js
El archivo save.js es donde construimos la estructura de bloques que se guardará en la base de datos:
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
export default function save() {
return (
<p {...useBlockProps.save()}>
{__(
'My First Block – hello from the saved content!',
'my-first-block'
)}
</p>
);
}
editor.scss y style.scss
Además de los scripts, en las carpetas src residen dos archivos SASS. El archivo editor.scss contiene los estilos aplicados al bloque en el contexto del editor, mientras que el archivo style.scss contiene los estilos del bloque para su visualización en el frontend así como en el editor. Profundizaremos en estos archivos en la segunda parte de esta guía.
Las carpetas node_modules y build
La carpeta node_modules
contiene los módulos de node y sus dependencias. No vamos a profundizar en los paquetes de node ya que está fuera del alcance de este artículo, pero puedes leer más en este artículo sobre dónde instala npm los paquetes.
La carpeta de build
contiene los archivos JS y CSS resultantes del proceso de construcción. Puedes profundizar en el proceso de compilación en las guías de sintaxis de ESNext y de configuración de la compilación de JavaScript.
El proyecto: Construir tu primer bloque Gutenberg
Es hora de ensuciarse las manos. Esta sección te enseñará cómo crear un plugin que proporcione un bloque de CTA llamado Kinsta Academy Block.
El bloque constará de dos columnas, con una imagen a la izquierda y un párrafo de texto a la derecha. Debajo del texto se colocará un botón con un enlace personalizable:
Este es solo un ejemplo sencillo, pero nos permite cubrir los fundamentos del desarrollo de bloques Gutenberg. Una vez que tengas claro lo básico, puedes seguir adelante y crear bloques de Gutenberg más y más complejos con la ayuda del Manual del Editor de Bloques y cualquier otro de los vastos recursos disponibles por ahí.
Asumiendo que tienes la última versión de WordPress corriendo en tu entorno de desarrollo local, esto es lo que vas a aprender de aquí en adelante:
- Cómo configurar el plugin Starter Block
- block.json en el trabajo
- Uso de los componentes incorporados: El componente RichText
- Añadir controles a la barra de herramientas del bloque
- Personalización de la barra lateral de configuración del bloque
- Añadir y personalizar un enlace externo
- Añadir varios estilos de bloque
- Anidación de bloques con el componente InnerBlocks
- Mejoras adicionales
Preparados… listos… ¡ya!
Cómo configurar el plugin Starter Block
Inicia tu herramienta de línea de comandos y navega hasta la carpeta /wp-content/plugins:
Ahora, ejecuta el siguiente comando:
npx @wordpress/create-block
Este comando genera los archivos PHP, SCSS y JS para registrar un bloque en modo interactivo, permitiéndole añadir los datos necesarios para su bloque fácilmente. Para nuestro ejemplo utilizaremos los siguientes datos:
- Variante de la Plantilla: static
- Slug del bloque: ka-example-block
- Nombre del espacio interno: ka-example-block
- Título de visualización del bloque: Kinsta Academy Block
- Descripción breve del bloque: Un bloque de ejemplo para los estudiantes de la Academia Kinsta
- Dashicon: superhero-alt
- Nombre de la categoría: widgets
- ¿Quieres personalizar el plugin de WordPress?: sí
- La página de inicio del plugin: https://kinsta.com/
- Versión actual del plugin: 0.1.0
- Autor del plugin: tu nombre
- Licencia: –
- Enlace al texto de la licencia: –
- Ruta de dominio personalizada para las traducciones: –
La instalación del plugin y de todas las dependencias lleva un par de minutos. Cuando el proceso se complete, verás la siguiente respuesta:
Ahora, ejecuta el siguiente comando desde la carpeta /wp-content/plugins:
cd ka-example-block
Finalmente, desde la carpeta de tu plugin (ka-example-block en nuestro ejemplo), puedes comenzar el desarrollo con:
npm start
Ahora abre la pantalla de plugins para encontrar y activar el plugin Kinsta Academy Block:
Crea una nueva publicación, abre el insertador de bloques y desplázate hasta la categoría de Diseño. Haz clic para añadir el bloque de la Academia Kinsta:
block.json a trabajar
Como mencionamos anteriormente, el registro del bloque del lado del servidor tiene lugar en el archivo principal .php. Sin embargo, no vamos a definir la configuración en el archivo .php. En su lugar, utilizaremos el archivo block.json.
Por lo tanto, abre de nuevo block.json y echa un vistazo a la configuración por defecto:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "ka-example-block/ka-example-block",
"version": "0.1.0",
"title": "Kinsta Academy Block",
"category": "widgets",
"icon": "superhero-alt",
"description": "An example block for Kinsta Academy students",
"supports": {
"html": false
},
"textdomain": "ka-example-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
Guiones y estilos
Las propiedades editorScript
, editorStyle
, y style
proporcionan las rutas relativas a los scripts y estilos del frontend y del backend.
No tienes que registrar manualmente los scripts y estilos definidos aquí porque éstos son registrados y puestos en cola automáticamente por WordPress. Para comprobarlo, inicia el inspector del navegador y abra la pestaña Red:
Como puedes ver en la imagen de arriba, nuestro script index.js que reside en la carpeta de construcción se ha puesto en cola regularmente sin tener que añadir ningún código PHP.
Etiquetas UI
Las propiedades title
y description
proporcionan las etiquetas necesarias para identificar el bloque en el editor:
Palabras clave
Como hemos mencionado anteriormente, puedes configurar con precisión los ajustes de los bloques mediante propiedades y atributos. Por ejemplo, puedes añadir una o más keywords
para ayudar a los usuarios a buscar bloques:
"keywords": [
"kinsta",
"academy",
"superhero"
],
Si ahora introduces «kinsta», «academy» o «superhero» en el insertador rápido, el editor te sugerirá el bloque de la Academia Kinsta:
Localización
Si te preguntas cómo se produce la localización de las cadenas en el archivo JSON, aquí tienes la respuesta:
En JavaScript, puede utilizar el método
registerBlockTypeFromMetadata
del paquete@wordpress/blocks
para registrar un tipo de bloque utilizando los metadatos cargados desde el archivo block.json. Todas las propiedades localizadas se envuelven automáticamente en llamadas a la función_x
(del paquete@wordpress/i18n
), de forma similar a como funciona en PHP conregister_block_type_from_metadata
. El único requisito es establecer la propiedadtextdomain
en el archivo block.json.
Aquí estamos utilizando la función registerBlockType
en lugar de registerBlockTypeFromMetadata
, ya que esta última ha quedado obsoleta desde Gutenberg 10.7, pero el mecanismo es el mismo.
Uso de los componentes incorporados: El componente RichText
Los elementos que conforman un bloque de Gutenberg son componentes de React, y puedes acceder a estos componentes a través de la variable global wp
. Por ejemplo, intenta escribir wp.editor
en la consola de tu navegador. Esto te dará la lista completa de los componentes incluidos en el módulo wp.editor
.
Desplázate por la lista y adivina para qué sirven los componentes por sus nombres.
Del mismo modo, puede comprobar la lista de componentes incluidos en el módulo wp.components
:
Ahora vuelve al archivo edit.js y echa un vistazo al script:
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit() {
return (
<p { ...useBlockProps() }>
{ __(
'Kinsta Academy Block – hello from the editor!',
'ka-example-block'
) }
</p>
);
}
Este código genera un bloque estático con un texto simple y no editable. Pero podemos cambiar las cosas fácilmente:
Para hacer que el texto sea editable tendrás que sustituir la etiqueta <p>
actual por un componente que haga que el contenido de entrada sea editable. Para ello, Gutenberg proporciona el componente integrado RichText.
Añadir un componente incorporado a tu bloque es un proceso de 5 pasos:
- Importar los componentes necesarios de un paquete de WordPress
- Incluir los elementos correspondientes en tu código JSX
- Definir los atributos necesarios en el archivo block.json
- Definir los manejadores de eventos
- Guardar datos
Paso 1: Importar los componentes necesarios de un paquete de WordPress
Ahora abre el archivo edit.js y cambia la siguiente declaración de import
:
import { useBlockProps } from '@wordpress/block-editor';
…a:
import { useBlockProps, RichText } from '@wordpress/block-editor';
De esta manera, estás importando la función useBlockProps
y el componente RichText
del paquete @wordpress/block-editor
.
useBlockProps
El hook useBlockProps
de React marca el elemento envolvente del bloque:
Cuando se utiliza la versión 2 de la API, se debe utilizar el nuevo gancho
useBlockProps
en la función deedit
para marcar el elemento envolvente del bloque. El gancho insertará los atributos y manejadores de eventos necesarios para habilitar el comportamiento del bloque. Cualquier atributo que desee pasar al elemento del bloque debe pasarse a través deuseBlockProps
y el valor devuelto debe extenderse al elemento.
Para simplificar, useBlockProps
asigna automáticamente atributos y clases al elemento envolvente (el elemento p
en nuestro ejemplo):
Si se elimina useBlockProps
del elemento envolvente, se tendría una simple cadena de texto sin acceso a la funcionalidad y el estilo del bloque:
Como explicaremos más adelante, también puedes pasar useBlockProps
un objeto de propiedades para personalizar la salida.
RichText
El componente RichText proporciona una entrada con contenido editable, permitiendo a los usuarios editar y formatear el contenido.
Encontrarás el componente documentado en GitHub en gutenberg/packages/block-editor/src/components/rich-text/README.md.
Paso 2: Incluir los elementos correspondientes en tu código JSX
...
const blockProps = useBlockProps();
return (
<RichText
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
/>
);
Comentemos el código línea por línea:
tagName
— función llamada cuando el contenido del elemento cambiaonChange
— función llamada cuando el contenido del elemento cambiaallowedFormats
— una matriz de formatos permitidos. Por defecto, se permiten todos los formatosvalue
— la cadena HTML para hacerla editableplaceholder
— texto que se mostrará cuando el elemento esté vacío
Paso 3: Definir los atributos necesarios en el archivo block.json
Los atributos proporcionan información sobre los datos almacenados por un bloque, como el contenido enriquecido, el color de fondo, las URL, etc.
Puede establecer un número arbitrario de atributos dentro de un objeto de attributes
en pares clave/valor, donde la clave es el nombre del atributo y el valor es la definición del atributo.
Ahora abre el archivo block.json y añade los siguientes attributes
prop:
"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
}
},
El atributo de content
permite almacenar el texto escrito por el usuario en el campo editable:
type
indica el tipo de datos almacenados por el atributo. El tipo es obligatorio a menos que se defina una propiedadenum
.source
define cómo se extrae el valor del atributo del contenido de la entrada. En nuestro ejemplo, es el contenido HTML. Ten en cuenta que si no proporciona una propiedad de fuente, los datos se almacenan en el delimitador de bloque (leer más).selector
es una etiqueta HTML o cualquier otro selector, como un nombre de clase o un atributo id.
Pasaremos a la función Edit
un objeto de propiedades. Así que, vuelve al archivo edit.js y haz el siguiente cambio:
export default function Edit( { attributes, setAttributes } ) { ... }
Paso 4: Definir los manejadores de eventos
El elemento RichText
tiene un atributo onChange
, que proporciona una función para llamar cuando el contenido del elemento cambia.
Definamos esa función y veamos todo el script edit.js:
import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } )
}
return (
<RichText
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
/>
);
}
Ahora guarda el archivo y vuelve a tu panel de control de WordPress, crea una nueva entrada o página y añade tu bloque personalizado:
Añade algo de texto y cambia a la vista de código. Este es el aspecto que debería tener su código:
<!-- wp:ka-example-block/ka-example-block -->
<p class="wp-block-ka-example-block-ka-example-block">Kinsta Academy Block – hello from the saved content!</p>
<!-- /wp:ka-example-block/ka-example-block -->
Como puedes ver, si cambias al Editor de Código, el contenido de tu bloque ha cambiado. Eso es porque tienes que modificar el archivo save.js para almacenar la entrada del usuario en la base de datos cuando se guarda la entrada.
Paso 5: Guardar los datos
Ahora abre el archivo save.js y cambia el script como sigue:
import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
return (
<RichText.Content
{ ...blockProps }
tagName="p"
value={ attributes.content }
/>
);
}
Eso es lo que estamos haciendo aquí:
- Importa el componente
RichText
paqueteblock-editor
. - Pasa varias propiedades a través de un argumento de objeto a la función de
save
(en este ejemplo, solo estamos pasando laattributes
propiedad) - Devuelve el contenido del componente
RichText
Puedes leer más sobre el componente RichText
en el Manual del Editor de Bloques y encontrar la lista completa de accesorios en Github
Ahora vamos a dar un paso más. En la siguiente sección, aprenderás a añadir controles a la barra de herramientas del bloque.
Añadir controles a la barra de herramientas del bloque
La barra de herramientas del bloque contiene un conjunto de controles que permiten a los usuarios manipular partes del contenido del bloque. Para cada control de la barra de herramientas, encontrará un componente:
Por ejemplo, puedes añadir un control de alineación de texto para tu bloque. Todo lo que necesitas hacer es importar dos componentes del paquete @wordpress/block-editor
.
Seguiremos los mismos pasos que en el ejemplo anterior:
- Importar los componentes necesarios de los paquetes de WordPress
- Incluir los elementos correspondientes en tu código JSX
- Definir los atributos necesarios en el archivo block.json
- Definir manejadores de eventos
- Guardar datos
Paso 1: Importar los componentes BlockControls y AlignmentControl de @wordpress/block-editor
Para añadir un control de alineación a la barra de herramientas del bloque, necesitas dos componentes:
BlockControls
muestra una barra de herramientas dinámica de controles (no documentada).AlignmentControl
presenta un menú desplegable que muestra las opciones de alineación del bloque seleccionado (más información)
Abre el archivo edit.js y edite la declaración de import
como se muestra a continuación:
import {
useBlockProps,
RichText,
AlignmentControl,
BlockControls
} from '@wordpress/block-editor';
Paso 2: Añadir elementos BlockControls y AlignmentControl
Dirígete a la función Edit
e inserta el elemento <BlockControls />
; al mismo nivel que <RichText />
;. A continuación, añade y <AlignmentControl />
; dentro de <BlockControls />
; :
export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
return (
<>
<BlockControls>
<AlignmentControl
value={ attributes.align }
onChange={ onChangeAlign }
/>
</BlockControls>
<RichText
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
style={ { textAlign: attributes.align } }
/>
</>
);
}
En el código anterior, <>
y </>
son la sintaxis corta para declarar fragmentos de React, que es como devolvemos múltiples elementos en React.
En este ejemplo, AlignmentControl
tiene dos atributos:
value
proporciona el valor actual del elementoonChange
proporciona un controlador de eventos que se ejecuta cuando el valor cambia
También hemos definido atributos adicionales para el elemento RichText
(consulta la lista completa de atributos con ejemplos)
Paso 3: Definir el atributo align en block.json
Ahora ve al archivo block.json y añade el atributo align
:
"align": {
"type": "string",
"default": "none"
}
Cuando termines, vuelve al editor de bloques, actualiza la página y selecciona el bloque. Deberías ver un mensaje de error dentro de tu bloque.
El motivo es que aún no hemos definido nuestro controlador de eventos.
Paso 4: Definir los manejadores de eventos
Ahora define onChangeAlign
:
const onChangeAlign = ( newAlign ) => {
setAttributes( {
align: newAlign === undefined ? 'none' : newAlign,
} )
}
Si newAlign
está undefined
, entonces establecemos newAlign
como none
. En caso contrario, utilizamos newAlign
.
Nuestro script edit.js debería estar completo (por ahora):
export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } )
}
const onChangeAlign = ( newAlign ) => {
setAttributes( {
align: newAlign === undefined ? 'none' : newAlign,
} )
}
return (
<>
<BlockControls>
<AlignmentControl
value={ attributes.align }
onChange={ onChangeAlign }
/>
</BlockControls>
<RichText
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ attributes.content }
placeholder={ __( 'Write your text...' ) }
style={ { textAlign: attributes.align } }
/>
</>
);
}
Ahora puedes volver al editor y alinear el contenido del bloque. Tu bloque debería mostrar con orgullo una Barra de Herramientas de Alineación.
Pero si guardas la entrada, verás que el contenido de tu bloque no está alineado en el front end como lo está en el editor de bloques. Eso es porque tenemos que modificar la función de save
para almacenar el contenido y los atributos del bloque en la base de datos.
Paso 5: Guardar los datos
Abre save.js y cambia la función de save
como sigue:
export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
return (
<RichText.Content
{ ...blockProps }
tagName="p"
value={ attributes.content }
style={ { textAlign: attributes.align } }
/>
);
}
Por último, para hacer el código más legible, puede extraer las propiedades individuales del objeto attribute
utilizando la sintaxis de asignación de desestructuración:
export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
const { content, align } = attributes;
return (
<RichText.Content
{ ...blockProps }
tagName="p"
value={ content }
style={ { textAlign: align } }
/>
);
}
Puedes hacer lo mismo en el archivo edit.js.
Ahora guarda el archivo y cambia al Editor de Código. El código del bloque debería tener el siguiente aspecto:
<!-- wp:ka-example-block/ka-example-block {"align":"right"} -->
<p class="wp-block-ka-example-block-ka-example-block" style="text-align:right">This is my first editable <strong>Gutenberg</strong> <em>block</em> 😎</p>
<!-- /wp:ka-example-block/ka-example-block -->
¡Y eso es todo! Acabas de añadir un control de alineación a la barra de herramientas del bloque 🤓
Puede leer más sobre los controles de la barra de herramientas del bloque en el Manual del Editor de Bloques.
Personalización de la barra lateral de configuración del bloque
También puedes añadir controles a la barra lateral de configuración del bloque (o incluso crear una nueva barra lateral para su aplicación).
La API proporciona un InspectorControls
componente para ello.
El manual del editor de bloques explica cómo utilizar la barra lateral de configuración:
La barra lateral de ajustes se utiliza para mostrar los ajustes menos utilizados o los que requieren más espacio en la pantalla. La barra lateral de configuración debe utilizarse únicamente para los ajustes a nivel de bloque.
Si tiene ajustes que solo afectan al contenido seleccionado dentro de un bloque (por ejemplo, el ajuste de «negrita» para el texto seleccionado dentro de un párrafo): no lo coloques dentro de la barra lateral de ajustes. La barra lateral de configuración se muestra incluso cuando se edita un bloque en modo HTML, por lo que solo debería contener ajustes a nivel de bloque.
Otra vez:
- Importar los componentes necesarios de los paquetes de WordPress
- Incluir los elementos correspondientes en tu código JSX
- Definir los atributos necesarios en el archivo block.json
- Definir manejadores de eventos
- Guardar datos
Paso 1. Importar los componentes InspectorControls y PanelColorSettings de @wordpress/block-editor
Puedes añadir varios controles para que los usuarios puedan personalizar aspectos concretos del bloque. Por ejemplo, puedes proporcionar un panel de control del color. Para ello, tendrás que importar los componentes InspectorControls
y PanelColorSettings
módulo block-editor
:
import {
useBlockProps,
RichText,
AlignmentControl,
BlockControls,
InspectorControls,
PanelColorSettings
} from '@wordpress/block-editor';
Paso 2: Incluir los elementos correspondientes en tu código JSX
Ahora puede añadir los elementos correspondientes al JSX devuelto por la función Edit
:
export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
const { content, align, backgroundColor, textColor } = attributes;
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } )
}
const onChangeAlign = ( newAlign ) => {
setAttributes( {
align: newAlign === undefined ? 'none' : newAlign,
} )
}
return (
<>
<InspectorControls>
<PanelColorSettings
title={ __( 'Color settings', 'ka-example-block' ) }
initialOpen={ false }
colorSettings={ [
{
value: textColor,
onChange: onChangeTextColor,
label: __( 'Text color', 'ka-example-block' )
},
{
value: backgroundColor,
onChange: onChangeBackgroundColor,
label: __( 'Background color', 'ka-example-block' )
}
] }
/>
</InspectorControls>
<BlockControls>
<AlignmentControl
value={ align }
onChange={ onChangeAlign }
/>
</BlockControls>
<RichText
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ content }
placeholder={ __( 'Write your text...' ) }
style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>
</>
);
}
Observa que también hemos actualizado el atributo de style
del elemento RichText
:
<RichText
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
value={ content }
placeholder={ __( 'Write your text...', 'my-affiliate-block' ) }
style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>
Paso 3: Definir los atributos necesarios en block.json
Ahora define los atributos backgroundColor
y textColor
en el archivo block.json:
"attributes": {
"content": {
"type": "string",
"source": "html",
"selector": "p"
},
"align": {
"type": "string",
"default": "none"
},
"backgroundColor": {
"type": "string"
},
"textColor": {
"type": "string"
}
},
Paso 4: Definir los manejadores de eventos
Ahora necesitas definir dos funciones para actualizar backgroundColor
y textColor
en la entrada del usuario:
const onChangeBackgroundColor = ( newBackgroundColor ) => {
setAttributes( { backgroundColor: newBackgroundColor } )
}
const onChangeTextColor = ( newTextColor ) => {
setAttributes( { textColor: newTextColor } )
}
Paso 5: Guardar los datos
Un último paso: Abre el archivo save.js y cambia el script de la siguiente manera:
export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
const { content, align, backgroundColor, textColor } = attributes;
return (
<RichText.Content
{ ...blockProps }
tagName="p"
value={ content }
style={ { textAlign: align, backgroundColor: backgroundColor, color: textColor } }
/>
);
}
Guarda el archivo y comprueba el bloque en el editor. Es posible que te encuentres con una sorpresa no deseada: un mensaje de error que te avisa de que el bloque tiene un contenido inesperado o no válido.
Esto ocurre porque el archivo save.js se ha modificado y el código guardado en la base de datos no coincide con el código utilizado en el editor.
Para solucionarlo, actualiza la página, elimina cualquier instancia de tu bloque y añádelo de nuevo a tu entrada:
Realiza los cambios, guarda la entrada y visualízala en el front end. Ahora los cambios que hiciste en el editor de bloques deberían reflejarse en el front site.
Añadir y personalizar un enlace externo
En esta sección, añadirás nuevos componentes a tu tipo de bloque:
- Un componente
ExternalLink
permite a los usuarios añadir un enlace personalizable a tu bloque personalizado - Varios controles en la barra lateral que permiten a los usuarios personalizar la configuración de los enlaces
Paso 1. Importar componentes desde @wordpress/componentes
Ahora necesitas importar varios componentes de @wordpress/components
. Abre tu archivo edit.js y añade la siguiente declaración de import
:
import {
TextControl,
PanelBody,
PanelRow,
ToggleControl,
ExternalLink
} from '@wordpress/components';
PanelBody
añade un contenedor plegable a la barra lateral de configuración.PaneRow
produce un contenedor genérico para los controles de la barra lateral.TextControl
proporciona un control de entrada de texto.ToggleControl
proporciona una palanca que permite a los usuarios activar/desactivar una opción específicaExternalLink
es un componente sencillo para añadir un enlace externo.
Paso 2. Incluir los elementos correspondientes en su código JSX
En primer lugar, añadirás el elemento ExternalLink
al mismo nivel que RichText
en un contenedor div
:
<div { ...blockProps }>
<RichText
...
/>
<ExternalLink
href={ kaLink }
className="ka-button"
rel={ hasLinkNofollow ? "nofollow" : "" }
>
{ linkLabel }
</ExternalLink>
</div>
El componente ExternalLink
no está documentado, así que nos remitimos al propio componente para obtener la lista de atributos disponibles. Aquí estamos usando los atributos href
, className
y rel
.
Por defecto, el valor del atributo rel
está establecido en noopener noreferrer
. Nuestro código añadirá la nofollow
palabra clave al atributo rel
de la etiqueta a
resultante cuando el control de alternancia esté activado.
Ahora puedes añadir la configuración de los enlaces a la barra lateral del bloque.
En primer lugar, añadirás un elemento PanelBody
dentro de InspectorControls
al mismo nivel que PanelColorSettings
:
<InspectorControls>
<PanelColorSettings
...
/>
<PanelBody
title={ __( 'Link Settings' )}
initialOpen={true}
>
...
</PanelBody>
</InspectorControls>
Esto es lo que estamos haciendo con esto:
- El atributo
title
proporciona el título del panel. initialOpen
establece si el panel está abierto inicialmente o no.
A continuación, añadiremos dos elementos PanelRow
dentro de PanelBody
, y un elemento TextControl
dentro de cada PanelRow
:
<PanelBody
title={ __( 'Link Settings', 'ka-example-block' )}
initialOpen={true}
>
<PanelRow>
<fieldset>
<TextControl
label={__( 'KA link', 'ka-example-block' )}
value={ kaLink }
onChange={ onChangeKaLink }
help={ __( 'Add your Academy link', 'ka-example-block' )}
/>
</fieldset>
</PanelRow>
<PanelRow>
<fieldset>
<TextControl
label={__( 'Link label', 'ka-example-block' )}
value={ linkLabel }
onChange={ onChangeLinkLabel }
help={ __( 'Add link label', 'ka-example-block' )}
/>
</fieldset>
</PanelRow>
</PanelBody>
El código anterior debería ser bastante sencillo. Los dos controles de texto permiten a los usuarios establecer la etiqueta del enlace y la URL.
También añadiremos un PanelRow
adicional con un ToggleControl
para activar/desactivar una opción específica, como por ejemplo, incluir o no un atributo:
<PanelRow>
<fieldset>
<ToggleControl
label="Add rel = nofollow"
help={
hasLinkNofollow
? 'Has rel nofollow.'
: 'No rel nofollow.'
}
checked={ hasLinkNofollow }
onChange={ toggleNofollow }
/>
</fieldset>
</PanelRow>
Paso 3: Definir los atributos necesarios en block.json
Ahora define los atributos kaLink
, linkLabel
y hasLinkNofollow
en el archivo block.json:
"kaLink": {
"type": "string",
"default": ""
},
"linkLabel": {
"type": "string",
"default": "Check it out!"
},
"hasLinkNofollow": {
"type": "boolean",
"default": false
}
No hay nada más que añadir aquí. Pasemos a definir las funciones de manejo de eventos.
Paso 4: Definir los manejadores de eventos
Get back to the edit.js file, add the new attributes to the attributes object, and add the following functions:
const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;
const onChangeKaLink = ( newKaLink ) => {
setAttributes( { kaLink: newKaLink === undefined ? '' : newKaLink } )
}
const onChangeLinkLabel = ( newLinkLabel ) => {
setAttributes( { linkLabel: newLinkLabel === undefined ? '' : newLinkLabel } )
}
const toggleNofollow = () => {
setAttributes( { hasLinkNofollow: ! hasLinkNofollow } )
}
Estas funciones actualizan los valores de los atributos correspondientes a la entrada del usuario.
Paso 5: Guardar los datos
Por último, tenemos que actualizar la función de save
en save.js:
export default function save( { attributes } ) {
const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;
const blockProps = useBlockProps.save( {
className: `has-text-align-${ align }`
} );
return (
<div
{ ...blockProps }
style={ { backgroundColor: backgroundColor } }
>
<RichText.Content
tagName="p"
value={ content }
style={ { color: textColor } }
/>
<p>
<a
href={ kaLink }
className="ka-button"
rel={ hasLinkNofollow ? "nofollow" : "noopener noreferrer" }
>
{ linkLabel }
</a>
</p>
</div>
);
}
Ten en cuenta que aquí hemos utilizado un elemento a
normal en lugar de ExternalLink
.
Puedes ver el resultado en la imagen de abajo.
Ahora guarda los datos y reinicia tu entorno.
Añadir varios estilos de bloque
En una sección anterior, aprendiste a añadir un control de barra de herramientas de bloque que permite a los usuarios alinear la entrada del usuario. Podemos añadir más controles de estilo a la barra de herramientas de bloque, pero también podemos proporcionar un conjunto de estilos de bloque predefinidos que el usuario puede elegir con un solo clic.
Para ello, vamos a utilizar una útil función de la API de bloques: Estilos de bloque.
Todo lo que tienes que hacer es definir la propiedad de styles
block.json y declarar los estilos correspondientes en tus hojas de estilo.
Por ejemplo, puedes añadir la siguiente serie de estilos:
"styles": [
{
"name": "default",
"label": "Default",
"isDefault": true
},
{
"name": "border",
"label": "Border"
}
],
Con esto, acabas de añadir un estilo por defecto y un estilo adicional llamado border
. Ahora vuelve al editor de bloques:
Los estilos estarán disponibles para el usuario haciendo clic en el conmutador de bloques y buscando el panel de Estilos en la barra lateral de configuración de bloques.
Selecciona un estilo y compruebe las clases aplicadas al elemento p
. Haz clic con el botón derecho del ratón en el bloque e inspecciona. Se ha añadido una nueva clase con un nombre estructurado de la siguiente manera:
is-style-{style-name}
Si ha marcado el estilo «Borde», se añadirá una clase is-style-border
al elemento p
. Si ha marcado el estilo «Predeterminado», se añadirá una clase is-style-default
en su lugar.
Ahora solo tienes que declarar las propiedades CSS. Abre el archivo editor.scss y sustituye los estilos actuales por los siguientes:
.wp-block-ka-example-block-ka-example-block {
padding: 4px;
}
Ahora puedes hacer lo mismo con style.scss. Como mencionamos anteriormente, los estilos definidos en style.scss se aplican tanto en el front end como en el editor:
.wp-block-ka-example-block-ka-example-block {
&.is-style-default{
border: 0;
background-color: #FFE2C7;
}
&.is-style-border{
border: 2px solid #000;
border-radius: 16px;
background-color: #F6F6F6;
}
}
Y ya está. Actualiza la página y diviértete con tus nuevos estilos de bloques:
Anidación de bloques Gutenberg con el componente InnerBlocks
Although fully functional, our custom block is still not very appealing. Para hacerlo más atractivo para el público, podríamos añadir una imagen.
Esto puede añadir una capa de complejidad a nuestro bloque, pero, afortunadamente, no es necesario reinventar el mundo porque Gutenberg proporciona un componente específico que puedes utilizar para crear una estructura de bloques anidados.
El componente InnerBlocks
se define como sigue:
InnerBlocks
exporta un par de componentes que pueden utilizarse en las implementaciones de bloques para permitir el contenido de bloques anidados.
En primer lugar, tendrás que crear un nuevo archivo .js en la carpeta src. En nuestro ejemplo, llamaremos a este archivo container.js.
Ahora tendrás que importar el nuevo recurso en el archivo index.js:
import './container';
Vuelve a container.js e importa los componentes necesarios:
import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import {
useBlockProps,
InnerBlocks
} from "@wordpress/block-editor";
El siguiente paso es definir una plantilla que proporcione la estructura dentro de la cual se colocarán los bloques. En el siguiente ejemplo, definimos una plantilla que consta de dos columnas que contienen un bloque de imagen principal y nuestro bloque personalizado:
const TEMPLATE = [ [ 'core/columns', { backgroundColor: 'yellow', verticalAlignment: 'center' }, [
[ 'core/column', { templateLock: 'all' }, [
[ 'core/image' ],
] ],
[ 'core/column', { templateLock: 'all' }, [
[ 'ka-example-block/ka-example-block', { placeholder: 'Enter side content...' } ],
] ],
] ] ];
La plantilla está estructurada como una matriz de blockTypes (nombre del bloque y atributos opcionales).
En el código anterior, hemos utilizado varios atributos para configurar los bloques Columnas y Columnas. En concreto, el atributo templateLock: 'all'
bloquea los bloques Column para que el usuario no pueda añadir, reordenar o eliminar los bloques existentes. templateLock
puede tomar uno de los siguientes valores:
all
—InnerBlocks
está bloqueado, y no se pueden añadir, reordenar o eliminar bloques.insert
— Los bloques sólo pueden ser reordenados o eliminados.false
— – La plantilla no está bloqueada.
La plantilla se asigna entonces al elemento InnerBlocks
:
<InnerBlocks
template={ TEMPLATE }
templateLock="all"
/>
Para evitar cualquier problema de compatibilidad, también hemos añadido un atributo templateLock
al componente InnerBlocks
(véanse también el problema #17262 y el pull #26128).
Aquí está nuestro archivo container.js final:
registerBlockType('ka-example-block/ka-example-container-block', {
title: __( 'KA Container block', 'ka-example-block' ),
category: 'design',
edit( { className } ) {
return(
<div className={ className }>
<InnerBlocks
template={ TEMPLATE }
templateLock="all"
/>
</div>
)
},
save() {
const blockProps = useBlockProps.save();
return(
<div { ...blockProps }>
<InnerBlocks.Content />
</div>
)
},
});
Mejoras adicionales
Nuestro bloque es totalmente funcional, pero podríamos mejorarlo un poco con algunos pequeños cambios.
Hemos asignado el atributo backgroundColor
al párrafo generado por el componente RichText
. Sin embargo, podemos preferir asignar el color de fondo al div
contenedor:
Por lo tanto, cambie el archivo edit.js y los div
s save.js como sigue:
<div
{ ...blockProps }
style={ { backgroundColor: backgroundColor } }
>
...
</div>
Esto permitirá al usuario cambiar el fondo de todo el bloque.
Por otro lado, un cambio más relevante tiene que ver con el método useBlockProps
. En el código original, definimos la constante blockProps
como sigue:
const blockProps = useBlockProps();
Pero podemos utilizar el useBlockProps
de forma más efectiva pasando un conjunto de propiedades. Por ejemplo, podemos importar classnames
del módulo classnames
y establecer el nombre de la clase envolvente en consecuencia.
En el siguiente ejemplo, asignamos un nombre de clase basado en el valor del atributo align
(edit.js).
import classnames from 'classnames';
...
export default function Edit( { attributes, setAttributes } ) {
...
const onChangeAlign = ( newAlign ) => {
setAttributes( {
align: newAlign === undefined ? 'none' : newAlign,
} )
}
const blockProps = useBlockProps( {
className: `has-text-align-${ align }`
} );
...
}
Haremos el mismo cambio en el archivo save.js:
import classnames from 'classnames';
...
export default function save( { attributes } ) {
...
const { content, align, backgroundColor, textColor, kaLink, linkLabel, hasLinkNofollow } = attributes;
const blockProps = useBlockProps.save( {
className: `has-text-align-${ align }`
} );
...
}
Y eso es todo. Ahora puede ejecutar la construcción para la producción:
npm run build
Resumen
Y aquí estamos, ¡al final de este increíble viaje! Empezamos con la configuración del entorno de desarrollo y terminamos creando un tipo de bloque completo.
Como mencionamos en la introducción, un conocimiento sólido de Node.js, Webpack, Babel y React son esenciales para crear bloques avanzados de Gutenberg y posicionarse en el mercado como desarrollador profesional de Gutenberg.
Sin embargo, no es necesario tener una experiencia establecida en React para empezar a divertirse con el desarrollo de bloques. El desarrollo de bloques podría darte motivación y objetivos para adquirir habilidades cada vez más amplias en las tecnologías que hay detrás de los bloques de Gutenberg.
Esta guía, por lo tanto, está lejos de ser completa. Es simplemente una introducción a una amplia variedad de temas que te ayudarán a empezar a construir tus primeros bloques de Gutenberg.
Por ello, te recomendamos que profundices tus conocimientos leyendo detenidamente la documentación y las guías en línea. Entre los muchos recursos disponibles ahí fuera, te recomendamos los siguientes:
- Tutorial oficial de creación de un bloque para principiantes
- Tutorial oficial de bloques para desarrolladores intermedios
- Bloques dinámicos
- How to Create Dynamic Blocks for Gutenberg
- Meta Cajas
- Creación de una barra lateral para su plugin
Si estás empezando con el desarrollo de WordPress, es posible que quieras entender los conceptos básicos del desarrollo del frontend. Aquí hay una lista rápida de recursos que pueden ayudarte a empezar:
- Cómo instalar WordPress localmente (ebook gratuito)
- El valor real del alojamiento gestionado de WordPress (ebook gratuito)
- ¿Qué es JavaScript?
- HTML frente a HTML5
- Cómo editar el CSS en WordPress
- ¿Qué es PHP?
- El curso de capacitación sobre ganchos de WordPress: Cómo utilizar acciones, filtros y ganchos personalizados
Y recuerda que el código completo de los ejemplos de esta guía está disponible en Gist.
Ahora es tu turno: ¿Has desarrollado algún bloque de Gutenberg? ¿Cuáles son las principales dificultades que has experimentado hasta ahora? Cuéntanos tu experiencia en los comentarios!
Deja una respuesta