Si eres desarrollador WordPress, seguro te has topado con este dilema: el cliente quiere animaciones Lottie, pero los plugins existentes añaden bloques personalizados pesados o requieren suscripciones.
En LaboratorioWP nos preguntamos: ¿Por qué crear un bloque nuevo si el bloque de Imagen ya existe?
Hoy te voy a enseñar, paso a paso, cómo programamos nuestro plugin «Lottie Image Extender». Vamos a «hackear» (en el buen sentido) el bloque nativo core/image utilizando los filtros de JavaScript de Gutenberg y un poco de ingenio con CSS.
Lo mejor: No necesitas compilar nada (No webpack, no NPM). Usaremos Vanilla JS compatible con el navegador.
La Arquitectura del Plugin
Para lograr esto, necesitamos atacar tres frentes:
- PHP: Permitir la subida de archivos
.json(WordPress los bloquea por defecto) y cargar los scripts. - JS (Editor): Inyectar controles extra en el bloque de imagen para seleccionar el JSON.
- UX (La parte difícil): Lograr que la animación se previsualice en el editor sin romper la capacidad de seleccionar el bloque.
Paso 1: Preparando el terreno (PHP)
Lo primero es crear la estructura de carpetas. Solo necesitamos dos archivos:
lottie-image-extender.phpblock-extensions.js
En el archivo PHP, lo vital es el filtro upload_mimes. WordPress es muy estricto con los archivos JSON por seguridad.
function lie_permitir_json_mimes( $mimes ) {
$mimes['json'] = 'application/json';
return $mimes;
}
add_filter( 'upload_mimes', 'lie_permitir_json_mimes' );
También necesitamos interceptar el renderizado en el frontend (render_block). Si el bloque tiene nuestro atributo lottieUrl, sustituimos la etiqueta <img> por el componente <lottie-player>.
Paso 2: Extendiendo Gutenberg con Filtros (JS)
Aquí es donde ocurre la magia. No vamos a registrar un bloque (registerBlockType), vamos a filtrar uno existente.
Usamos wp.hooks.addFilter para añadir nuestros atributos al bloque core/image:
javascript
function addLottieAttribute(settings, name) {
if (name !== 'core/image') return settings;
// Añadimos lottieUrl, loop, speed, etc.
settings.attributes = Object.assign({}, settings.attributes, {
lottieUrl: { type: 'string', default: '' },
// ... otros atributos
});
return settings;
}
Y luego usamos un Higher Order Component (HOC) para envolver el componente visual del bloque (BlockEdit) y añadirle nuestro panel de control en la barra lateral (InspectorControls).
Paso 3: El reto del «Bloque Fantasma» (UX)
Este fue el desafío más grande durante el desarrollo.
Si simplemente reemplazas la imagen por el reproductor Lottie en el editor, Gutenberg pierde la referencia del bloque. Al hacer clic en la animación, el editor no sabe que estás intentando seleccionar el bloque de imagen, y la barra de herramientas desaparece.
¿La solución? El patrón del «Bloque Fantasma» con CSS.
La estrategia que implementamos fue la siguiente:
- Capa 1 (Fondo): Renderizamos el
<lottie-player>con unz-index: 1. Es lo que el usuario ve. - Capa 2 (Interacción): Mantenemos el componente original del bloque de imagen encima, pero con Opacidad 0 y
position: absolute.
var nativeBlockOverlay = el('div', {
style: {
position: 'absolute',
opacity: 0, // Invisible a la vista
zIndex: 10, // Pero está encima para recibir el clic
width: '100%',
height: '100%'
}
}, el(BlockEdit, props));
De esta forma, cuando haces clic en la animación, técnicamente estás haciendo clic en el bloque de imagen invisible. Gutenberg detecta el clic, selecciona el bloque y muestra las herramientas de alineación. ¡Problema resuelto!
Paso 4: Inyección de Estilos
Como no tenemos control total sobre el HTML que genera el bloque nativo dentro de nuestro contenedor invisible, usamos un pequeño «parche CSS» inyectado con Javascript para forzar al figure a ocupar el 100% de la altura.
var cssPatch = el('style', {}, `
.lottie-native-block-overlay figure.wp-block-image {
height: 100% !important;
}
`);
Resultado Final
Al juntar estas piezas, obtenemos un plugin que:
- Pesa menos de 5kb (sin contar la librería del player).
- No añade bloques nuevos a la lista del usuario.
- Mantiene la compatibilidad con los estilos de alineación y espaciado de tu tema.
Es un ejemplo perfecto de cómo el desarrollo en WordPress moderno se trata más de extender y adaptar que de reinventar la rueda constantemente.
Glosario Técnico del Tutorial
Para entender mejor el código:
- Higher Order Component (HOC): En React (y Gutenberg), es una función que toma un componente y devuelve un nuevo componente con funcionalidades añadidas. Es como ponerle una «armadura» a un componente existente.
- Hooks (wp.hooks): Son el equivalente en Javascript a los
add_actionyadd_filterde PHP. Nos permiten modificar el comportamiento del editor sin tocar el núcleo. - Vanilla JS: Javascript puro, sin librerías extra ni necesidad de compiladores como Webpack o Babel.
- MIME Type: Identificador del formato de archivo. WordPress bloquea
application/jsonpor defecto, así que debemos «ponerlo en la lista blanca» mediante PHP. - Z-Index: Propiedad CSS que determina el orden de apilamiento de los elementos. Un z-index mayor significa que el elemento está «más cerca» del usuario (encima de los otros).
- Stacking Context: El contexto de apilamiento. Es cómo el navegador decide qué capa va encima de cuál. Fundamental para nuestro truco del «Bloque Fantasma».


