Skip to main content

Como añadir un metabox en React a Gutenberg

Publicado hace
Actualizado hace
4 minutos de lectura

Recientemente me vi en la necesidad de agregar controles al editor de bloques de WordPress, o Gutenberg como también se le llama al proyecto, esto normalmente es muy sencillo pero tenía un par de complejidades que no había visto antes:

  1. Debía tener controles en React y
  2. Debía posicionarse en la parte inferior del editor

Estos requisitos por si mismos no son mayor problema, pero juntos era algo que no se acostumbra a hacer.

El problema

El asunto aquí es que es sencillo hacer ambas cosas por separado, podemos agregar un nuevo plugin al editor y mostrarlo en la parte lateral (el sidebar), ó, podemos agregar un metabox con PHP y se mostrará automáticamente en la parte inferior del editor.

¿Ven el problema? No hay forma de agregar un plugin de Gutenberg en la parte inferior, y no podemos agregar controles React en PHP.

…¿O si?

La solución

Resulta que la solución es mucho más simple de lo que pensaba, lo que necesitamos es una combinación de ambas para que esto funcione, básicamente, podemos hacer lo siguiente.

  1. Crear un metabox que aparezca en la parte inferior de la página, este únicamente mostrará un contenedor
  2. Creamos un plugin de Gutenberg con la funcionalidad react que necesitamos, este se mostrará en el sidebar por defecto
  3. Creamos un portal que mueva nuestro componente en React a nuestro contenedor dentro del metabox

¡Esa es la magia! Ahora veamos como podemos hacerlo con código.

Note

¿Portal?

Esto merece su propio post, pero a grandes rasgos los portales nos permiten mover partes de nuestros componentes a cualquier sitio dentro del DOM, pero mantienen su estructura dentro de nuestra aplicación en React.

Registrar un Metabox en WordPress

Ahora, si queremos hacerlo con código, lo primero que debemos hacer es crear un Plugin que agregue nuestro metabox:

1<?php
2
3/**
4 * Plugin Name: Mah React metabox
5 * Author: Mario Aguiar
6 * Author URI: https://www.marioaguiar.net
7 * Plugin URI: https://www.marioaguiar.net
8 * Version: 1.0
9 */
10
11namespace Mah;
12
13/**
14 * Maneja las funcionalidades de metabox
15 */
16class Metabox
17{
18 /**
19 * Agrega los hooks necesarios
20 *
21 * @return void
22 */
23 public function init(): void
24 {
25 add_action('add_meta_boxes', [$this, 'register_metabox']);
26 }
27
28 /**
29 * Agrega un metabox
30 *
31 * @return void
32 */
33 public function register_metabox(): void
34 {
35 add_meta_box(
36 'mah-metabox',
37 __('Mah metabox'),
38 function () {
39 echo "<div id='mah-metabox-content'></div>";
40 },
41 null,
42 'normal',
43 'high'
44 );
45 }
46}
47
48(new Metabox())->init();
49

Esto lo que hará será agregar un nuevo metabox al editor de blocks, si no fijamos bien, podemos adivinar que está vacío (aunque más bien simplemente no tiene texto), algo así:

Imagen del metabox vacío

Registrar un Plugin en Gutenberg

Esto nos servirá como el contenedor de nuestro componente en React, ahora, para nuestro componente podemos agregar un nuevo archivo, simplemente creamos un plugin de Gutenberg utilizando registerPlugin:

1/**
2 * WordPress dependencies
3 */
4import { registerPlugin } from '@wordpress/plugins';
5import { PluginDocumentSettingPanel } from '@wordpress/editor';
6
7registerPlugin( 'mah-metabox', {
8 render: () => {
9 return (
10 <PluginDocumentSettingPanel
11 name="mah-metabox"
12 title="Mah Metabox"
13 >
14 <h2>Mah Metabox</h2>
15 </PluginDocumentSettingPanel>
16 );
17 },
18} );
19

No olvidemos agregar nuestro archivo al editor:

1/**
2 * Agrega los hooks necesarios
3 *
4 * @return void
5 */
6public function init(): void
7{
8 // …
9 add_action('enqueue_block_editor_assets', [$this, 'enqueue_assets']);
10}
1/**
2 * Agrega los scripts y dependencias en nuestro plugin
3 *
4 * @return void
5 */
6public function enqueue_assets(): void
7{
8 $asset_file = include plugin_dir_path(__FILE__) . 'build/index.asset.php';
9
10 wp_enqueue_script(
11 'mah-metabox',
12 plugin_dir_url(__FILE__) . 'build/index.js',
13 $asset_file['dependencies'],
14 $asset_file['version'],
15 true
16 );
17}

Y el resultado sería algo así:

Imagen del plugin en el sidebar

Ahora tenemos los dos componentes que necesitamos, y estamos preparados para juntarlos.

Important

¿Qué es PluginDocumentSettingPanel?

Este es un componente de Gutenberg que nos permite agregar controles al editor de bloques, en este caso lo estamos utilizando para mostrar nuestro componente en el sidebar.

A pesar de lo que esto podría hacernos pensar (y lo sencillo que sería hacer todo esto), no existe una alternativa que nos permita mostrar nuestro componente en la parte inferior del editor.

Juntando el plugin de Gutenberg con nuestro Metabox

Por fortuna, esto es increiblemente sencillo gracias al anteriormente mencionado createPortal, simplemente necesitamos modificar nuestro plugin para crear un portal y enviar nuestro componente a través de ese portal:

1/**
2 * WordPress dependencies
3 */
4import { createPortal } from '@wordpress/element';
5import { registerPlugin } from '@wordpress/plugins';
6
7const Metabox = () => (
8 <h2>Mah Metabox</h2>
9);
10
11const MetaboxPortal = () => (
12 createPortal(
13 <Metabox />,
14 document.querySelector( '#mah-metabox-content' )
15 )
16);
17
18registerPlugin( 'mah-metabox', {
19 render: MetaboxPortal,
20} );

¡Listo! Eso es todo lo que necesitamos, lo que estamos haciendo es crear un portal hacia nuestro elemento con id mah-metabox, así, cuando React ejecute MetaboxPortal sabrá que tiene que enviar su contenido a través del portal, y terminará mostrando nuestro componente justo en el lugar que necesitamos, que es nuestro metabox:

Imagen del componente dentro de nuestro metabox

Conclusión

Esto resulta bastante útil cuando necesitamos más espacio del que nuestra sidebar puede darnos, un buen ejemplo es el plugin Yoast SEO que muestra la información del post debajo del editor, lo cual hace que editarlo sea mucho más sencillo.

Una vez seguidos todos estos pasos, sólo necesitamos agregar nuestros controles como si estuvieramos trabajando en cualquier otro proyecto de React, y listo, ya tenemos un metabox en React en Gutenberg. Con la ventaja de poder acceder a los datos del post y modificarlos directamente desde nuestro componente a travez de los componentes en @wordpress/data.

Imagen del plugin en el editor

Leer más