Publicado el 9 de mayo, 2023 en Programación
Este artículo intenta ordenar un poco las ideas de un bloque dinámico de Gutenberg, toda la información que ahora mismo está un poco dispersa, recopilada de lo que me habría gustado saber la primera vez que cree uno, explicado paso a paso.
El nuevo editor para WordPress Gutenberg ha llegado para quedarse, esa es la realidad, poco a poco la comunidad desarrolladora lo va asumiendo y aceptando. También ayuda las mejoras que ha recibido el editor visual propio de WordPress en los últimos tiempos, nada que ver con sus inicios.
De aquí que cada vez haya más desarrolladores/as que han empezado a migrar sus plantillas y extensiones de shortcodes o componentes de otros editores visuales como Elementor y Visual Composer a Gutenberg.
¿Qué es un bloque dinámico?
A diferencia de un bloque normal o estático, un bloque dinámico es aquel que requiere de información de la base de datos para mostrar su contenido.
Un ejemplo fácil de este tipo de bloques es si queremos mostrar las últimas entradas de nuestro blog, un listado de los usuarios registrados o por ejemplo un portafolio creado con un Custom Post (que es el ejemplo que vamos a realizar en este tutorial).
El bloque dinámico nos permite definir lo que queremos mostrar, pero a su vez que este contenido se actualice automáticamente cuando se ha modificado / añadido un nuevo elemento que cumpla sus condiciones
Preparando el entorno
Este tutorial da por hecho que tienes unos conocimientos básicos de WordPress, PHP, Javascript y React (Gutenberg funciona sobre React) y que dispones de un entorno de desarrollo local con una instalación de WordPress activa
Por último vas a necesitar Node.js instalado en tu ordenador para poder ejecutar el script de creación de bloques de WordPress
Creando el plugin para nuestro bloque
En este tutorial damos por sentado que dispones de un tipo de post portfolio
que has registrado previamente con register_post_type()
, si quieres puedes seguir los mismos pasos cambiando el post_type
por el que tú prefieras o por post
o page
para mostrar las entradas o páginas nativas de WordPress
El primer paso de crear un bloque dinámico es el mismo que un bloque estático, vamos a crear un plugin que contenga todo el código de nuestro bloque.
Para ello utilizaremos la librería que ha creado WordPress para esto mismo
Primero abrimos la terminal de nuestro ordenador y navegamos a la carpeta de plugins de nuestro WordPress
cd wp-content/plugins
Una vez dentro de la carpeta vamos a ejecutar la librería
npx @wordpress/create-block
Confirmamos con Y, esto ejecuta el script en modo interactivo, este nos irá haciendo preguntas sobre la configuración de nuestro plugin y bloque, los pasos son:
- El tipo de bloque: Por defecto viene seleccionado estático, pero en este caso elegiremos dinámico
- El «slug» del bloque: El identificador único del plugin y a su vez nombre de la carpeta
- «Namespace» interno: El identificador único nuestro como autores del bloque
- «Display title«: Título del bloque
- Descripción del bloque
- Icono
- Categoría: Donde se mostrará el bloque dentro del listado de bloques disponibles
- Deseas customizar el plugin: Ponemos que no
Después de esto dejamos que el script instale todo lo necesario, una vez terminado ya tendremos los archivos disponibles
En nuestro caso hemos llamado al plugin utrans-blocks
por lo que en los siguientes pasos cuando veas utrans-blocks
debes reemplazarlo por el nombre de tu plugin.
Entramos en la carpeta de nuestro plugin con:
cd utrans-blocks
Y para poder empezar a trabajar arrancamos el proyecto con
npm start
Con todo esto, ya podemos activar nuestro bloque y a añadirlo a una de nuestras páginas


¡Listo! Ahora que ya tenemos nuestro plugin creado, vamos a darle funcionalidades
La estructura de un bloque dinámico de Gutenberg
Todo lo que nos interesa modificar de nuestro bloque se encuentra dentro de la carpeta src
, como tenemos el proceso de node arrancado en nuestro terminal, cada vez que hagamos un cambio en esta, el proceso generará los archivos de la build

