En entradas anteriores de este blog, hemos explorado el desarrollo de bloques de WordPress desde varios ángulos. Hemos examinado el desarrollo de bloques estáticos y dinámicos y hemos ampliado la funcionalidad de los bloques del núcleo. Sin embargo, el enfoque que hemos adoptado hasta ahora nos ha permitido esencialmente crear bloques estándar que no reaccionaban a las interacciones del usuario en tiempo real. En pocas palabras, estos bloques no eran interactivos.
En este artículo, exploraremos un nuevo enfoque del desarrollo de bloques, que nos permitirá crear bloques interactivos gracias a una nueva y potente API de WordPress: la API Interactivity de WordPress. Introducida en WordPress 6.5, esta API te permite crear bloques que reaccionan en tiempo real a las interacciones del usuario, permitiéndote crear experiencias de usuario enriquecidas y hacer que tus sitios sean atractivos, dinámicos y atractivos.
Hay mucho de lo que hablar, pero antes de empezar, ¡echemos un vistazo a los requisitos esenciales!
Lo que necesitas antes de empezar con la API Interactivity
Como la API Interactivity se basa en React, necesitarás al menos conocimientos básicos de JavaScript del lado del servidor y de React, así como de herramientas de construcción como npm y npx. También necesitarás un conocimiento profundo sobre el desarrollo de WordPress y del editor de bloques Gutenberg.
Una vez que hayas adquirido los conocimientos necesarios, necesitarás un entorno de desarrollo local que te permita poner en marcha un sitio de WordPress de forma rápida y sencilla. Te recomendamos DevKinsta, nuestra suite de desarrollo local diseñada específicamente para WordPress. Con DevKinsta, puedes crear un nuevo sitio local de WordPress en unos pocos clics y personalizarlo al detalle.
Cuando creas un nuevo proyecto de WordPress en DevKinsta, puedes configurar las siguientes opciones:
- Dominio de nivel superior: Por defecto .local
- Versión PHP
- Nombre de la base de datos
- Activar HTTPS
- Detalles de WordPress
- Actualización automática de WordPress
- Multisitio
Además, puedes importar un sitio web MyKinsta existente desde una copia de seguridad.

¿Qué es la API Interactivity?
La API Interactivity es una API nativa de WordPress que te permite añadir interactividad a los bloques de Gutenberg y, en consecuencia, a las entradas y páginas de un sitio de WordPress. Es una solución ligera y moderna que adopta un enfoque declarativo para gestionar las interacciones de los usuarios.
Crear un bloque interactivo desde cero requiere conocimientos avanzados de desarrollo PHP y JavaScript del lado del servidor. Sin embargo, no es necesario reinventar la rueda con cada nuevo proyecto, ya que WordPress proporciona una plantilla para crear bloques interactivos:
npx @wordpress/create-block --template @wordpress/create-block-interactive-template
Esta plantilla incluye todo lo que necesitas para crear un bloque interactivo, incluidos dos ejemplos prácticos que puedes utilizar como referencia para tu primer proyecto: un botón para cambiar el tema actual y un botón para expandir/contraer un párrafo.
Para empezar, abre tu herramienta de línea de comandos favorita, navega hasta el directorio Plugins de tu instalación local de WordPress y escribe lo siguiente:
npx @wordpress/create-block your-interactive-block --template @wordpress/create-block-interactive-template
Espera unos instantes a que se complete la instalación y, a continuación, abre la carpeta del proyecto con tu editor de código preferido. Recomendamos utilizar Visual Studio Code, pero puedes utilizar cualquier editor con el que te sientas más cómodo.

@wordpress/create-block-interactive-templateDesde la línea de comandos, navega hasta la carpeta del nuevo plugin e inicia el servidor de desarrollo utilizando el siguiente comando:
npm start
A partir de ahora, cualquier cambio que realices en tu bloque será visible en tiempo real en tu instalación de WordPress.
A continuación, en tu admin de WordPress, navega a la pantalla Plugins y activa el plugin Interactivity API que acabas de crear. Crea una nueva entrada o página, luego busca Tu bloque interactivo en el insertador de bloques y añádelo a tu contenido. Guarda la entrada y previsualízala en el frontend. Verás un bloque amarillo que contiene dos botones. El primer botón cambia el color de fondo del bloque, y el segundo muestra u oculta el contenido del párrafo.

@wordpress/create-block-interactive-templateAhora que tienes un plugin de referencia para los temas tratados en este artículo, podemos seguir adelante y explorar los bloques interactivos más a fondo.
La estructura de los bloques interactivos
La estructura de los bloques interactivos es la misma que la de los bloques tradicionales. Seguirás necesitando un archivo package.json, un archivo block.json, un archivo edit.js y un archivo style.scss. Además, necesitarás un archivo render.php para la renderización del lado del servidor y un archivo view.js para gestionar la interactividad del frontend.
Echemos un vistazo a los componentes específicos de un bloque interactivo desglosando los archivos individuales del proyecto inicial.
package.json
El archivo package.json se utiliza en los proyectos Node para identificar tu proyecto, gestionar scripts y gestionar e instalar dependencias durante el desarrollo.
A continuación se muestra el package.json para el bloque interactivo proporcionado por el create-block-interactive-template:
{
"name": "your-interactive-block",
"version": "0.1.0",
"description": "An interactive block with the Interactivity API.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"main": "build/index.js",
"scripts": {
"build": "wp-scripts build --experimental-modules",
"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 --experimental-modules"
},
"dependencies": {
"@wordpress/interactivity": "latest"
},
"files": [
"[^.]*"
],
"devDependencies": {
"@wordpress/scripts": "^30.24.0"
}
}
Las secciones scripts y dependencies son especialmente importantes en este caso.
build: Compila el código fuente en JavaScript para producción. La opción--experimental-moduleshabilita la compatibilidad con los módulos de scripts de WordPress.start: Inicia el servidor de desarrollo. Observa que se vuelve a especificar la opción--experimental-modules.dependencies: Incluye las dependencias en tiempo de ejecución con el último paquete de la API de Interactividad.
block.json
El archivo block.json es el manifiesto de tu bloque Gutenberg. Especifica los metadatos, los medios, los scripts y los estilos a cargar. Por defecto, el create-block-interactive-template genera el siguiente block.json:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/your-interactive-block",
"version": "0.1.0",
"title": "Your Interactive Block",
"category": "widgets",
"icon": "media-interactive",
"description": "An interactive block with the Interactivity API.",
"example": {},
"supports": {
"interactivity": true
},
"textdomain": "your-interactive-block",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php",
"viewScriptModule": "file:./view.js"
}
Los siguientes campos son esenciales para un bloque interactivo:
apiVersion:3es la última versión de la API Block y admite las últimas funcionalidades de los bloques, como los Módulos de Script.supports: Especifica la compatibilidad del bloque."interactivity": trueañade compatibilidad con la API Interactivity.render: Especifica el archivo PHP responsable de la renderización en el frontend. Este archivo es donde se añaden las directivas que hacen que un bloque sea interactivo.viewScriptModule: Especifica el archivo JavaScript que contiene la lógica de interactividad. Este archivo sólo se carga en el frontend y sólo si la página contiene el bloque interactivo.
render.php
En render.php es donde se construye el marcado de un bloque dinámico. Para que tu bloque sea interactivo, tienes que añadir atributos que hagan interactivos los elementos DOM de tu bloque.
El archivo render.php del proyecto de inicio tiene el siguiente aspecto:
<?php
/**
* PHP file to use when rendering the block type on the server to show on the front end.
*
* The following variables are exposed to the file:
* $attributes (array): The block attributes.
* $content (string): The block default content.
* $block (WP_Block): The block instance.
*
* @see https://github.com/WordPress/gutenberg/blob/trunk/docs/reference-guides/block-api/block-metadata.md#render
*/
// Generates a unique id for aria-controls.
$unique_id = wp_unique_id( 'p-' );
// Adds the global state.
wp_interactivity_state(
'create-block',
array(
'isDark' => false,
'darkText' => esc_html__( 'Switch to Light', 'your-interactive-block' ),
'lightText' => esc_html__( 'Switch to Dark', 'your-interactive-block' ),
'themeText' => esc_html__( 'Switch to Dark', 'your-interactive-block' ),
)
);
?>
<div
<?php echo get_block_wrapper_attributes(); ?>
data-wp-interactive="create-block"
<?php echo wp_interactivity_data_wp_context( array( 'isOpen' => false ) ); ?>
data-wp-watch="callbacks.logIsOpen"
data-wp-class--dark-theme="state.isDark"
>
<button
data-wp-on--click="actions.toggleTheme"
data-wp-text="state.themeText"
></button>
<button
data-wp-on--click="actions.toggleOpen"
data-wp-bind--aria-expanded="context.isOpen"
aria-controls="<?php echo esc_attr( $unique_id ); ?>"
>
<?php esc_html_e( 'Toggle', 'your-interactive-block' ); ?>
</button>
<p
id="<?php echo esc_attr( $unique_id ); ?>"
data-wp-bind--hidden="!context.isOpen"
>
<?php
esc_html_e( 'Your Interactive Block - hello from an interactive block!', 'your-interactive-block' );
?>
</p>
</div>
Esto es lo que hace este código
wp_interactivity_state: Obtiene y/o establece el estado global inicial de un almacén (store) de la API Interactivity.data-wp-interactive: Activa la API Interactivity en el elemento DOM y sus elementos hijos. Su valor debe ser el namespace (espacio de nombres) único de tu plugin o bloque.wp_interactivity_data_wp_context(): Genera la directivadata-wp-context, que proporciona un estado local a un nodo HTML específico y en sus elementos hijos.data-wp-watch: Ejecuta un callback cuando se crea un nodo y cada vez que cambia el estado o el contexto.data-wp-class--dark-theme: Añade o elimina la clasedark-themedel elemento HTML.data-wp-on--click: Ejecuta código de forma síncrona al hacer clic.data-wp-text: Establece el texto interior del elemento HTML.data-wp-bind--aria-expandedydata-wp-bind--hidden: Establece atributos HTML (aria-expandedyhidden) en los elementos correspondientes en función de un valor booleano o de cadena.
view.js
Este archivo define el Store que contiene la lógica y los datos necesarios para el comportamiento del bloque, incluyendo el estado, las acciones y callbacks.
A continuación se muestra el archivo view.js generado por el proyecto de inicio:
/**
* WordPress dependencies
*/
import { store, getContext } from '@wordpress/interactivity';
const { state } = store( 'create-block', {
state: {
get themeText() {
return state.isDark ? state.darkText : state.lightText;
},
},
actions: {
toggleOpen() {
const context = getContext();
context.isOpen = ! context.isOpen;
},
toggleTheme() {
state.isDark = ! state.isDark;
},
},
callbacks: {
logIsOpen: () => {
const { isOpen } = getContext();
// Log the value of `isOpen` each time it changes.
console.log( `Is open: ${ isOpen }` );
},
},
} );
store: La función principal utilizada para crear y registrar el estado Global y la lógica del bloque.getContext: Función utilizada dentro de las acciones y callbacks para acceder al estado local (elcontext) del elemento DOM que desencadenó el evento.state: Define los datos reactivos globales del bloque.actions: Incluye las funciones que definen la lógica y cambian el estado.callbacks: Incluye las funciones que se ejecutarán en respuesta a determinados eventos o cambios de estado de forma automática.
Es mucho que asimilar, ¡pero no te preocupes! Todo quedará más claro una vez que hayas leído los siguientes apartados.
Examinemos ahora los conceptos clave de la API Interactivity: directivas, store, estado, acciones y callbacks.
Directivas de la API Interactivity
Al igual que otras bibliotecas frontend como Alpine.js y Vue.js, la API Interactivity utiliza atributos HTML especiales que te permiten responder a eventos de la página, actualizar el estado de la aplicación, manipular el DOM, aplicar estilos CSS, gestionar la entrada del usuario y mucho más.
Estos atributos se denominan directivas y te permiten conectar tu marcado a la lógica JavaScript subyacente.
A continuación encontrarás una lista de las directivas que más utilizarás.
| Función | Directiva | Descripción |
|---|---|---|
| Activación/Namespace | data-wp-interactive |
Activa la API para el elemento y sus hijos. El valor debe ser el identificador único de tu plugin. |
| Estado local | data-wp-context |
Proporciona un estado local (un «contexto») para el elemento actual y todos sus hijos. Acepta un objeto JSON. Ten en cuenta que se recomienda utilizar wp_interactivity_data_wp_context() para establecerlo en PHP (normalmente render.php). |
| Vinculación de atributos | data-wp-bind--[attribute] |
Establece un atributo HTML (por ejemplo, disabled, value) en función de un estado reactivo o de un valor de contexto (un valor booleano o de cadena). |
| Modificación de texto | data-wp-text |
Establece el contenido de texto interno del elemento. Sólo acepta cadenas. |
| Conmutación de clase CSS | data-wp-class--[classname] |
Añade o elimina una clase CSS en función de un valor booleano. |
| Estilo Inline | data-wp-style--[css-property] |
Añade o elimina una clase de estilo inline en función de un valor booleano. |
| Gestión de eventos | data-wp-on--[event] |
Ejecuta código en respuesta a eventos DOM estándar como click o mouseover. |
| Ejecución inicial | data-wp-init |
Ejecuta una función de callback una vez, sólo cuando se crea el nodo. |
| Vigilancia del estado | data-wp-watch |
Ejecuta un callback cuando se crea el nodo y de nuevo cada vez que cambia el estado o el contexto. |
| Iteración de lista | data-wp-each |
Renderiza una lista de elementos. |
Para obtener una lista completa de las directivas, consulta las notas de desarrollo de la API Interactivity y la referencia de la API.
Estado global, contexto local y estado derivado
Antes de empezar a utilizar la API Interactivity, es esencial que te familiarices con los conceptos fundamentales de la gestión de estados en el desarrollo frontend. Quienes desarrollen habitualmente con React, Vue o Angular ya estarán familiarizados con estos conceptos. Para quienes sean nuevos en estas tecnologías, puede ser útil proporcionar algunas definiciones generales.
Estado global
El estado global se refiere al conjunto de datos accesibles desde casi todos los componentes de una aplicación. En el caso de la API Interactivity, por ejemplo, el estado global afecta a todos los bloques interactivos de la página, manteniéndolos sincronizados. Por ejemplo, cuando un usuario añade un producto a su cesta, esto se refleja en el bloque de la cesta de la compra.
Cuando utilices la API Interactivity, debes establecer los valores iniciales del estado Global en el servidor utilizando la función wp_interactivity_state(). En el proyecto de inicio descrito anteriormente, esta función se utiliza en el archivo render.php de la siguiente manera:
// Adds the global state.
wp_interactivity_state(
'create-block',
array(
'isDark' => false,
'darkText' => esc_html__( 'Switch to Light', 'your-interactive-block' ),
'lightText' => esc_html__( 'Switch to Dark', 'your-interactive-block' ),
'themeText' => esc_html__( 'Switch to Dark', 'your-interactive-block' ),
)
);
Esta función acepta dos argumentos:
- Un identificador único para el namespace (espacio de nombres) de la tienda. En este caso,
create-block. - Un array de datos que se fusionará con el espacio de nombres de la tienda existente, si existe.
Los valores iniciales del estado global se utilizan después para renderizar la página. Puedes acceder directamente a los valores de estado global utilizando state en los valores de atributo de la directiva, como en el código siguiente:
<button
data-wp-on--click="actions.toggleTheme"
data-wp-text="state.themeText"
></button>
La función store() proporciona el principal punto de acceso al estado Global desde JavaScript, limitado al namespace seleccionado. Volviendo al código del proyecto de inicio, la función store() se utiliza en el archivo view.js de la siguiente manera:
import { store, getContext } from '@wordpress/interactivity';
const { state } = store( 'create-block', {
state: { ... },
actions: { ... },
callbacks: { ... },
} );
Para acceder al estado global, puedes utilizar la propiedad state:
actions: {
toggleTheme() {
state.isDark = ! state.isDark;
},
},
Contexto local
El contexto local es información a la que solo pueden acceder un componente específico y sus elementos hijos directos. Un bloque interactivo de WordPress proporciona un estado independiente para el bloque y sus elementos anidados.
Si utilizas la API Interactivity, puedes acceder al contexto local mediante la función getContext(). Volviendo al proyecto de inicio, cuando el usuario hace clic en el botón Alternar, se desencadena la acción toggleOpen(), que accede al contexto Local del componente:
actions: {
toggleOpen() {
const context = getContext();
context.isOpen = ! context.isOpen;
},
},
getContext(): Recupera el objeto de estado local del bloque. Las propiedades de este objeto se definen en el marcado del componente (render.php) mediante la funciónwp_interactivity_data_wp_context().context.isOpen = ! context.isOpen;: Cambia el valor de la propiedadisOpenen el contexto Local del componente.
Estado derivado
El estado derivado se refiere a los datos calculados dinámicamente a partir del estado Global o Local existente.
Por ejemplo, echa un vistazo al código del archivo view.js, concretamente en esta sección:
const { state } = store( 'create-block', {
state: {
get themeText() {
return state.isDark ? state.darkText : state.lightText;
},
},
...
}
Este bloque define el estado Derivado themeText dentro del estado Global definido en el namespace create-block.
get themeText()no es un valor fijo, sino una función que se ejecuta cada vez que intentas leer la propiedadthemeText. No debe invocarse como una función normal porque la API Interactivity la trata como una propiedad de estado y recalcula automáticamente su valor cada vez que cambian los valores de otras propiedades de estado. En el código anterior, el valor de la propiedadthemeTextse recalcula cada vez que cambia el valor de la propiedadisDark. Sistate.isDarkestrue, entoncesthemeTexttoma el valor destate.darkText; en caso contrario, toma el valor destate.lightText.
Para una visión más completa de los conceptos descritos en esta sección, consulta Comprender el estado global, el contexto local y el estado derivado.
Acciones y callbacks
Las acciones y callbacks determinan la respuesta a la interacción con el usuario y a los cambios de estado.
La sección actions de un bloque interactivo contiene funciones que se ejecutan en respuesta a eventos generados por el usuario. Estas funciones sirven principalmente para modificar el estado Local o Global del componente. Toma el siguiente código del archivo view.js:
actions: {
toggleOpen() {
const context = getContext();
context.isOpen = ! context.isOpen;
},
...
},
- En esta sección de código, la función
toggleOpen()utilizagetContext()para acceder al contexto Local del bloque que desencadenó la acción para cambiar el valor de la propiedadisOpen.
Del mismo modo, puedes acceder al estado Global:
actions: {
...,
toggleTheme() {
state.isDark = ! state.isDark;
},
},
- La función
toggleTheme()accede directamente al objeto globalstatey cambia el valor de la propiedadisDark.
Las acciones se activan mediante la directiva data-wp-on--[event]. Por ejemplo, en el archivo render.php, encontrarás el siguiente botón:
<button
data-wp-on--click="actions.toggleOpen"
data-wp-bind--aria-expanded="context.isOpen"
aria-controls="<?php echo esc_attr( $unique_id ); ?>"
>
- En este código HTML, el atributo
data-wp-on--clickactiva la accióntoggleOpencuando el usuario hace clic en el botón de conmutación.
La sección callbacks contiene funciones que se ejecutan automáticamente cuando cambian los datos de los que dependen. Su finalidad es generar efectos secundarios en respuesta a un cambio de estado.
En el proyecto básico generado por create-block-interactive-template, encontrarás el siguiente callback:
callbacks: {
logIsOpen: () => {
const { isOpen } = getContext();
// Log the value of `isOpen` each time it changes.
console.log( `Is open: ${ isOpen }` );
},
},
- La función
logIsOpenutiliza la variableisOpen, que está disponible en el contexto Local. - El callback recupera el valor de
isOpenutilizandogetContext(). - Cada vez que cambia el valor de
isOpen, la función lanza un mensaje a la consola del navegador.

Cómo construir un bloque interactivo
Ahora que ya hemos visto la teoría, ¡es hora de empezar a divertirnos con el código! En la segunda parte de esta guía, aprenderás a crear un bloque interactivo que permite a los usuarios añadir productos a una cesta de la compra ideal, con cantidades y totales que se actualizan automáticamente. Se trata de un ejemplo de demostración, pero esperamos que te ayude a comprender claramente cómo utilizar el estado, las acciones y los callbacks.

Vamos a crear un bloque llamado Interactive Counter utilizando el create-block-interactive-template. Para empezar, abre tu herramienta de línea de comandos y escribe lo siguiente:
npx @wordpress/create-block interactive-counter --template @wordpress/create-block-interactive-template
A continuación, navega hasta el directorio de tu nuevo proyecto y ejecuta la primera construcción.
cd interactive-counter && npm run build
Abre ahora el proyecto en tu editor de código. En el directorio /src, busca el archivo block.json. Debería tener este aspecto:
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "create-block/interactive-counter",
"version": "0.1.0",
"title": "Interactive Counter",
"category": "widgets",
"icon": "media-interactive",
"description": "An interactive block with the Interactivity API.",
"supports": {
"interactivity": true
},
"textdomain": "interactive-counter",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php",
"viewScriptModule": "file:./view.js"
}
Siéntete libre de personalizarlo, pero asegúrate de no modificar los campos esenciales descritos anteriormente.
El archivo edit.js
El siguiente paso es crear el bloque que aparecerá en el editor. Para ello, tendrás que editar el archivo /src/edit.js. Abre el archivo y modifícalo como se indica a continuación:
import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';
export default function Edit({ attributes, setAttributes }) {
const blockProps = useBlockProps();
const products = [
{ id: 'product1', name: __('Product 1', 'interactive-counter'), price: 10.00 },
{ id: 'product2', name: __('Product 2', 'interactive-counter'), price: 15.00 },
{ id: 'product3', name: __('Product 3', 'interactive-counter'), price: 20.00 },
];
return (
<div {...blockProps}>
<h3>{__('Shopping Cart', 'interactive-counter')}</h3>
<ul>
{products.map((product) => (
<li key={product.id} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '10px' }}>
<span style={{ flex: 1 }}>{product.name} - ${product.price.toFixed(2)}</span>
<div style={{ display: 'flex', gap: '10px', alignItems: 'center' }}>
<button disabled>-</button>
<span>0</span>
<button disabled>+</button>
</div>
<span style={{ flex: 1, textAlign: 'right' }}>
{__('Subtotal:', 'interactive-counter')} $0.00
</span>
</li>
))}
</ul>
<div style={{ borderTop: '1px solid #ccc', paddingTop: '15px' }}>
<p style={{ display: 'flex', justifyContent: 'space-between' }}>
<strong>{__('Subtotal:', 'interactive-counter')}</strong>
<span>$0.00</span>
</p>
<p style={{ display: 'flex', justifyContent: 'space-between' }}>
<strong>{__('Tax (22%):', 'interactive-counter')}</strong>
<span>$0.00</span>
</p>
<p style={{ display: 'flex', justifyContent: 'space-between' }}>
<strong>{__('Total:', 'interactive-counter')}</strong>
<span>$0.00</span>
</p>
</div>
<p>{__('Quantities and totals will be interactive in the frontend.', 'interactive-counter')}</p>
</div>
);
}
Este código genera un bloque personalizado en el back end. El bloque sólo será interactivo en el front-end. Para más detalles sobre el archivo /src/edit.js, consulta nuestras guías de desarrollo de bloques para Gutenberg.
El archivo render.php
El siguiente archivo a editar es /src/render.php. Abre el archivo y sustituye el código existente por el siguiente:
<?php
/**
* Render callback for the interactive-counter block.
*/
$products = [
['id' => 'product1', 'name' => __('Product 1', 'interactive-counter'), 'price' => 10.00],
['id' => 'product2', 'name' => __('Product 2', 'interactive-counter'), 'price' => 15.00],
['id' => 'product3', 'name' => __('Product 3', 'interactive-counter'), 'price' => 20.00],
];
// Initialize global state
wp_interactivity_state('interactive-counter', [
'products' => array_map(function ($product) {
return [
'id' => $product['id'],
'name' => $product['name'],
'price' => $product['price'],
'quantity' => 0,
'subtotal' => '0.00',
];
}, $products),
'vatRate' => 0.22,
]);
Esto es lo que hace este código
- En primer lugar, crea un array de productos codificado. Cada producto tiene un ID, un nombre y un precio.
- A continuación, inicializa el estado Global con
wp_interactivity_state. El primer parámetro es el nombre de la tienda, que debe coincidir con el utilizado enview.js. - A continuación, asigna el array anterior de productos a un nuevo array
products, añadiendo cantidad y subtotal a las propiedades del array original. Este nuevo array proporciona la estructura de datos que utilizarás enview.js. vatRateestablece el valor por defecto para el cálculo de impuestos.
A continuación, añade lo siguiente al código anterior:
<div <?php echo get_block_wrapper_attributes(); ?> data-wp-interactive="interactive-counter" data-wp-init="callbacks.init">
<h3><?php echo esc_html__('Cart', 'interactive-counter'); ?></h3>
<ul>
<?php foreach ($products as $index => $product) : ?>
<li data-wp-context='{
"productId": "<?php echo esc_attr($product['id']); ?>",
"quantity": 0,
"subtotal": "0.00"
}'
data-wp-bind--data-wp-context.quantity="state.products[<?php echo $index; ?>].quantity"
data-wp-bind--data-wp-context.subtotal="state.products[<?php echo $index; ?>].subtotal">
<span class="product-name"><?php echo esc_html($product['name']); ?> - $<?php echo esc_html(number_format($product['price'], 2)); ?></span>
<div class="quantity-controls">
<button data-wp-on--click="actions.decrement">-</button>
<span data-wp-text="context.quantity">0</span>
<button data-wp-on--click="actions.increment">+</button>
</div>
<span class="product-subtotal">
<?php echo esc_html__('Subtotal:', 'interactive-counter'); ?>
$<span data-wp-text="context.subtotal">0.00</span>
</span>
</li>
<?php endforeach; ?>
</ul>
<div class="totals">
<p>
<strong><?php echo esc_html__('Subtotal:', 'interactive-counter'); ?></strong>
$ <span data-wp-text="state.subtotal">0.00</span>
</p>
<p>
<strong><?php echo esc_html__('Tax (22%):', 'interactive-counter'); ?></strong>
$ <span data-wp-text="state.vat">0.00</span>
</p>
<p>
<strong><?php echo esc_html__('Total:', 'interactive-counter'); ?></strong>
$ <span data-wp-text="state.total">0.00</span>
</p>
</div>
</div>
Esto es lo que hace este código
- La función
get_block_wrapper_attributes()del contenedordives una función de WordPress que genera los atributos estándar de un bloque. En este caso, genera el atributo de clase"wp-block-create-block-interactive-counter". - El atributo
data-wp-interactivehace que este bloque sea interactivo. - El atributo
data-wp-initactiva el callbackinitdefinido enview.js. - El bucle
foreachgenera un elemento de lista para cada producto del arrayproducts. data-wp-contextdefine el contexto local del bloque.data-wp-bindvincula el valor dedata-wp-context.quantitya la propiedad globalstate.products[$index].quantity.- Lo mismo ocurre en la línea inferior con el subtotal.
- Los dos botones siguientes activan las acciones
decrementyincrementgracias al atributodata-wp-on--click. - El atributo
data-wp-textdespanactualiza el contenido del elemento en función del valor actual decontext.quantity.
El resto del código se explica por sí mismo, así que pasemos al siguiente archivo.
El archivo view.js
Este archivo contiene la lógica de tu bloque interactivo.
import { store, getContext } from '@wordpress/interactivity';
store('interactive-counter', {
state: {
get subtotal() {
const { products } = store('interactive-counter').state;
return products
.reduce((sum, product) => sum + product.price * (product.quantity || 0), 0)
.toFixed(2);
},
get vat() {
const { subtotal, vatRate } = store('interactive-counter').state;
return (subtotal * vatRate).toFixed(2);
},
get total() {
const { subtotal, vat } = store('interactive-counter').state;
return (parseFloat(subtotal) + parseFloat(vat)).toFixed(2);
},
},
actions: {
increment: () => {
const context = getContext();
const { products } = store('interactive-counter').state;
const product = products.find(p => p.id === context.productId);
if (product) {
product.quantity = (product.quantity || 0) + 1;
product.subtotal = (product.price * product.quantity).toFixed(2);
context.quantity = product.quantity;
context.subtotal = product.subtotal;
console.log(`Incremented ${context.productId}:`, { quantity: product.quantity, subtotal: product.subtotal, context });
} else {
console.warn('Product not found:', context.productId);
}
},
decrement: () => {
const context = getContext();
const { products } = store('interactive-counter').state;
const product = products.find(p => p.id === context.productId);
if (product && (product.quantity || 0) > 0) {
product.quantity -= 1;
product.subtotal = (product.price * product.quantity).toFixed(2);
context.quantity = product.quantity;
context.subtotal = product.subtotal;
console.log(`Decremented ${context.productId}:`, { quantity: product.quantity, subtotal: product.subtotal, context });
} else {
console.warn('Cannot decrement:', context.productId, product?.quantity);
}
},
},
callbacks: {
init: () => {
const { products } = store('interactive-counter').state;
products.forEach((product, index) => {
product.quantity = 0;
product.subtotal = '0.00';
console.log(`Initialized product ${index}:`, { id: product.id, quantity: product.quantity, subtotal: product.subtotal });
});
},
},
});
Este archivo define el store para el namespace interactive-counter. Gestiona el estado, las acciones y los callbacks:
store('interactive-counter', {
state: { ... },
actions: { ... },
callbacks: { ... },
});
Echemos un vistazo más de cerca.
state: Define tres propiedades de estado calculadas (getters):subtotal,vat, ytotal. Estas funciones recuperan valores del estado Global y calculan los valores a devolver.actions: Define dos funciones que se ejecutan en los eventos:incrementydecrement. Estas funciones recuperan el arrayproductsdel estado Global, recuperan el producto actual del contexto Local basándose encontext.productId, actualizan los valores de las propiedades del producto actual (quantityysubtotal), y sincronizan el contexto Local con los nuevos valores.callbacks: Define un callbackinitpara la inicialización.
La siguiente imagen muestra el bloque interactivo en el frontend.

Resumen
En este artículo, hemos presentado las principales características de la API Interactivity de WordPress. Hemos profundizado en conceptos clave como Estado global, Contexto local, Directivas, Acciones y Callbacks. Aprendiste a crear un bloque interactivo desde cero utilizando el @wordpress/create-block-interactive-template, y lo pusimos en práctica creando un bloque real que interactúa con la entrada del usuario.
Esperamos haberte proporcionado las herramientas y los conocimientos necesarios para crear sitios web de WordPress atractivos, dinámicos e interactivos utilizando la API Interactivity de WordPress.
¡Feliz programación!