Creación de Bloque Nativo con Renderizado del Lado del Servidor (SSR)
Clase 25 de 29 • Curso Profesional de WordPress
La construcción de un bloque nativo con SSR (Server Side Render) lleva algunos pasos:
- Modificar los atributos del componente
- Agregar los componentes necesarios para poder editar todos los campos del bloque
- Crear las funciones necesarias para establecer los atributos de cada componente
- Modificar la función PHP de registro para que espere todos los atributos
- Modificar la función PHP de renderizado dinámico
Abórdalo paso a paso.
Modificar los atributos del componente
Tu componente debe tener dos atributos, el texto del titular y la imagen de portada. En el ejemplo "Basic Block" solo habías generado el atributo content
(que te va a servir para el título), pero no tenías ningún lugar donde guardar la imagen.
Para seguir las buenas prácticas, vas a agregar 2 atributos. Uno para la URL de la imagen y el otro para el texto alternativo de la misma, para colaborar con el SEO y la accesibilidad.
Ahora vamos a nuestro archivo index.js
y modifiquemos los atributos de la siguiente manera:
attributes: { content: { type: 'string', // Definimos el tipo de dato que debe esperar el componente. En este caso es un texto, por eso lo declaramos como string. default: 'Hello world' // Definimos el valor por defecto. }, mediaURL: { type: 'string' // Definimos el tipo de dato que debe esperar el componente. En este caso es un texto (URL de la imagen), por eso lo declaramos como string. }, mediaAlt: { type: 'string' // Definimos el tipo de dato que debe esperar el componente. En este caso es un texto (Texto Alternativo de la imagen), por eso lo declaramos como string. } }
Como vemos, agregamos mediaURL
y mediaAlt
con las características que sirven para que el componente sepa que tipo de dato esperar.
Agregar los componentes necesarios para poder editar todos los campos del bloque
Ahora que ya configuraste los nuevos atributos, tienes que analizar qué componentes vas a utilizar. En este caso, es un componente que se denomina MediaUpload
y que te permitirá elegir la imagen de portada.
Para ello vamos a importarlo desde el paquete @wordpress/block-editor
de la siguiente manera:
import { InspectorControls, MediaUpload } from '@wordpress/block-editor'; // Esta librería está disponible desde que instalamos el paquete "wordpress/scripts" desde NPM
Por otro lado, necesitas un botón que pueda desencadenar el evento para elegir la imagen, por eso importaremos el componente Button
desde el paquete @wordpress/components
.
Luego vas a modificar la UI en la sidebar para incorporar el elemento dentro de la clave edit
:
<InspectorControls> <PanelBody title="Modificar texto del Bloque Básico" initialOpen={ true } > <PanelRow> <TextControl label="Complete el campo" // Indicaciones del campo value={ content } // Asignación del atributo correspondiente onChange={ handlerOnChangeInput } // Asignación de función para gestionar el evento OnChange /> </PanelRow> </PanelBody> <PanelBody title="Seleccioná una imagen" initialOpen={ true } > <PanelRow> <MediaUpload onSelect={ handlerOnSelectMediaUpload } // Asignación de función para gestionar el evento OnSelect type="image" // Limita los tipos de archivos que se pueden seleccionar // Se envía el evento open y el renderizado del elemento que desencadenará la apertura de la librería, en este caso un botón render={ ({open}) => { //Agregamos las clases de los botones de WordPress habituales para que mantenga el estilo dentro del editor return <Button className="components-icon-button image-block-btn is-button is-default is-large" onClick={open}>Elegir una imagen</Button>; }} /> </PanelRow> </PanelBody> </InspectorControls>
Crear las funciones necesarias para establecer los atributos de cada componente
Como puedes ver en el código anterior, vamos a crear la función handlerOnSelectMediaUpload
para establecer los atributos del componente.
Por eso, vamos a crearla dentro de tu clave edit
:
const handlerOnSelectMediaUpload = (image) => { setAttributes({ mediaURL: image.sizes.full.url, // El objeto image cuenta con todas las propiedades de los archivos de la Media Library de WordPress, entre ellas los diferentes tamaños mediaAlt: image.alt // También cuenta con el Texto Alternativo definido en la Media Library para cada archivo }) }
Dentro de image
vas a poder acceder a todas las características de las imágenes de la galería de WordPress, es decir, a toda la información del archivo y a todos los metadatos.
Es por eso que vas a asignar el image.alt
que es el campo que se completa en la librería de medios de WordPress. Por otro lado, asignamos el valor de la URL de la imagen del tamaño completo, por eso utilizamos image.sizes.full.url
.
El código del tu clave edit
quedará así:
edit: (props) => { const { attributes: {content}, setAttributes, className, isSelected} = props; // Función para guardar el atributo content const handlerOnChangeInput = (newContent) => { setAttributes( {content: newContent}) } // Función para guardar el atributo mediaURL y mediaAlt const handlerOnSelectMediaUpload = (image) => { setAttributes({ mediaURL: image.sizes.full.url, mediaAlt: image.alt }) } return <> <InspectorControls> <PanelBody // Primer panel en la sidebar title="Modificar texto del Bloque Básico" initialOpen={ true } > <PanelRow> <TextControl label="Complete el campo" // Indicaciones del campo value={ content } // Asignación del atributo correspondiente onChange={ handlerOnChangeInput } // Asignación de función para gestionar el evento OnChange /> </PanelRow> </PanelBody> <PanelBody // Segundo panel en la sidebar title="Seleccioná una imagen" initialOpen={ true } > <PanelRow> <MediaUpload onSelect={ handlerOnSelectMediaUpload } // Asignación de función para gestionar el evento OnSelect type="image" // Limita los tipos de archivos que se pueden seleccionar // Se envía el evento open y el renderizado del elemento que desencadenará la apertura de la librería, en este caso un botón render={ ({open}) => { //Agregamos las clases de los botones de WordPress habituales para que mantenga el estilo dentro del editor return <Button className="components-icon-button image-block-btn is-button is-default is-large" onClick={open}>Elegir una imagen</Button>; }} /> </PanelRow> </PanelBody> </InspectorControls> <ServerSideRender // Renderizado de bloque dinámico block="pg/basic" // Nombre del bloque attributes={ props.attributes } // Se envían todos los atributos /> </> }
Modificar la función PHP de registro para que espere todos los atributos
Ahora que tu JS está listo, tienes que hacer los cambios necesarios en las funciones PHP. Para ello lo primero es anticiparle al servidores, cuales son los atributos que recibirá el bloque.
Para ello se debe modificar la función de registro del bloque de la siguiente manera en el archivo functions.php
:
// Asignación de la función de registro del bloque al Hook "init" add_action('init', 'pgRegisterBlock'); // Función de registro del bloque function pgRegisterBlock() { // Tomamos el archivo PHP generado en el Build $assets = include_once get_template_directory().'/blocks/build/index.asset.php'; wp_register_script( 'pg-block', // Handle del Script get_template_directory_uri().'/blocks/build/index.js', // Usamos get_template_directory_uri() para recibir la URL del directorio y no el Path $assets['dependencies'], // Array de dependencias generado en el Build $assets['version'] // Cada Build cambia la versión para no tener conflictos de caché ); register_block_type( 'pg/basic', // Nombre del bloque array( 'editor_script' => 'pg-block', // Handler del Script que registramos arriba 'attributes' => array( // Repetimos los atributos del bloque, pero cambiamos los objetos por arrays 'content' => array( 'type' => 'string', 'default' => 'Hello world' ), 'mediaURL' => array( 'type' => 'string' ), 'mediaAlt' => array( 'type' => 'string' ) ), 'render_callback' => 'pgRenderDinamycBlock' // Función de callback para generar el SSR (Server Side Render) ) ); }
Como puedes ver, es la misma estructura que ya habías generado en tu JS.
Modificar la función PHP de renderizado dinámico
El último paso es modificar el renderizado dinámico del bloque para que tenga en cuenta todos los atributos.
Para ello vamos a utilizar de base el que generaste con ACF y vamos a reproducir esa misma estructura en la función de renderizado en el archivo functions.php
. Haciendo esto, tu código debería quedar de la siguiente manera:
// Función de callback para el SSR (Server Side Render) function pgRenderDinamycBlock($attributes, $content) { return ( '<h1 class="my-3">'.$attributes['content'].'</h1> <img src="'.$attributes['mediaURL'].'" alt="'.$attributes['mediaAlt'].'" /> <hr>' ); }
De esta forma, estás incorporando todos los atributos y componentes a tu bloque nativo.
Si todo salió bien, esto es lo que deberías ver en tu navegador al incorporar tu Basic Block:
Recuerda que siempre que hagas cambios en tu código JS tienes que volver a compilar o tienes que tener activado el comando npm run start
para que cada vez que guardes compile nuevamente tu bloque.