La principal diferencia de estructura entre un bloque estático y uno dinámico es que este segundo cuenta con un archivo render.php para mostrar el bloque en la parte pública de nuestro sitio web
Mientras que un bloque estático contará con un archivo JavaScript
Añadiendo parámetros al backoffice
Digamos que nuestra idea es crear un porfolio en formato grid y queremos que el usuario pueda configurar el número de proyectos a mostrar y en cuantas columnas
Lo primero que tenemos que hacer es declarar estos dos atributos para nuestro bloque, esto lo haremos dentro del block.json
Debemos añadir un nuevo parámetro dentro del json con los atributos que queremos añadir, por ejemplo:
...
"attributes": {
"numberOfItems": {
"type": "number",
"default": 8
},
"columns": {
"type": "number",
"default": 4
}
}
Con estos parámetros le estoy diciendo al bloque que quiero un atributo numérico numberOfItems
con valor por defecto 8 y un atributo columns
, también numérico, con valor por defecto 4
Mostrado los items del portfolio en el backoffice
Toda la visualización y configuración de la parte del backoffice del bloque se hace dentro del edit.js
De momento vamos a hacer que el bloque recoja nuestros últimos proyectos publicados en el porfolio
Primero añadimos useSelect como dependencia
import { useSelect, useDispatch } from '@wordpress/data';
Después modificamos la función Edit
de la siguiente manera
export default function Edit( { attributes } ) {
const { numberOfItems } = attributes;
const portfolio = useSelect(
( select ) => {
return select( 'core' ).getEntityRecords( 'postType', 'portfolio', {
'per_page': numberOfItems
});
},
[ numberOfItems ]
);
console.log(portfolio);
}
Vamos por partes, la función Edit
, recibe los atributos que hemos definido previamente en el block.json
, de momento solo recogemos el numberOfItems
para utilizarlo en el useSelect
.
El useSelect, recibe dos parámetros, el primero la función en la que le indicamos que queremos que nos devuelva los tipos de post porfolio, limitados al número de items de numberOfItems
El segundo parámetro es una array de dependencias de las variables que queremos que useSelect
tenga en cuenta, que si se modifican requiere que refresque los resultados obtenidos
Ahora añadimos una función .map, para realizar un bucle con los proyectos y mostrarlos
export default function Edit( { attributes } ) {
const { numberOfItems, columns } = attributes;
const portfolio = useSelect(
( select ) => {
return select( 'core' ).getEntityRecords( 'postType', 'portfolio', {
'per_page': numberOfItems
});
},
[ numberOfItems ]
);
return (
<div { ...useBlockProps() }>
<ul class="portfolio portfolio-cols--{ columns }">
{ porfolio && porfolio.map( ( project ) => {
return (
<li key={ project.id }>
<h3>
<a href={ project.link }>
{ project.title }
</a>
</h3>
</li>
)
})}
</ul>
</div>
);
}
Añadiendo campos para modificar los atributos
Ahora vamos a añadir dos controles para nuestro bloque que nos permita modificar el número de ítems del porfolio a mostrar y el número de columnas.
El número de ítems lo crearemos como un campo de número, mientras que las columnas será un desplegable con opciones cerradas, para ello primero debemos importar los componentes por los tipos de campo necesarios.
Como queremos mostrar estos campos en la barra lateral (InspectorControls
), también debemos importar este y los componentes del panel de la siguiente forma
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, PanelRow, SelectControl, TextControl } from '@wordpress/components';
Ahora vamos a modificar la función Edit
para mostrar los dos nuevos campos
export default function Edit( { attributes, setAttributes } ) {
const { numberOfItems, columns } = attributes;
const portfolio = useSelect(
( select ) => {
return select( 'core' ).getEntityRecords( 'postType', 'portfolio', {
'per_page': numberOfItems
});
},
[ numberOfItems ]
);
return (
<>
<InspectorControls>
<PanelBody title={ __( "Portfolio display options", 'utrans-portfolio' ) }>
<PanelRow>
<SelectControl
label={ __( "Number of columns", 'utrans-portfolio' ) }
value={ attributes.columns }
options={ [
{ label: 'One column', value: 1 },
{ label: 'Two columns', value: 2 },
{ label: 'Three columns', value: 3 },
{ label: 'Four columns', value: 4 }
] }
onChange={ ( val ) => setAttributes( { operation: val } ) }
__nextHasNoMarginBottom
/>
</PanelRow>
<PanelRow>
<TextControl
label={ __( "Number of items", 'utrans-portfolio' ) }
onChange={ ( val ) => setAttributes( { number: val } ) }
type="number"
min="0"
value={ attributes.numberOfItems }
/>
</PanelRow>
</PanelBody>
</InspectorControls>
<div { ...useBlockProps() }>
<ul class="portfolio portfolio-cols--{ columns }">
{ porfolio && porfolio.map( ( project ) => {
return (
<li key={ project.id }>
<h3>
<a href={ project.link }>
{ project.title }
</a>
</h3>
</li>
)
})}
</ul>
</div>
</>
);
}
Como podemos ver hemos creado un componente de InspectorControls
con un PanelBody
y después un PanelRow
por cada campo que queramos añadir
En cuanto se modifica un campo se lanza la función setAttribute
que guardará el nuevo valor
Con esto listo, vamos a trabajar la parte pública de nuestro bloque
Mostrando nuestro porfolio en la parte pública de nuestra web
En un bloque dinámico, el encargado de renderizar este en la parte pública es el archivo render.php
y podemos utilizar todas las funciones de WordPress
Este archivo recibe una variable especial $attributes
que dispone del valor de los atributos que hayamos configurado en el editor
Para renderizar los elementos del porfolio vamos a realizar una WP_Query
, usando el atributo numberOfItems
para definir el número de elementos y el atributo columns
para utilizarlo como nombre de clase CSS y poder darle estilos a posteriori
<?php
$number = isset($attributes['numberOfItems']) ? $attributes['numberOfItems'] : 8;
$columns = isset($attributes['columns']) ? $attributes['columns'] : 4;
$args = [
'post_type' => 'portfolio',
'posts_per_page' => $number,
];
$the_query = new WP_Query( $args );
?>
<div <?php echo get_block_wrapper_attributes(); ?>>
<ul class="portfolio portfolio--cols--<?php echo $columns; ?>">
<?php
// The Loop
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post(); ?>
<li class="portfolio__item">
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a>
</li>
<?php
}
}
// Restore original Post Data
wp_reset_postdata();
?>
</ul>
</div>
¿Dónde ponemos los estilos CSS?
Dentro del directorio del bloque encontramos dos archivos de estilos stye.scss
y editor.scss
Los estilos que definíamos en el style.scss se cargaran tanto en el editor como en el frontal de la web, mientras que los estilos definidos en el editor.scss solo se cargaran en el editor de Gutenberg
Vemos que la extensión de los archivos es .scss, Node i Webpack se encargan de procesar estos estilos a CSS puro, por lo que podemos escribir nuestro CSS en formato SCSS con todas las ventajas que este incluye, si no estás familiarizado/a con SCSS, haz clic aquí
Vamos a añadir algo de estilos a nuestro porfolio
.wp-block-utrans-portfolio-utrans-blocks {
.portfolio {
display: grid;
grid-template-columns: repeat(1, minmax(0, 1fr));
gap: 1rem;
&--cols--2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
&--cols--3 {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
&--cols--4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
}
¿Y ahora qué?
Este tutorial pretende ser una introducción a la creación de bloques dinámicos de Gutenberg, puedes ampliar mejorado la visualización de la parte frontal o añadiendo nuevos parámetros de personalización en el editor
Te dejo con algunos enlaces relevantes que me han ayudado en estos primeros pasos:
Deja una respuesta