>

Creando bloques personalizados para Gutenberg de WordPress

Fernan Díez     Colaboraciones    01/12/2017

Pongámonos en contexto y expliquemos en primer lugar qué es esto de Gutenberg. El proyecto Gutenberg tiene como fundamento sustituir el actual editor visual TinyMCE que utilizamos en WordPress por un nuevo editor más completo y pensado para que el usuario final pueda disponer de más posibilidades a la hora de crear y maquetar sus contenidos.

Bloques WordPress Gutenberg

Gutenberg será, por lo tanto, el nuevo editor visual para WordPress y que actualmente ya está disponible en formato plugin y las previsiones anuncian que la próxima versión 5 podría incluso incluirlo en su núcleo.

Publicando en WordPress mediante bloques

Una de las principales particularidades de Gutenberg es que funcionará a partir de elementos de contenido llamados bloques. Los bloques soportados hasta el momento son los de párrafo, imagen, titulares, galería, citas o listas entre otros.

También podremos agrupar esos bloques en filas y columnas para poder formatear el resultado de los contenidos que introduzcamos, dotando al editor visual de múltiples posibilidades.

Bloques personalizados para Gutenberg en WordPress

Las posibilidades de introducción de contenidos aumentan cuando vamos a poder ser capaces de crear nuestros propios bloques de contenido personalizados para Gutenberg.

Los párrafos, imágenes y otros contenidos pueden quedarse cortos, y quizás, queramos añadir directamente desde el editor bloques nuevos para crear textos resaltados, llamadas a la acción, botones destacados o diferentes animaciones que ofrezcan efectos visuales a la información publicada.

En este sentido, entra en juego la posibilidad de crear bloques personalizados, que de un modo más o menos ágil y con ciertos conocimientos vamos a poder utilizar cuando Gutenberg se incorpore finalmente al core de WordPress.

Una de las claves de WordPress y de otros componentes es que podamos extender sus funcionalidades, en ese sentido, Gutenberg cumple con esa premisa.

Gutenberg dispone de una API que permite conectarse a los servicios principales, siendo la sección de la Block API, uno de los módulos más interesantes. Si consultamos la documentación oficial actual de Gutenberg nos podremos encontrar con algunos ejemplos que nos facilitan su comprensión y que trataremos de explicar en las siguientes líneas.

Creando nuestro primer bloque personalizado

Partiendo de un ejemplo sencillo podremos implementar bloques de contenido estático mediante JavaScript con la función registerBlockType que es la función responsable de crear las especificaciones de un nuevo bloque.

De este modo nos permitirá indicar al editor cómo debe aparecer, aplicar los cambios en la edición y finalmente guardar el contenido.

La implementación del bloque se realiza mediante JavaScript si bien necesitaremos utilizar la acción enqueue_block_editor_assets de WordPress para incluir los scripts en el editor, un comportamiento similar a la ya conocida acción wp_enqueue_scripts para encolar estilos y scripts en WordPress.

/* 
Enqueuing Block Scripts
https://wordpress.org/gutenberg/handbook/blocks/writing-your-first-block-type/
*/
function gutenberg_boilerplate_enqueue_block_editor_assets() {
    wp_enqueue_script(
        'gutenberg-boilerplate-es5-step01',
        plugins_url( 'step-01/block.js', __FILE__ ),
        array( 'wp-blocks', 'wp-element' )
    );
}
add_action( 'enqueue_block_editor_assets', 'gutenberg_boilerplate_enqueue_block_editor_assets' );

Una vez que el bloque se registra deberíamos poder comprobar cómo se muestra inmediatamente dentro del editor como opción disponible. Podremos además incluir elementos visuales como los iconos prestablecidos de Dashicons, u otros elementos relacionados con las funciones de edición y guardado.

var el = wp.element.createElement,
    registerBlockType = wp.blocks.registerBlockType,
    blockStyle = { backgroundColor: '#900', color: '#fff', padding: '20px' };

