Use el título de la página en el bloque de banner personalizado de Gutenberg

4 minutos de lectura

Creé un bloque de imagen de banner personalizado para Gutenberg, que funciona muy bien, pero quiero saber si es posible usar el título de la página como marcador de posición de texto de banner actual hasta que se haya editado.

ingrese la descripción de la imagen aquí

Mi función de edición es

 return [
            el('div', {className:'header-banner'},
                el(
                    element.Fragment,
                    null,
                    controls,
                    el( "div",{
                        className: 'banner-image',
                        style: { backgroundImage: 'url('+attributes.mediaURL+')' }
                    },
                    attributes.title || isSelected ?  el(RichText, {
                            key: 'editable',
                            tagName: "h1",
                            className: "banner-title",
                            //Can i add the page title in here if it is avaiable??
                            //placeholder: i18n.__('Write title…'),
                            value: attributes.title,
                            onChange: function onChange(value) {
                                return props.setAttributes({ title: value });
                            },
                            inlineToolbar: true
                        }) : null 

                    )
                )
            )//header-banner
        ];    

Gracias 🙂

avatar de usuario
joemaller

Gutenberg almacena el estado actual del editor usando wp.datos, que es una abstracción sobre Redux. Para obtener el título (o 100+ otros valores), tenemos que consultar el core/editor Almacén de datos. Gutenberg simplifica la recuperación de atributos de publicaciones con getEditedPostAttribute.

Una vez que sabemos dónde buscar, conseguir el título es sencillo:

const { select } = wp.data;
const title = select("core/editor").getEditedPostAttribute( 'title' );

Eso funciona, pero no responde. Cuando cambia el título de la publicación, title no reflejará el nuevo valor. Eso es una especie de decepción.

Para reflejar los cambios en el título del editor, debemos escuchar los cambios en el core/editor Almacén de datos. Hay algunas maneras de hacer esto.

Una solución es definir una función de controlador de cambios simple y suscribirla a las actualizaciones del almacén de datos:

const { select } = wp.data;

function logTitle() {
  const title = select("core/editor").getEditedPostAttribute( 'title' );
  console.log("Editor Title:", title);
}
subscribe(logTitle);

Eso disparará cuando ningún wp.data el valor de la tienda se actualiza, lo que sucede mucho.

Lo que parece ser la forma sancionada por Gutenberg de incluir valores de almacenamiento de datos es usar un componente de orden superior para incluir el valor directamente:

const GetTitle = props => <div>{props.title}</div>;

const selectTitle = withSelect(select => ({
  title: select("core/editor").getEditedPostAttribute( 'title' )
}));
const PostTitle = selectTitle(GetTitle);

Luego, en la salida del bloque, incluya un <PostTitle /> etiqueta jsx. Eso es mucho más limpio que las devoluciones de llamadas anidadas u otro controlador de cambios.

Los componentes de orden superior pueden ser difíciles de seguir. La breve explicación es que envuelven un componente existente, generan algunos datos y luego devuelven una copia del componente con los nuevos datos pasados ​​como accesorios. Esto separa la lógica de la presentación y ayuda con la mantenibilidad.

GetTitle es bastante simple, es solo un pequeño componente que toma un props objeto con una clave de título y escupe algo de html.

withSelect es un constructor o decorador de funciones. Acepta un argumento de función y devuelve una nueva función que espera un componente. Normalmente, la función devuelta se invoca inmediatamente (una especie de IIFE) pero lo almacené en el selectTitle variables para mayor claridad. La nueva función genera un objeto que contiene el título, este objeto se pasará como accesorios a cualquier componente pasado a withSelect. A través de un poco de magia, esto se llamará cada vez que se actualice el almacén de datos.

Al final, PostTitle contiene la función resultado de selectTitle que es un componente rellenado previamente con los accesorios generados. Este componente se puede colocar en nuestro marcado usando un <PostTitle /> etiqueta. Siempre que se actualice el almacén de datos del editor, el componente de nivel superior reflejará los nuevos datos.

  • Muchas gracias por esto, funciona muy bien. Muy buena explicación también 🙂

    – Jim-miraidev

    13 de agosto de 2018 a las 8:26

  • ¿Puedes usar PostTitle para actualizar un atributo? como puedo hacer que funcione en el editor, pero no parece actualizar el contenido de la interfaz

    – Jim-miraidev

    16 de agosto de 2018 a las 8:26


  • la getDocumentTitle selector quedó en desuso y se eliminó. github.com/WordPress/gutenberg/pull/9623

    – joemaller

    1 oct 2018 a las 19:59

  • uso de @joemaller getEditedPostAttribute( 'title' ) en cambio

    – jla

    9 de septiembre de 2019 a las 6:46

@joemaller gracias por la útil respuesta.

Aquí hay un ejemplo que demuestra el uso withSelect() para envolver un componente definido a través del edit propiedad del objeto de configuración de bloque pasado a registerBlockType().

El componente se pasa el title a través de accesorios.

Si el usuario edita el título de la publicación/página, el componente se vuelve a representar con el nuevo título porque sus accesorios habrán cambiado. Esto le permite actualizarse en “tiempo real”.

import { withSelect } from '@wordpress/data'

edit: withSelect(
  ( select ) => {
    return {
      title: select( 'core/editor' ).getEditedPostAttribute( 'title' ),
    }
  } )( props => {
    return (
      <div>{ props.title }</div>
    )
} ),

¿Ha sido útil esta solución?