Ú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:
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:
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 }) ) ); } } );
Queremos tu opinión :)