WordPress Interactivity API

La Interactivity API ha revolucionado la forma de crear bloques en WordPress, simplificando y estandarizando la incorporación de acciones y eventos con JavaScript en el frontend de nuestros bloques, eliminando la necesidad de añadir JavaScript o jQuery manualmente.

A continuación, exploraremos cómo funciona esta API aplicándola a un bloque, explicándolo paso a paso y utilizando el mismo ejemplo del post anterior. Mucho del código será reutilizado, pero la idea es entender cómo esta nueva herramienta cambia nuestra forma de desarrollo. En futuros posts, probaremos otras funcionalidades y opciones de configuración.

Creando el bloque

Al igual que en el post anterior, omitiremos la parte de crear el bloque desde cero y utilizaremos la herramienta @wordpress/create-block, que nos crea todo el scaffolding del plugin y el bloque.

En la carpeta wp-content/plugins, ejecutaremos el siguiente comando:


npx @wordpress/create-block BeforeAfterImagesI --template @wordpress/create-block-interactive-template
cd beforeafterimagesi
npm start

Esto creará una estructura con todas las opciones para usar la Interactivity API. Para observar las diferencias, comencemos por el archivo src/block.json:

"supports": {
	"interactivity": true
},

Esta linea activa la Interactivity API y la deja disponible para su utilización y también agrega el archivo:

"render": "file:./render.php",

La línea "interactivity": true activa la Interactivity API y la deja disponible para su utilización. Además, se agrega la línea "render": "file:./render.php", donde incluiremos la lógica que renderizará la vista en el frontend y donde sucede gran parte de la funcionalidad. Este archivo nos permite trabajar en PHP con todas las herramientas que ello implica. Añadiremos directivas a nuestro HTML a través de atributos data-wp-..., que iremos viendo a medida que avancemos. Puedes revisar la documentación completa aquí.

Incorporando nuestro bloque

Para comenzar, copiaremos los archivos que no requieren modificaciones de nuestro plugin anterior:

  • src/edit.js: No hay cambios en este archivo, ya que solo trabajaremos en el frontend.
  • src/slider.js: Para incluir en el archivo anterior.
  • src/editor.scss: Los estilos no cambian.
  • src/style.scss: Los estilos no cambian.

Por otro lado, crearemos el archivo src/save.js para guardar la estructura de los InnerBlocks y las imágenes seleccionadas, pero lo simplificaremos ya que no necesitamos la estructura para el frontend.

En src/index.js, agregaremos las siguientes líneas:

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,
} );

En src/save.js, incluiremos solo la estructura básica para guardar el contenido de los InnerBlocks:

export default function save() {
	return (
		<div { ...useBlockProps.save() }>
			<InnerBlocks.Content />
		</div>
	);
}

Render.php

Ahora trasladaremos la estructura de InnerBlocks para mostrar en el frontend y le agregaremos las directivas de la Interactivity API para su funcionamiento.

En src\render.php, eliminamos el contenido por defecto y agregamos el siguiente código para definir la estructura del slider. Obtenemos las imágenes desde la variable global $block, accediendo así al contenido de cada InnerBlock. Luego, establecemos la variable de contexto sliderPosition con un valor inicial del 50% y la vinculamos al contenedor mediante el atributo data-wp-style--position="context.sliderPosition", lo que permitirá actualizar dinámicamente su posición.

Además, añadimos el atributo data-wp-on--input="actions.changePosition" al input del slider, lo que activa un listener para el evento input, permitiendo que la posición del slider se actualice en tiempo real.

<div
    <?php echo get_block_wrapper_attributes(); ?>
    data-wp-interactive="create-block"
    <?php echo wp_interactivity_data_wp_context( array( "sliderPosition" =>"50%" ) ); ?>
	class="wp-block-create-block-beforeafterimagesi"
>
    <div class="container" data-wp-style----position="context.sliderPosition">
        <div class="image-container">
			<?php 
				foreach ( $block->parsed_block['innerBlocks'] as $picture ) {
					echo $picture['innerHTML'];
				}
			?>
        </div>
        <input type="range" min="0" max="100" value="50"
            aria-label="Percentage of before photo shown"
            class="slider" data-wp-on--input="actions.changePosition" />
        <div class="slider-line" aria-hidden="true"></div>
        <div class="slider-button" aria-hidden="true">
            <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" fill="currentColor" viewBox="0 0 256 256">
                <rect width="256" height="256" fill="none"></rect>
                <line x1="128" y1="40" x2="128" y2="216"   fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" ></line>
                <line x1="96" y1="128" x2="16" y2="128" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" ></line>
                <polyline points="48 160 16 128 48 96" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" ></polyline>
                <line x1="160" y1="128" x2="240" y2="128" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" ></line>
                <polyline points="208 96 240 128 208 160" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="16" ></polyline>
            </svg>
        </div>
    </div>

Ahora necesitamos agregar nuestra acción changePosition al javascript src/view.js:

import { store } from '@wordpress/interactivity';

const { state } = store( 'create-block', {
	state: {
	},
	actions: {
		changePosition( e ) {
			const context = getContext();
			context.sliderPosition = `${e.target.value}%`;
		},
	},
	callbacks: {
	},
} );

Obtenemos el contexto y actualizamos sliderPosition según el evento del input, el cual configuramos previamente en el nodo container con la directiva data-wp-style----position dentro de render.php.


¡Y eso es todo! Con este paso, nuestro bloque ya funciona correctamente con la Interactivity API.

Código del ejemplo: aquí