registerBlockType( 'gutenberg-boilerplate-es5/hello-world-step-01', {
    title: 'Hello World (Step 1)',

    icon: 'universal-access-alt',

    category: 'layout',

    edit: function() {
        return el( 'p', { style: blockStyle }, 'Hello editor.' );
    },

    save: function() {
        return el( 'p', { style: blockStyle }, 'Hello saved content.' );
    },
} );

Herramientas para crear bloques de contenidos en Gutenberg

Como recomendación adicional para profundizar en más detalle, disponemos de algunos proyectos que nos pueden facilitar el aprendizaje del desarrollo de nuevos bloques de contenido para Gutenberg.

Entre otros ejemplos, nos encontramos con WordPress Gutenberg Boilerplate que se compone de un conjunto de herramientas y ejemplos base para la creación de bloques para Gutenberg. Es ideal si quieres adentrarte un poco más de lleno en el desarrollo de bloques de funcionalidades y quieres saber el porqué de cada paso.

Si necesitamos, por ejemplo, crear un bloque personalizado con contenido dentro de una caja resaltada tendremos un patrón por donde empezar.

De este modo podemos utilizar este pequeño framework para registrar un nuevo bloque personalizado a través de este archivo block.js:

	/**
 * BLOCK: Basic
 *
 * Registering a basic block with Gutenberg.
 * Simple block, renders and saves the same content without any interactivity.
 *
 * Styles:
 *        editor.css — Editor styles for the block.
 *        style.css  — Editor and Front end styles for the block.
 */
( function() {
	var __ = wp.i18n.__; // The __() for internationalization.
	var el = wp.element.createElement; // The wp.element.createElement() function to create elements.
	var registerBlockType = wp.blocks.registerBlockType; // The registerBlockType() to register blocks.

	/**
	 * Register Basic Block.
	 *
	 * Registers a new block provided a unique name and an object defining its
	 * behavior. Once registered, the block is made available as an option to any
	 * editor interface where blocks are implemented.
	 *
	 * @param  {string}   name     Block name.
	 * @param  {Object}   settings Block settings.
	 * @return {?WPBlock}          The block, if it has been successfully
	 *                             registered; otherwise `undefined`.
	 */
	registerBlockType( 'gb/01-basic', { // Block name. Block names must be string that contains a namespace prefix. Example: my-plugin/my-custom-block.
		title: __( 'Basic', 'GB' ), // Block title.
		icon: 'shield-alt', // Block icon from Dashicons → https://developer.wordpress.org/resource/dashicons/.
		category: 'common', // Block category — Group blocks together based on common traits E.g. common, formatting, layout widgets, embed.

		// The "edit" property must be a valid function.
		edit: function( props ) {
			// Creates a class='wp-block-gb-01-basic'>
			return el(
				'p', // Tag type.
				{ className: props.className }, // The class="wp-block-gb-01-basic" : The class name is generated using the block's name prefixed with wp-block-, replacing the / namespace separator with a single -.
				'Hello World! — from the editor (01 Basic Block).' // Content inside the tag.
			);
		},

		// The "save" property must be specified and must be a valid function.
		save: function( props ) {
			return el(
				'p', // Tag type.
				{ className: props.className }, // The class="wp-block-gb-01-basic" : The class name is generated using the block's name prefixed with wp-block-, replacing the / namespace separator with a single -.
				'Hello World! — from the frontend (01 Basic Block).' // Content inside the tag.
			);
		},
	} );
})();

Podremos dotarle de estilos que aparecerán en el propio editor visual desde el panel de administración a través del fichero editor.css:

	/**
 * ----------------------------------------------------------------------------
 * #.# Editor CSS
 *
 * BLOCK: 01-basic block CSS for the editor.
 * ----------------------------------------------------------------------------
 */

.wp-block-gb-01-basic {
	color: #000000;
	background: mistyrose;
	border: 0.2rem solid red;
	padding: 2rem;
}

Definiremos la parte relacionada con el CSS que deberá aparecer en el frontend con style.css:

	/**
 * ----------------------------------------------------------------------------
 * #.# Frontend CSS
 *
 * BLOCK: 01-basic block CSS for the editor & front end.
 * ----------------------------------------------------------------------------
 */

.wp-block-gb-01-basic {
	color: #000000;
	background: gold;
	border: 0.2rem solid goldenrod;
	padding: 2rem;
}

Crearemos la relación necesaria entre los archivos anteriores y el concatenaremos la carga tanto en el panel de administración como en el frontend de la web:

	/**
 * BLOCK: Basic
 *
 * Gutenberg Custom Block assets.
 *
 * @since   1.0.0
 * @package GB
 */
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
// Hook: Editor assets.
add_action( 'enqueue_block_editor_assets', 'gb_block_01_basic_editor_assets' );
/**
 * Enqueue the block's assets for the editor.
 *
 * `wp-blocks`: includes block type registration and related functions.
 * `wp-element`: includes the WordPress Element abstraction for describing the structure of your blocks.
 * `wp-i18n`: To internationalize the block's text.
 *
 * @since 1.0.0
 */
function gb_block_01_basic_editor_assets() {
	// Scripts.
	wp_enqueue_script(
		'gb-block-01-basic', // Handle.
		plugins_url( 'block.js', __FILE__ ), // Block.js: We register the block here.
		array( 'wp-blocks', 'wp-i18n', 'wp-element' ), // Dependencies, defined above.
		filemtime( plugin_dir_path( __FILE__ ) . 'block.js' ) // filemtime — Gets file modification time.
	);
	// Styles.
	wp_enqueue_style(
		'gb-block-01-basic-editor', // Handle.
		plugins_url( 'editor.css', __FILE__ ), // Block editor CSS.
		array( 'wp-edit-blocks' ), // Dependency to include the CSS after it.
		filemtime( plugin_dir_path( __FILE__ ) . 'editor.css' ) // filemtime — Gets file modification time.
	);
} // End function gb_block_01_basic_editor_assets().
// Hook: Frontend assets.
add_action( 'enqueue_block_assets', 'gb_block_01_basic_block_assets' );
/**
 * Enqueue the block's assets for the frontend.
 *
 * @since 1.0.0
 */
function gb_block_01_basic_block_assets() {
	// Styles.
	wp_enqueue_style(
		'gb-block-01-basic-frontend', // Handle.
		plugins_url( 'style.css', __FILE__ ), // Block frontend CSS.
		array( 'wp-blocks' ), // Dependency to include the CSS after it.
		filemtime( plugin_dir_path( __FILE__ ) . 'editor.css' ) // filemtime — Gets file modification time.
	);
} // End function gb_block_01_basic_block_assets().

En cualquier caso estamos proponiendo un ejemplo sencillo como referencia, pero si trabajamos más a fondo podremos dotar de elementos más complejos a nuestro editor. Algo muy interesante si somos desarrolladores de plugins para WordPress.

La nueva dirección de aquellas herramientas que puedan intervenir en el contenido deberán pasar por esta nueva metodología para poder ser implementadas correctamente en su conjunto.

Conclusiones

Hemos querido presentar con este artículo una forma diferente de aproximarse al desarrollo con WordPress y la mejora de la herramienta como sistema de publicación, siendo conscientes de todo el trabajo que se está realizando en la sombra por toda la comunidad de desarrolladores de WordPress.

Esperamos también que podamos disfrutar de Gutenberg como editor plenamente integrado en el núcleo de WordPress y poder comenzar a utilizarlo de manera habitual en nuestros proyectos. Y la verdad, cada vez queda menos tiempo para que llegue ese momento.


Sobre el autor

Fernan Díez   

Desarrollo Web WordPress & Marketing Online Publico 'WordPress Diario', un podcast sobre desarrollo web con WordPress y marketing online donde encontrarás consejos, herramientas y recomendaciones sobre todo lo que te puede interesar acerca del mundo del diseño web con WordPress, y el marketing digital.