Contents
Introducción
Este artículo explica paso a paso cómo crear un bloque personalizado para WordPress usando InnerBlocks y controles personalizados en JavaScript. Cubriremos la estructura del proyecto, el registro del bloque, el desarrollo del componente de edición con InnerBlocks, controles en la barra lateral (InspectorControls) y la renderización de la salida con InnerBlocks.Content. También incluimos ejemplos completos de código para cada archivo necesario.
Requisitos previos
- WordPress 5.0 (mejor con 5.8 )
- Node.js y npm instalados
- Conocimientos básicos de ESNext, React/JSX y la API de bloques de Gutenberg
- Herramientas de compilación: recomendamos @wordpress/scripts para simplificar
Estructura del proyecto
Un plugin simple para este bloque podría tener la siguiente estructura:
- my-innerblocks-block/
- block.json
- src/
- index.js
- edit.js
- save.js
- build/ (generado)
- plugin.php
- style.css (opcional)
- editor.css (opcional)
1. block.json (metadatos)
Usar block.json facilita el registro del bloque con register_block_type_from_metadata. Define atributos, estilos, y scripts a enlazar.
{ apiVersion: 2, name: mi-plugin/innerblocks-con-controles, title: Sección con InnerBlocks y Controles, category: layout, icon: columns, description: Bloque que permite anidar bloques con controles personalizados, supports: { html: false }, editorScript: file:./build/index.js, editorStyle: file:./build/editor.css, style: file:./build/style.css, attributes: { backgroundColor: { type: string, default: #ffffff }, showTitle: { type: boolean, default: true }, columns: { type: number, default: 2 } } }
2. plugin.php (registro en PHP)
Archivo principal del plugin que registra el bloque usando los metadatos y encola los assets compilados.
3. index.js (entrada JS)
Archivo de entrada que registra la edición y la save. Importa edit y save desde src.
import { registerBlockType } from @wordpress/blocks import edit from ./edit import save from ./save import metadata from ../block.json registerBlockType( metadata.name, { ...metadata, edit, save, } )4. edit.js (componente de edición con InnerBlocks y controles)
Este es el núcleo: muestra la interfaz de edición con InnerBlocks, Panel lateral con controles y controles en la barra del bloque. Usamos componentes de @wordpress/block-editor y @wordpress/components.
import { __ } from @wordpress/i18n import { useBlockProps, InnerBlocks, InspectorControls, BlockControls } from @wordpress/block-editor import { PanelBody, ToggleControl, RangeControl, ToolbarGroup, ToolbarButton } from @wordpress/components import { Fragment } from @wordpress/element import { useState } from @wordpress/element const ALLOWED_BLOCKS = [ core/heading, core/paragraph, core/image, core/gallery ] export default function Edit( props ) { const { attributes, setAttributes, clientId } = props const { backgroundColor, showTitle, columns } = attributes const blockProps = useBlockProps( { style: { backgroundColor: backgroundColor, padding: 1rem, }, className: mi-innerblocks-block columns-{ columns }, } ) const template = [ [ core/heading, { placeholder: Título de la sección, level: 3 } ], [ core/paragraph, { placeholder: Escribe el contenido... } ], ] return () } setAttributes( { showTitle: val } ) } /> setAttributes( { columns: val } ) } min={ 1 } max={ 4 } /> setAttributes( { showTitle: ! showTitle } ) } /> { showTitleTítulo de sección
}Explicación clave del edit.js
- useBlockProps: aplica atributos y estilos al wrapper del bloque de forma compatible con la API.
- InspectorControls: panel lateral donde colocamos ToggleControl y RangeControl para modificar atributos.
- BlockControls: controla la barra superior del bloque con botones personalizados.
- InnerBlocks: permite anidar bloques aquí se pasan allowedBlocks, template, templateLock y renderAppender.
5. save.js (salida del bloque)
En la función save usamos InnerBlocks.Content para serializar el contenido anidado y produce la salida HTML final que se guarda en el contenido de la entrada.
import { useBlockProps, InnerBlocks } from @wordpress/block-editor export default function Save( props ) { const { attributes } = props const { backgroundColor, showTitle, columns } = attributes const blockProps = useBlockProps.save( { style: { backgroundColor: backgroundColor, padding: 1rem, }, className: mi-innerblocks-block columns-{ columns }, } ) return ({ showTitle) }Título de sección
}
6. estilo básico (editor y front-end)
Ejemplo de CSS para columnas adaptables y espaciado.
.mi-innerblocks-block { box-sizing: border-box } .mi-innerblocks-block .mi-seccion-titulo { margin-top: 0 } .mi-innerblocks-block.columns-1 > .wp-block { width: 100% } .mi-innerblocks-block.columns-2 > .wp-block { width: 50% } .mi-innerblocks-block.columns-3 > .wp-block { width: 33.3333% } .mi-innerblocks-block.columns-4 > .wp-block { width: 25% } / Asegúrate de que los bloques hijos se comporten como elementos en fila / .mi-innerblocks-block > .wp-block { display: inline-block vertical-align: top }
7. Compilar con @wordpress/scripts
Configura package.json con scripts para compilación:
{ name: mi-innerblocks-block, version: 1.0.0, scripts: { build: wp-scripts build, start: wp-scripts start }, devDependencies: { @wordpress/scripts: ^25.0.0 } }
Coloca la entrada en src/index.js y configura block.json para apuntar a build/index.js. Ejecuta npm run build o npm run start mientras desarrollas.
8. Buenas prácticas y consejos
- Usa atributos en block.json para que Gutenberg pueda serializarlos correctamente.
- Prefiere InnerBlocks.Content en save para dejar que Gutenberg serialice los bloques hijos.
- Si necesitas controlar la estructura inicialmente, usa template. Si quieres bloquear completamente la estructura, usa templateLock: all.
- Define allowedBlocks para evitar que se inserten bloques no deseados.
- Para estilos personalizados en el editor, registra editor.css y asegúrate de compilarlo en build/editor.css.
- Prueba la accesibilidad y la edición con diferentes tamaños de pantalla.
9. Ejemplo avanzado: renderAppender personalizado
Puedes quitar el renderizador por defecto y usar uno propio para ofrecer un botón con etiqueta personalizada.
import { InnerBlocks } from @wordpress/block-editor import { Button } from @wordpress/components function CustomAppender() { return () } // En el edit:
10. Consideraciones sobre compatibilidad y rendimiento
- Evita ejecutar lógica costosa en el componente de edición guarda lo mínimo necesario en atributos.
- Si necesitas contenido dinámico (p. ej. basado en visitas o consultas), usa renderizado del lado servidor (server-side render) con render_callback en PHP.
- Usa className y estilos en CSS en lugar de inline cuando puedas, para facilitar la cache y la separación de responsabilidades.
Conclusión
Crear un bloque con InnerBlocks y controles personalizados en JS te permite construir secciones flexibles y potentes para editores de contenido en WordPress. La clave es entender la separación entre edición (edit.js) y salida (save.js), usar InnerBlocks para la anidación y aprovechar InspectorControls y BlockControls para exponer configuraciones al usuario. Con block.json y @wordpress/scripts la experiencia de desarrollo es mucho más sencilla y estandarizada.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |