¿Cómo usar MediaUpload, componente para bloques de Gutenberg?

Último tutorial en lo referente a Gutenberg, el nuevo editor de WordPress, en esta ocasión sobre el uso del componente MediaUpload. Este artículo tiene como base la herramienta «create-guten-block» para estructurar un bloque. Aunque también sirve como referencia para los que no lo usan. Si no estás informado sobre dicha herramienta, te invito a leer este otro artículo relacionado con ella.

Tutorial: MediaUpload

Nota: Recuerda que al final del documento adjunto el resultado del archivo generado con este tutorial.

Como toda herramienta, empezaremos declarándola junto a otros componentes que usaremos. También necesitamos registrar 2 atributos básicos para mostrar correctamente una imagen. Por ejemplo:

const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;

const { InspectorControls, MediaUpload } = wp.editor;

var el = wp.element.createElement;
var components = wp.components;
	attributes: {
		mediaURL: {
			type: 'string',
			source: 'attribute',
			selector: 'img',
			attribute: 'src',
		},
		mediaAlt: {
			type: 'string'
		}
	}

Luego dentro del parámetro edit configuramos la función setMedia para guardar los valores en los atributos asignados. Luego a la hora de renderizar los campos necesarios para subir la imagen, se podría optar por dos localizaciones: en el editor o en la barra lateral. Las localizaciones son a libre elección en función de lo que nos parezca más intuitivo para el usuario.

Campos en el editor

Esta forma es la más clásica, pues, como opinión personal, es la mejor para orientarnos en el documento. Para la renderización usaremos un array para generar 3 elementos: configuración para generar el botón de subida (1), el título que se mostrará en el editor (2) y el preview cuando se carga la imagen (3).

	edit: function( props ) {
		function setMedia( media ) {
			props.setAttributes(
				{
					mediaURL: media.url,
					mediaAlt: media.alt
				}
			);
		}

		return el( 'div', {className: props.className},
			el( MediaUpload, { // (1) Botón de subida
					onSelect: setMedia,
					type: 'image',
					render: function( obj ) {
						return el( components.Button, {
								className: 'components-icon-button image-block-btn is-button is-default is-large',
								onClick: obj.open
							},
							el( 'svg', { className: 'dashicon dashicons-edit', width: '20', height: '20' },
								el( 'path', { d: "M2.25 1h15.5c.69 0 1.25.56 1.25 1.25v15.5c0 .69-.56 1.25-1.25 1.25H2.25C1.56 19 1 18.44 1 17.75V2.25C1 1.56 1.56 1 2.25 1zM17 17V3H3v14h14zM10 6c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm3 5s0-6 3-6v10c0 .55-.45 1-1 1H5c-.55 0-1-.45-1-1V8c2 0 3 4 3 4s1-3 3-3 3 2 3 2z" } )
							),
							el( 'span', {},
								'Seleccionar imagen'
							)
						);
					}
				}
			),
			el( 'p', {}, 'Preview:'), // (2) Título
			el( 'img', { // (3) Preview
					src : props.attributes.mediaURL,
					alt : props.attributes.mediaAlt
				}
			)
		);
	}

El resultado sería el siguiente:

Mediaupload preview example editor gutenber

Campos en la barra lateral

Para mostrarlo en la barra lateral, será necesario usar el componente InspectorControls. Para la renderización usaremos un array para generar 3 elementos: configuración para generar el campo en la barra lateral (1), el título que se mostrará en el editor (2) y el preview cuando se carga la imagen (3).

	edit: function( props ) {
		function setMedia( media ) {
			props.setAttributes(
				{
					mediaURL: media.url,
					mediaAlt: media.alt
				}
			);
		}

		return [
			el( InspectorControls, {}, // (1) Barra lateral
				el( components.PanelBody, {
						title: 'Imagen personalizado',
						className: 'image-block',
						initialOpen: true,
					},

					el( MediaUpload, {
						onSelect: setMedia,
						type: 'image',
						render: function( obj ) {
							return el( components.Button, {
									className: 'components-icon-button image-block-btn is-button is-default is-large',
									onClick: obj.open
								},
								el( 'svg', { className: 'dashicon dashicons-edit', width: '20', height: '20' },
									el( 'path', { d: "M2.25 1h15.5c.69 0 1.25.56 1.25 1.25v15.5c0 .69-.56 1.25-1.25 1.25H2.25C1.56 19 1 18.44 1 17.75V2.25C1 1.56 1.56 1 2.25 1zM17 17V3H3v14h14zM10 6c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm3 5s0-6 3-6v10c0 .55-.45 1-1 1H5c-.55 0-1-.45-1-1V8c2 0 3 4 3 4s1-3 3-3 3 2 3 2z" } )
								),
								el( 'span', {},
									'Elegir imagen'
								),
							);
						}
					}),

				),
			),
			el( 'p', {}, 'Preview:'), // (2) Título para el bloque
			el( 'img', { // (3) Previsualización de la imagen
					src : props.attributes.mediaURL,
					alt: props.attributes.mediaAlt
				}
			)
		];
	}

El resultado sería el siguiente:

Ejemplo MediaUpload Preview Gutenberg

Por último, sin importar la localización que se elija, configuraremos el parámetro save para mostrar la imagen correctamente la imagen con solo los atributos mediaURL y mediaAlt.

	save: function( props ) {
		return (
			el( 'div', {
					className: props.className
				},
				el( 'img', {
					src: props.attributes.mediaURL,
					alt: props.attributes.mediaAlt
				})
			)
		);
	}

La configuración dará como resultado el siguiente HTML.

<div class="wp-block-cgb-block-hola-block">
    <img src="http://testing.wordpress.com/wp-content/uploads/2019/03/bg-somos.png" alt="Logo Irontec">
</div>

Hasta aquí finalizamos el tutorial en el uso del componente MediaUpload y espero que sea de ayuda para personalizar los proyectos con Gutenberg. El siguiente tutorial será de cómo cargar imágenes con la herramienta de WordPress en nuestro bloque.

block.js final

Adjunto el aspecto de mi archivo hola-block/src/block/block.js por si algún dato no quedó claro. Si llegase haber algún error, hacérmelo saber en los comentarios.

/**
 * BLOCK: hola-block
 *
 * Registering a basic block with Gutenberg.
 * Simple block, renders and saves the same content without any interactivity.
 */

//  Import CSS.
import './style.scss';
import './editor.scss';

const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;

const { InspectorControls, MediaUpload } = wp.editor;

var el = wp.element.createElement;
var components = wp.components;

registerBlockType( 'cgb/block-hola-block', {
	title: __( 'Hola Block - Irontec' ),
	icon: {
		background: '#a0251f',
		foreground: '#ffffff',
		src: 'heart'
	},
	category: 'common',
	keywords: [
		__( 'Hola Block — Irontec' ),
		__( 'CGB Example' ),
		__( 'create-guten-block' ),
	],
	attributes: {
		mediaURL: {
			type: 'string',
			source: 'attribute',
			selector: 'img',
			attribute: 'src',
		},
		mediaAlt: {
			type: 'string'
		}
	},
	edit: function( props ) {
		function setMedia( media ) {
			props.setAttributes(
				{
					mediaURL: media.url,
					mediaAlt: media.alt
				}
			);
		}

		return [
			el( InspectorControls, {}, // 1. Barra lateral
				el( components.PanelBody, {
						title: 'Imagen personalizado',
						className: 'image-block',
						initialOpen: true,
					},

					el( MediaUpload, {
						onSelect: setMedia,
						type: 'image',
						render: function( obj ) {
							return el( components.Button, {
									className: 'components-icon-button image-block-btn is-button is-default is-large',
									onClick: obj.open
								},
								el( 'svg', { className: 'dashicon dashicons-edit', width: '20', height: '20' },
									el( 'path', { d: "M2.25 1h15.5c.69 0 1.25.56 1.25 1.25v15.5c0 .69-.56 1.25-1.25 1.25H2.25C1.56 19 1 18.44 1 17.75V2.25C1 1.56 1.56 1 2.25 1zM17 17V3H3v14h14zM10 6c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm3 5s0-6 3-6v10c0 .55-.45 1-1 1H5c-.55 0-1-.45-1-1V8c2 0 3 4 3 4s1-3 3-3 3 2 3 2z" } )
								),
								el( 'span', {},
									'Elegir imagen'
								),
							);
						}
					}),

				),
			),
			el( 'p', {}, 'Preview:'), // 2. Título para el bloque
			el( 'img', { // 3. Previsualización de la imagen
					src : props.attributes.mediaURL,
					alt: props.attributes.mediaAlt
				}
			)
		];
	},
	save: function( props ) {
		return (
			el( 'div', {
					className: props.className
				},
				el( 'img', {
					src: props.attributes.mediaURL,
					alt: props.attributes.mediaAlt
				})
			)
		);
	}
} );

 



¿Te gusta este post? Es solo un ejemplo de cómo podemos ayudar a tu empresa...
Sobre Victor Vargas

Desarrollador de aplicaciones web y móviles. Mi experiencia se extiende en el desarrollo de módulos, plugins, scripts y temas para diversas plataformas como Wordpress, Prestashop, Magento, MediaWiki, CRM, Odoo, etc.

Queremos tu opinión :)