Contenido

  1. Primeros Pasos
    1. Creando un Plugin de WordPress
      1. Instalando las dependencias.
        1. Agregando webpack
          1. Archivos para crear el primer Bloque
            1. Creando el Primer Bloque
              1. Los 7 Pasos para utilizar los Componentes de Gutenberg.
                1. Paso 1: Importar el Componente o los Componentes que utilizarás.
                  1. Paso 2: Coloca el Componente donde deseas utilizarlo.
                    1. Paso 3: Crea una función que lea los contenidos del Componente
                      1. Paso 4: Registrar un Atributo
                        1. Paso 5: Extraer el Atributo desde Props.
                          1. Paso 6: Guarda el Contenido con setAttributes
                            1. Paso 7: Trabajar con save()
                              1. Código completo hasta aquí

                                El Desarrollo en WordPress está evolucionando en la dirección correcta. PHP aún juega un papel importante pero con Gutenberg ya es posible utilizar tecnologías modernas como React, webpack, npm para crear bloques.
                                Actualmente Gutenberg solo reside en el Editor de WordPress, pero en los próximos años temas completas serán realizados con Gutenberg.

                                Primeros Pasos

                                Para comenzar a trabajar con nuestro Primer Bloque es necesario instalar un ambiente de desarrollo y algunas herramientas, debido a que estaremos utilizando una herramienta llamada WP-Scripts que simplifica el desarrollo de Bloques de Gutenberg y la forma de agregarla en nuestro proyecto es con NPM es necesario instalar Node.js y NPM. En el sitio web de Node.js puedes descargarlo, una vez que sigues el wizard de instalación puedes comprobar la instalación en una terminal o command promp con los comandos:

                                node -v
                                npm -v

                                Si tienes un resultado con alguna versión, ya tienes instalado Node.js y npm.

                                Creando un Plugin de WordPress

                                El código de bloques personalizados de Gutenberg puede residir en un tema o en un Plugin por lo tanto en una instalación de WordPress en la carpeta wp-content/plugins/ creamos una carpeta llamada bloques-gutenberg y dentro de esta carpeta el archivo bloques-gutenberg.php, tenemos que agregar información para decirle a WordPress que este es un nuevo Plugin.

                                <?php
                                /*
                                    Plugin Name: Gutenberg Blocks para WordPress
                                    Plugin URI: 
                                    Description: Plugin para crear bloques de Gutenberg
                                    Version: 1.0.0
                                    Author: Juan De la torre
                                    Author URI: @JuanDevWP en Twitter
                                    Text Domain: guten
                                */

                                Una vez agregado este código y guardado el archivo accedemos a Plugins y activamos nuestro nuevo Plugin.

                                Después, copia el siguiente código (para más explicación de lo que hace este código puedes revisar los comentarios que he colocado en el)

                                <?php
                                
                                if ( ! defined( 'ABSPATH' ) ) exit; // Prevenir que el plugin sea ejecutado directamente
                                
                                
                                /** Registra Bloques Personalizados */
                                add_action( 'init', 'ccj_bloques');
                                
                                function ccj_bloques() {
                                
                                    // Si gutenberg no esta activado
                                    if ( !function_exists( 'register_block_type' ) ) {
                                        return;
                                    }
                                    
                                    // Registrar el archivo script.js para gutenberg
                                    wp_register_script(
                                        'ccj-editor-script',		// nombre
                                        plugins_url( 'build/index.js', __FILE__ ),		// archivo script
                                        array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor' ),	// dependencias
                                        filemtime( plugin_dir_path( __FILE__ ) . 'build/index.js' ) // version
                                    );
                                
                                    // Registrar CSS para el editor (unicamente)
                                    wp_register_style(
                                        'ccj-editor-styles',								// nombre
                                        plugins_url( 'build/editor.css', __FILE__ ),	// archivo
                                        array( 'wp-edit-blocks' ),						// dependencias
                                        filemtime( plugin_dir_path( __FILE__ ) . 'build/editor.css' )	//version
                                    );
                                
                                    // Registrar CSS para el frontend y editor
                                    wp_register_style(
                                        'ccj-frontend-styles',	// nombre
                                        plugins_url( 'build/style.css', __FILE__ ),	// CSS 
                                        array(), // dependencias
                                        filemtime( plugin_dir_path( __FILE__ ) . 'build/style.css' ) // version
                                    );
                                
                                    // Arreglo de Bloques (Conforme vayas creando bloques aqui deberás registrarlos)
                                    $blocks = [];
                                
                                    // Recorrer $blocks y agregar cada uno
                                    foreach( $blocks as $block ) {
                                		register_block_type( $block, array(
                                			'editor_script' => 'ccj-editor-script',	// agregar script de editor
                                			'editor_style' => 'ccj-editor-styles',	// agregar estilos de editor
                                			'style' => 'ccj-frontend-styles',	// agregar estilos frontend
                                		) );	  
                                    }
                                    
                                }
                                
                                

                                El código anterior puedes notar que carga un archivo llamado index.js en la carpeta build/ así como una hoja de estilos CSS para el frontend y una para el editor, en Gutenberg tendrás 2 hojas de estilos, en algunos casos una para ajustes o CSS en el editor, mientras que la otra para la presentación de tus bloques en el FrontEnd.

                                Instalando las dependencias.

                                El siguiente paso es crear un archivo package.json para manejar las dependencias de nuestro proyecto, en este caso WP-Scripts. por lo tanto puedes abrir tu terminal y navega hasta la carpeta del plugin o si utilizas VS Code puedes hacer lo siguiente:

                                Al escribir npm init, te aparecerán una serie de opciones, solo presiona enter o coloca la información como autor, nombre de paquete según creas conveniente.

                                Esto creará un archivo package.json donde se guardarán las dependencias ( o nombres de los paquetes que utilizaremos, así como sus versiones).

                                Vamos a instalar unas dependencias, en la misma terminal que esta abierto puedes colocar lo siguiente:

                                npm install @wordpress/scripts svgr/webpack url-loader --save-dev

                                Este paso toma alrededor de 5 o 10 minutos dependiendo tu conexión así que esperamos un poco. Una vez listo abrimos el package.json y busca una sección que dice “scripts” y reemplaza su contenido por el siguiente:

                                  "scripts": {
                                    "start": "wp-scripts start",
                                    "build": "wp-scripts build"
                                  },

                                WP-Scripts ya cuenta con una serie de scripts y funciones para simplificar el desarrollo de bloques de Gutenberg, es una excelente herramienta desarrollada por los creadores de Gutenberg.

                                Agregando webpack

                                Webpack nos permitirá crear un bundle optimizado para producción tomando todas las ventajas de Webpack como Code Splitting y mucho más, crea un archivo llamado webpack.config.js y agrega lo siguiente:

                                const defaultConfig = require("@wordpress/scripts/config/webpack.config");
                                 
                                module.exports = {
                                  ...defaultConfig,
                                  module: {
                                    ...defaultConfig.module,
                                    rules: [
                                      ...defaultConfig.module.rules,
                                      {
                                        test: /\.svg$/,
                                        use: ["@svgr/webpack", "url-loader"]
                                      }
                                    ]
                                  }
                                };

                                Archivos para crear el primer Bloque

                                En el plugin que hemos creado vamos a agregar una carpeta llamada src/ por lo tanto la estructura de nuestro proyecto será asi:

                                bloques-gutenberg/ 
                                   - node_modules/
                                   - src/
                                   - bloques-gutenberg.php
                                   - package.json
                                   - webpack.config.js

                                Dentro de esta carpeta llamada src/ colocaremos un archivo llamado index.js ya que WP-Scripts buscará este archivo en esta ubicación para comenzar a compilar los bloques de Gutenberg.

                                Después crearemos una carpeta para nuestro primer bloque, es buena práctica tener una carpeta por bloque que generes, por lo tanto en src/ crearemos la carpeta integrante y dentro un archivo llamado index.js, nuestra estructura será asi:

                                bloques-gutenberg/ 
                                   - node_modules/
                                   - src/
                                        - integrante/
                                            index.js
                                        - index.js
                                   - bloques-gutenberg.php
                                   - package.json
                                   - webpack.config.js

                                El siguiente paso es utilizar una de las nuevas caracteristicas de JavaScript e importar los contenidos de integrante/index.js, para ello abrimos el index.js que se encuentra en src/ y agregamos ell siguiente código

                                import "./integrante";

                                Es importante nombrar el archivo dentro de la carpeta integrante/ como index.js ya que de esta forma JavaScript buscará ese archivo automaticamente y no necesitas colocar el nombre del archivo en ese import. Escribe el siguiente comando en tu terminal:

                                npm start

                                Este comando ejecutará las tareas de WP-Scripts y te va a crear la carpeta build/ – que registramos en el plugin – así como el archivo index.js

                                A estas alturas es buena idea crear en build/ los archivos editor.css y style.css, lo puedes hacer manualmente en VS Code, más delante volveremos hacia esos archivos.

                                Creando el Primer Bloque

                                Cada bloque estará en una carpeta, por lo tanto estaremso trabajando en el archivo index.js de la carpeta integrante/ agrega el siguiente código en el archivo:

                                import { registerBlockType } from '@wordpress/blocks'; // importar función principal
                                
                                registerBlockType('ccj/integrante', { // El nombre va sin espacios y en minusculas
                                    title: 'Integrante Equipo', // Nombre del bloque
                                    icon: 'admin-users', // Cualquier dashicon
                                    category: 'layout', // Valores posibles: common, formatting, layout, widgets, embed
                                    edit: () => {
                                        return (
                                            <p>Todo lo que coloques en edit() se ve en Gutenberg</p>
                                        )
                                    },
                                    save: () => {
                                        return (
                                            <p>Todo lo que coloques en save() se ve en el front end/p>
                                        )
                                    }
                                });

                                Asegúrate de tener corriendo el comando npm start en tu terminal, una vez que guardes cambios y abras Gutenberg, en la categoría de Layout Elements encontrarás nuestro bloque.

                                Dependiendo de la categoría seleccionada es donde el bloque se mostrará, en nuestro caso nuestro código le dice a este bloque que deberá estar en ‘category: ‘layout’, otras opciones para la categoría son: common, formatting, layout, widgets, embed. Importante también mencionar que puedes crear tus propias categorías.

                                Los 7 Pasos para utilizar los Componentes de Gutenberg.

                                En Gutenberg la mayoría de componentes ya están desarrollados, existen componentes para subir fotos, videos, texto, columnas, etc. Para utilizarlos se siguen una serie de pasos que es lo que yo llamo: Los 7 Pasos para utilizar los Componentes de Gutenberg.

                                Paso 1: Importar el Componente o los Componentes que utilizarás.

                                Vamos a importar un componente que nos permite escribir, ya que de momento nuestro bloque no hace mucho, coloca el siguiente código en la parte superior de integrante/index.js

                                 import { RichText } from '@wordpress/editor';

                                En este caso importamos el componente RichText, de wordpress/editor, en el editor de Gutenberg puedes abrir la consola de tu navegador y escribir wp.editor para acceder a todos los componentes.

                                Paso 2: Coloca el Componente donde deseas utilizarlo.

                                Nuestro componente permite que el usuario escriba texto, por lo tanto lo colocaremos en el edit() para que el usuario pueda escribir en el mientras estamos en Gutenberg, también le pasaremos un placeholder para darle indicaciones al usuario, atributos como placeholder son valores que le puedes pasar a cada componente y pueden variar de acuerdo a los diferentes Componentes.

                                  return (
                                        <RichText 
                                            placeholder="Agrega el titulo de esta sección"
                                        />
                                    )

                                Paso 3: Crea una función que lea los contenidos del Componente

                                Tener un RichText nos permitirá escribir en el Componente, pero debemos escribir una función que lea sus contenidos, para ello utilizaremos un evento de React llamado onChange que detectará y ejecutará una función cada que un usuario este escribiendo, ya con la función nuestro edit() debe verse así:

                                    edit: () => {
                                
                                        // Funciones para leer los contenidos de nuestros componentes
                                        const onChangeNombre = (nuevoNombre) => {
                                            console.log(nuevoNombre)
                                        }
                                
                                        return (
                                          <p className="nombre">
                                             <RichText 
                                                   placeholder="Agrega el nombre del Integrante"
                                                   onChange={onChangeNombre}
                                              />
                                          </p>
                                        )
                                    }

                                De esta forma conforme el usuario escriba o utilice el componente, se estará enviando a la consola el contenido.

                                Paso 4: Registrar un Atributo

                                Los atributos son los que guardan la información, la cantidad y tipo de atributos que tengas serán la forma que deberá tener tu bloque, si creas un bloque para mostrar un testimonial, tus atributos serán un texto, imagen y nombre de la persona que escribe ese testimonial, por lo tanto serán únicos en cada componente, antes de la función edit() agregamos:

                                    attributes: {
                                        nombreIntegrante: {
                                            type: 'string',
                                            source: 'html', 
                                            selector: '.nombre'
                                        }
                                    },
                                    edit: () => // Código previo...

                                El atributo anterior, debido a que será utilizado para el RichText debemos decirle que guardará HTML y además será utilizado por el selector (similar a CSS) que tenga una clase llamado nombre, casi todos tus atributos deberán tener un selector que sea una clase y un selector tipo CSS.

                                Paso 5: Extraer el Atributo desde Props.

                                En Gutenberg también hay props al igual que en React, contienen funciones y los diferentes atributos, para extraerlos lo hacemos dentro de la función edit: (props) => – Siempre puedes enviar a la consola console.log(props) para poder ver el contenido de los props, aplicando destructuring de JavaScript podemos extraer el atributo desde props:

                                const { attributes: { nombreIntegrante  } } = props;

                                Paso 6: Guarda el Contenido con setAttributes

                                setAttributes será la función que se encargue de guardar lo que lee nuestra función en el evento del Componente en el atributo, es como el conector entre atributo y Componente, setAttributes se encuentra disponible en los props, por lo tanto primero hay que extraerlo, del código anterior agregamos setAttributes por fuera del destructuring de attributes:

                                const { attributes: { nombreIntegrante  } setAttributes } = props;

                                Nuestra función que actualmente esta escrita asi:

                                   const onChangeNombre = (nuevoNombre) => {
                                        console.log(nuevoNombre)
                                   }

                                Deberá quedar así:

                                    const onChangeNombre = nuevoNombre => {
                                        setAttributes({ nombreIntegrante: nuevoNombre})
                                    }

                                También es buena idea que el atributo que hemos extraido anteriormente sea pasado como value del componente:

                                <RichText
                                        placeholder="Agrega el nombre del Integrante"
                                        onChange={onChangeNombre}
                                        value={nombreIntegrante}
                                />

                                Paso 7: Trabajar con save()

                                save() será similar a edit() en muchas cosas, pero en lugar de permitirle al usuario editar el contenido, va a mostrarlo, tenemos que extraer los props y también utilizar el componente aunque con una sintaxis diferente:

                                    save: (props) => {
                                
                                        // Extraer Contenido de Props
                                        const { attributes: { nombreIntegrante } } = props;
                                
                                        return (
                                           <p className="nombre">
                                                 <RichText.Content value={nombreIntegrante} />
                                           </p>
                                        )
                                    }

                                A diferencia del RichText de edit, en el save() mostraremos el contenido guardado en ese atributo, por lo tanto no requerimos un evento, si no más bien mostrar el contenido con .Content

                                De esta forma podremos Guardar cambios, abrir Gutenberg y probar nuestro Componente.

                                Código completo hasta aquí

                                
                                    import {registerBlockType } from '@wordpress/blocks';
                                    import { PlainText, RichText } from '@wordpress/editor';
                                
                                    registerBlockType('wcgdl/equipo', {
                                        title: 'Integrante Equipo',
                                        icon: 'admin-users',
                                        category: 'layout', // common, formatting, layout, widgets, embed
                                        attributes: {
                                            nombreIntegrante: {
                                                type: 'string', 
                                                source: 'html', 
                                                selector : '.nombre'
                                            }
                                        },
                                        edit: (props) => {
                                            // Extraer Contenido de Props
                                            const { attributes: { nombreIntegrante }, setAttributes } = props;
                                
                                            // Funciones para leer los contenidos de nuestros componentes
                                            const onChangeNombre = nuevoNombre => {
                                                setAttributes({ nombreIntegrante: nuevoNombre });
                                            }
                                
                                            return (
                                                    <p className="nombre">
                                                        <RichText
                                                            placeholder="Nombre Integrante"
                                                            onChange={ onChangeNombre }
                                                            value={nombreIntegrante}
                                                        />
                                                    </p>
                                            )
                                        },
                                        save: (props) => {
                                
                                            // Extraer Contenido de Props
                                            const { attributes: { nombreIntegrante } } = props;
                                
                                            return (
                                                    <p className="nombre"><RichText.Content value={nombreIntegrante} /></p>
                                            )
                                        }
                                    });

                                Los pasos vistos en este Bloque se repiten a lo largo de la mayoria de los bloques, para no hacer una entrada más larga he decidido crear un repositorio que puedes ver y estudiar, si tienes alguna duda puedes hacermela saber por Twitter en @JuanDevWP

                                Enlace al repositorio

                                Continua tu aprendizaje Otras Entradas en Nuestro Blog...