Cómo agregar una selección de imagen en su bloque Gutenberg personalizado de WordPress
Esta publicación es para usted que está creando un bloque de Gutenberg personalizado y necesita una forma de seleccionar o cargar una imagen de la Biblioteca multimedia. La mayoría de los otros tipos de campos, como casillas de verificación, entradas de texto o selectores de colores, son bastante fáciles de agregar, pero un cargador de medios requiere un poco más de código. Crearemos un componente Inspector que es responsable de representar un botón para abrir la Biblioteca multimedia, seleccionar una imagen y, opcionalmente, eliminarla o cambiarla más adelante. Todo usando componentes estándar de WordPress.
Antes de sumergirnos en el código, tenga en cuenta que esta publicación requiere algunos conocimientos de Gutenberg sobre cómo escribir bloques personalizados. Nos centraremos solo en la parte del cargador de medios y no en cómo registrarse y hacer un bloque de Gutenberg en sí mismo. Si no está seguro de cómo escribir un bloque de Gutenberg personalizado, tengo una serie de tutoriales que cubren exactamente esto:
Con eso fuera del camino, ¡vamos a sumergirnos!
que haremos
La función de selección de medios será funcionalmente exactamente igual que la función de imagen destacada de WordPress. Agregaremos dentro de Inspector un panel que consistirá en un botón para elegir una imagen.
Al hacer clic en el botón, aparecerá la ventana "Seleccionar o cargar medios" que le permitirá seleccionar un archivo de la Biblioteca de medios. Limitamos la Biblioteca de medios para mostrar solo imágenes. Una vez que se selecciona una imagen, la ventana emergente se cierra y el panel muestra una vista previa de una pequeña miniatura de la imagen seleccionada. Debajo de los botones de vista previa para cambiar y eliminar la imagen aparecerán. Exactamente como con la imagen destacada.
Este tutorial asume que utilizará la imagen seleccionada como fondo del bloque, solo como ejemplo. Es por eso que almacenamos la URL de la imagen. Incluiré un ejemplo de cómo usar la imagen seleccionada (tanto en el edit
como en la save
función). Al elegir una imagen, la imagen aparecerá como fondo de nuestro bloque, tanto dentro del editor como en la interfaz.
Almacenamos la ID del medio y la URL del medio en los atributos del bloque. El código usa withSelect
, un componente de orden superior provisto en el wp.data
paquete, para consultar más información sobre los medios seleccionados, por ID.
También estoy "tomando prestados" los nombres de las clases de la funcionalidad de imagen destacada de WordPress para garantizar que todo se vea bien y que no haya necesidad de escribir ningún CSS. Esto es, por supuesto, opcional.
Guardar los medios seleccionados en atributos
Lo que necesita guardar en los atributos de su bloque depende un poco de usted. Como mínimo, necesitamos almacenar la identificación de medios, obviamente. Esto podría ser suficiente si no necesita usar la URL de los medios en ninguna parte del código del script. Por ejemplo, si usa ServerSideRender
donde PHP es responsable de representar la salida del bloque. En ese caso, puede obtener fácilmente la URL de la imagen de la ID de medios usando, por ejemplo [wp_get_attachment_image_src](https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/)()
,. Sin embargo, en el siguiente ejemplo, muestro un ejemplo simple de mostrar la imagen como fondo de nuestro bloque, por lo que también almaceno la URL de medios como atributo. Usaremos el atributo URL tanto en edit
(para agregar el fondo en el editor) como en save
(para agregar el fondo en la interfaz).
Comencemos definiendo nuestros atributos. La ID de medios debe ser un número de tipo y el valor predeterminado es 0. Esto facilita la comparación. Y la URL de los medios debe ser una cadena de tipo con una cadena vacía predeterminada.
attributes: {
mediaId: {
type: 'number',
default: 0
},
mediaUrl: {
type: 'string',
default: ''
}
},
Creando el componente
Para que nuestro código sea más ordenado, definimos un componente separado para la edit
función del bloque. Más adelante pasaremos este componente a withSelect
as para envolverlo alrededor de nuestro componente.
En el retorno del componente hacemos un simple <div>
para el contenido del bloque. Supongo que tendrá o tendrá más contenido de bloque real para reemplazar el contenido de ejemplo ficticio. También renderizamos InspectorControls
(paquete wp.blockEditor
) para agregar una sección al inspector. Por ahora agrego un vacío PanelBody
dentro del archivo InspectorControls
. Agrego una <div>
con la misma clase que usa la sección de imágenes destacadas de WordPress. Esto asegura que nuestro estilo se vea bien. Más adelante, completaremos esto PanelBody
con el código para la función de selección de medios.
Pero primero, desestructuramos el componente necesario al comienzo del archivo:
const { InspectorControls } = wp.blockEditor;
const { PanelBody } = wp.components;
const { Fragment } = wp.element;
Encima registerBlockType
defino un componente simple llamado BlockEdit
. Si prefiere mover esto a un archivo separado, puede hacerlo. Esto es común y recomendado, pero para este tutorial mantendré las cosas simples y las mantendré en el mismo archivo.
Ahora queremos representar este componente en nuestra edit
función. Pero queremos envolverlo en un withSelect
.
Usando withSelect
en la edit
función
Si no está familiarizado con withSelect
, es un componente útil de orden superior que nos permite realizar consultas. Puede, por ejemplo, consultar publicaciones con esto. Sin embargo, utilizaremos la función select('core').getMedia()
para consultar la ID del medio. Como respuesta obtendremos un objeto con toda la información del medio. El objeto multimedia que obtengamos como respuesta se proporcionará como accesorio en nuestro BlockEdit
componente, listo para usar. Hábil.
Nos aseguramos de consultar los medios solo si el atributo de ID de medios realmente está configurado en algo distinto de 0. Así es como se verá nuestra función de edición:
Al final, después de cerrar la withSelect
fila, #3
es donde solicitamos withSelect
la devolución de nuestro BlockEdit
componente. Con esto, nuestro BlockEdit
componente ahora tiene acceso a props.media
.
Representación de una selección de medios
Finalmente viene la parte divertida: La parte del Inspector.
El componente que nos interesa es MediaUpload
(paquete wp.blockEditor
). Si está interesado, el repositorio de WordPress Github para Gutenberg tiene documentación sobre este componente. También envolveremos este componente dentro de un componente llamado MediaUploadCheck
(paquete wp.blockEditor
). Este componente se asegura de que el usuario actual tenga capacidades para usar la biblioteca de medios, por lo que es una buena práctica usar esto.
El MediaUpload
componente tiene un accesorio requerido: render
. La forma en que funciona este componente es que definimos una función para el render
accesorio donde representamos la salida para el "área de carga de medios". En nuestro caso, representaremos un Button
(paquete wp.components
). Dentro del accesorio de representación de MediaUpload, tenemos acceso a la open
función a la que podemos llamar para que WordPress abra la ventana emergente de la Biblioteca multimedia:
Hay algunos accesorios más disponibles para MediaUpload
. Cubriremos los más importantes para hacerlo funcional en este tutorial, pero hay algunos más con los que puede jugar. Al menos, podría estar interesado en el accesorio allowedTypes
donde puede limitar qué tipos de archivos son posibles de seleccionar en la Biblioteca. En nuestro caso, lo configuramos para permitir solo imágenes.
Agregando elMediaUpload
Primero desestructura los nuevos componentes;
const { Button } = wp.components;
const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
Agreguemos MediaUploadCheck
y MediaUpload
dentro de nuestro div
en nuestro PanelBody
:
El código anterior se desestructura open
dentro de la función para render
. Representamos un simple Button
donde su onClick
propiedad ejecutará la open
función. También agregué los mismos nombres de clase que la funcionalidad de imagen destacada de WordPress para garantizar que no necesitemos agregar ningún estilo.
Dentro del Button
componente comprobamos si se ha configurado o no una imagen (attributes.mediaId
). Si no es así, hacemos eco del texto “Elegir una imagen". Ahora deberíamos tener esto en nuestro bloque.
Al hacer clic en el botón, debería aparecer la ventana emergente de la biblioteca multimedia. Sin embargo, seleccionar una imagen no funciona en este momento, porque nos faltan los accesorios onSelect
y en. Arreglemos eso ahora. Configuramos la ID de medios seleccionada y configuramos para ejecutar una función que luego definiremos dentro de nuestro componente.value``MediaUpload``value``onSelect
Definamos la onSelectMedia
función dentro de nuestro componente.
Manejo de selección de medios
Nota: Estoy definiendo mis funciones como funciones de flecha (onSelectMedia =() => { }
). Las funciones de flecha son bastante nuevas en ESNext y bastante ingeniosas. La desventaja es que el uso de funciones de flecha requiere que agregue soporte para esto en su configuración de Babel. Si no lo ha hecho, le recomiendo que busque bajo el título "Configuración de Babel" en esta publicación.
Justo antes de la declaración de devolución del componente, defino una onSelectMedia
función. Todo lo que necesitamos hacer es actualizar nuestros atributos usando setAttributes()
. Como parámetro onSelectMedia
obtenemos un objeto multimedia. Simplemente extraemos lo que necesitamos del objeto multimedia. En nuestro caso, es la ID del medio y la URL de tamaño completo, que son las propiedades id
y url
respectivamente.
Pruébelo ahora y ahora podrá seleccionar una imagen de la Biblioteca multimedia. Los medios seleccionados se guardan en los atributos del bloque. Sin embargo, todavía no hay una vista previa en el Inspector, y debido a que ha seleccionado una imagen, el botón para seleccionar una imagen desaparece. El panel ahora está vacío. El siguiente paso es mostrar la vista previa siempre que se haya seleccionado una imagen, así como proporcionar opciones para eliminarla o cambiarla.
Representación de una imagen de vista previa
Dentro del Button
componente que renderizamos dentro MediaUpload
de la render
prop hacemos eco del texto "Elegir una imagen" si una imagen aún no está configurada. Pero necesitamos agregar algo de código para cuando se establece una imagen aquí; una vista previa
Para ayudarnos a generar una buena vista previa, usamos el componente ResponsiveWrapper
(paquete wp.components
). Para que ResponsiveWrapper
funcione completamente, necesitamos proporcionar accesorios para la altura y el ancho. También necesitamos la URL de la miniatura. No tiene sentido usar la URL completa (que puede ser gigantesca) para generar una vista previa dentro del Inspector. Aquí es donde withSelect
entra la propiedad. Dentro del componente representamos una <img>
etiqueta HTML simple.
Primero desestructuramos el componente necesario:
const { ResponsiveWrapper } = wp.components;
Como podéis ver accedemos al prop withSelect
que nos ha facilitado el componente, props.media
. Obtenemos el ancho, el alto y la URL al tamaño de la miniatura de los medios del objeto.
¡Ahora debería obtener una buena vista previa de la imagen seleccionada!
Debido a que representamos la imagen de vista previa dentro, al Button
hacer clic en la imagen de vista previa se activará la Button
función onClick
de, que es abrir la Biblioteca de medios. De esa manera ya puedes cambiar la imagen seleccionada.
Actualmente no hay forma de eliminar o restablecer la imagen seleccionada. ¡Arreglemos eso!
Agregar una función de eliminación
Como mínimo, deberíamos ofrecer la posibilidad de que el usuario elimine la imagen seleccionada. A partir de ahora, una vez que haya seleccionado una imagen, solo puede cambiarla, pero no eliminarla.
Haremos lo mismo que hace WordPress para la imagen destacada: una nueva Button
debajo de la imagen de vista previa (totalmente fuera de su MediaUploadCheck
). Al proporcionarle algunos accesorios inteligentes Button
, hacemos que se vea como un enlace (isLink
) con color de texto rojo (isDestructive
). Lea la documentación de Button para ver qué más es posible. Envolvemos el botón dentro de otro MediaUploadCheck
, solo para asegurarnos de que el usuario tenga las capacidades correctas.
Para este evento Button
ejecutamos onClick
una nueva función dentro de nuestro componente: removeMedia()
. Lo definimos en algún lugar justo antes de la función de retorno del componente, como hicimos con onSelectMedia
.
Todo lo que hace esta función es restablecer nuestros dos valores de atributo.
Ahora tendremos un enlace agradable y claro para eliminar la imagen:
Al hacer clic en el botón nuevo, la imagen seleccionada y el botón mismo desaparecen, y vuelve a aparecer el botón para seleccionar una imagen.
Agregar un botón de reemplazo
Este paso es totalmente opcional. Como se mencionó anteriormente, hacer clic en la imagen de vista previa de la imagen abrirá la Biblioteca multimedia y le permitirá cambiar la imagen. Sin embargo, esto podría no ser tan intuitivo para que todos lo entiendan. WordPress agrega un botón separado para cambiar la imagen, solo para que quede muy claro. Podemos hacer lo mismo.
Para renderizar un botón de cambio de imagen básicamente repetimos el código que tenemos para seleccionar la imagen: otro MediaUpload
componente. Proporcionamos la misma función para onSelect
, allowedFileTypes
y value
que antes. Dentro del render
accesorio para MediaUpload
simplemente renderizamos otro Button
que abre la Biblioteca multimedia. Coloquemos este botón antes del botón Eliminar, ya que tiene más sentido para el usuario final:
Así que ahora deberías obtener esto:
Usando la imagen seleccionada
A estas alturas, debería estar bastante claro cómo puede usar la imagen seleccionada. Tiene el ID de medios y la URL de medios almacenados en los atributos de su bloque. Sin embargo, como un ejemplo simple, incluiré un código que establece la imagen seleccionada como fondo del bloque. El código se puede hacer exactamente igual en edit
las save
funciones y. Simplemente creamos un objeto de estilo que aplicamos en el div envolvente del bloque. En el objeto de estilo, establecemos la imagen de fondo en la URL de los medios.
Con el resto del contenido de su bloque personalizado, fácilmente podría verse así:
Si aplica el estilo de bloque en ambos edit
y save
, su bloque ahora debería tener los medios seleccionados como fondo. Tanto dentro del editor como en el frontend.
Conclusión
Seleccionar una imagen (o archivo) de la biblioteca multimedia es una función que usted, como desarrollador de Gutenberg, sin duda necesitará para sus bloques. Aprendimos cómo agregar una función para seleccionar una imagen de la biblioteca multimedia en nuestro bloque personalizado de Gutenberg. Lo hemos hecho de la misma manera que WordPress lo hace para la imagen destacada. (Edición de mayo de 2020: WordPress ahora ha actualizado la imagen destacada para usar useSelect
, el gancho React en su lugar). Esto asegura que nuestro código no sea "pirateado" con un alto riesgo de romperse en futuras actualizaciones.
¡Déjame saber si has tenido algún uso de esto!
código completo
A continuación se muestra el código completo de un bloque personalizado que presenta la función de selección de medios. Y nada más realmente. ¡Esa parte depende de ti!