logo

Cómo personalizar los bloques existentes de Gutenberg con campos adicionales

02 julio 2023

En este artículo explicaré cómo podemos extender los atributos de los bloques ya existentes en WordPress de una manera sencilla para poder añadir campos adicionales para su configuración.

Utilizaremos en este ejemplo el bloque de Código para poder añadir 3 campos adicionales:

  • Uno para especificar el lenguaje de programación.
  • Otro para dar la opción de mostrar la enumeración de las líneas de código.
  • Y un tercero para indicar a partir de qué número debe empezar la enumeración.


Este post es el primero de una serie de artículos, el objetivo de estos atributos será el de poder utilizar una librería de resaltado de código (como react-syntax-highlighter) en el front end que necesitará de estos datos para saber cómo mostrar el código añadido.

Los pasos a seguir:

  • Añadir los attributos
  • Añadir los controles al editor.

Añadir los atributos.

Podemos modificar los ajustes de un bloque mediante el filtro blocks.registerBlockType

Esta sería la manera de hacerlo:

/**
 * WordPress dependencies.
 */
const { addFilter } = wp.hooks;

const addCodeAttributes = (settings, name) => {
	// No hacer nada si no es el bloque de código.
	if (name !== 'core/code') {
		return settings;
	}

	// Registrar los atributos que necesitamos.
	settings.attributes = Object.assign(settings.attributes, {
		language: {
			type: 'string',
			default: 'javascript',
		},
		showLineNumbers: {
			type: 'boolean',
			default: true,
		},
		startingLineNumber: {
			type: 'string',
			default: '1',
		},
	});

	return settings;
};

// Llamar a nuestro callback addCodeAttributes al filtro blocks.registerBlockType.
addFilter('blocks.registerBlockType', 'example/code-block-attributes', addCodeAttributes);

Añadir los controles al editor.

Ahora necesitamos añadir los controles al editor para poder editar los valores de estos nuevos ajustes.
Para ello haremos uso del filtro editor.BlockEdit, el cual nos permite modificar el componente BlockEdit.

Para añadir los controles podemos crear un panel nuevo al inspector de controles o podemos añadir nuestros controles personalizados al panel Avanzado.

En el siguiente ejemplo utilizaré el panel Avanzado haciendo uso del componente InspectorAdvancedControls, luego explicaré como hacerlo con un panel nuevo.

/**
 * WordPress dependencies.
 */
const { __ } = wp.i18n;
const { addFilter } = wp.hooks;
const { InspectorAdvancedControls } = wp.editor;
const { createHigherOrderComponent } = wp.compose;
const { ToggleControl, TextControl } = wp.components;

// Crear un nuevo Higher Order Component, que recibe el componente BlockEdit original, el cual podemos extender.
const withCustomCodeControls = createHigherOrderComponent((BlockEdit) => {
	return (props) => {
		const { name } = props;

		// No hacer nada si no es el bloque de código.
		if (name !== 'core/code') {
			return <BlockEdit {...props} />;
		}

		const { attributes, setAttributes } = props;
		const { language, showLineNumbers, startingLineNumber } = attributes;

		// Devolver el componente original, agregando nuestros propios controles.
		return (
			<>
				<BlockEdit {...props} />
				<InspectorAdvancedControls>
					<TextControl
						label={__('Lenguaje de programación', 'example')}
						value={language}
						onChange={(value) => setAttributes({ language: value })}
					/>
					<ToggleControl
						label={__('Mostrar enumeración', 'example')}
						checked={showLineNumbers}
						onChange={(value) => setAttributes({ showLineNumbers: value })}
					/>
					<TextControl
						label={__('Empezar enumeración por', 'example')}
						value={startingLineNumber}
						onChange={(value) => setAttributes({ startingLineNumber: value })}
					/>
				</InspectorAdvancedControls>
			</>
		);
	};
}, 'withCustomCodeControls');

// Añadir nuestro component withCustomCodeControls al filtro editor.BlockEdit.
addFilter('editor.BlockEdit', 'example/with-custom-code-controls', withCustomCodeControls);

Este es el resultado:

Si queremos por el contrario crear un panel nuevo para manejar estos nuevos ajustes de la siguiente manera:

IMAGE

Necesitaremos usar el componente InspectorControls en lugar del que hemos usado en el anterior ejemplo InspectorAdvancedControls. Y a su vez el componente PanelBody para añadir el panel nuevo.

El cambio implicaría envolver los controles TextControl y ToogleControl que hemos añadido dentro de PanelBody que a su vez estaría envuelto por InspectorControls:

// cambio en dependencias de WordPress
const { InspectorControls } = wp.editor;
const { ToggleControl, TextControl, PanelBody } = wp.components;

// Sustituir InspectorAdvancedControls por InspectorControls y añadir PanelBody
<InspectorControls>
	<PanelBody title={__('Ajustes de resaltador de código', 'example')}>
		<TextControl
			label={__('Lenguaje de programación', 'example')}
			value={language}
			onChange={(value) => setAttributes({ language: value })}
		/>
		<ToggleControl
			label={__('Mostrar enumeración', 'example')}
			checked={showLineNumbers}
			onChange={(value) => setAttributes({ showLineNumbers: value })}
		/>
		<TextControl
			label={__('Empezar enumeración por', 'example')}
			value={startingLineNumber}
			onChange={(value) => setAttributes({ startingLineNumber: value })}
		/>
	</PanelBody>
</InspectorControls>

Este es el resultado: