frontend

Emulsify Drupal | Generando tema base

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     IMPORTANTE: Emulsify nos permite crear un BASE THEME a partir de Emulsify NO un Subtheme     

     Si eres de l@s que estás interesad@ en aprender a implementar, las utilizar tendencias en maquetación y diseño web, este es uno de los principales módulos que deberías considerar conocer, ya que te ayudará, en caso de que quieras darle un Giro de 360º a tus proyectos en Drupal, utilizando los componentes y el conocido como Diseño Atómico. Si quieres aprender más sobre esta tendencia revolucionaria, tienes el curso Introducción a Pattern Lab y Drupal 9 usando Emulsify.

     Emulsify Drupal, según su página oficial, "es una herramienta de código abierto para crear sistemas de diseño con componentes reutilizables y pautas claras para los equipos. Emulsify ayuda a las organizaciones a escalar su diseño al tiempo que reduce los costos, agiliza los flujos de trabajo y mejora la accesibilidad".

     A diferencia de otros themes contribuidos de Drupal, su instalación supone varias diferencias con respecto al resto. Su propósito fundamental, es ofrecernos todo lo que vayamos a necesitar para crear un Base Theme para Drupal, utilizando componentes. 

     Por esta razón, he creado esta guía paso a paso, de la instalación del módulo, desde su Página oficial 

     Prerrequisitos:

   Instalación del módulo Emulsify Drupal para Drupal 9

       Ya que desde la página de Drupal han anunciado hace tiempo, que el final del soporte tanto para Druapl 7 como para Drupal 8, terminará previsiblemente, a finales de este mismo año 2021, he decidido enfocarme en la instalación para Drupal 9, pero puedes seguir la guía con los cambios para otras versiones que están en la misma página.

     Paso 1 - Descarga del módulo usando composer

        A estas alturas, ya debes estar totalmente familiarizado con la instalación de módulos y themes en Drupal, utilizando el gestor de paquetes Composer, que nos facilitará enormemente las tareas de descarga o actualización de nuestros proyetos.

        Así que, nos colocaremos en la carpeta raíz del proyecto y en este caso, el comando a utilizar será el siguiente:

composer require emulsify-ds/emulsify-drupal

     Paso 2 - Preparación para generar el Tema Base

       Aquí es donde comienzan las diferncias, con respecto a otras instalaciones, como por ejemplo la del módulo Bootstrap, en este caso, al descargar el módulo se ha creado la carpeta contrib, dentro de la carpeta themes y dentro podremos ver todos los archivos relacionados con Emulsify, a continuación, nos moveremos hacia dicha carpeta, para poder generar un base theme que heredará todas las características y funcionalidades necesarias. O sea, que escribiremos en consola lo siguiente para movernos hasta la carpeta del theme padre:

cd web/themes/contrib/emulsify-drupal

   Paso 3 - Generar el Tema base

     Una vez colocados dentro de la carpeta del Theme padre, podremos ejecutar el siguiente código, para que se autogeneren todos los archivos relacionados con nuestro nuevo Tema base o personalizado:

php emulsify.php "THEME NAME"

    Si quieres conocer alguna otras opciones puedes ejecutar también el comando:

php emulsify.php -h

   Paso 4 - Descargar las dependencias del Base Theme

     Como he mencionado al principio, esta instalación rompe con lo que estábamos acostumbrados, esto significa, que tendremos que colocarnos dentro de la carpeta de nuestro nuevo_base_theme, que acabamos de generar, para poder comenzar con la descarga del resto de dependencias que hace tan pontente este tipo de instalación:

cd ../../custom/base_theme_name/

    Paso 5 - Instalación de dependencias para el Base Theme

     Este proceso suele tardar algo más de lo habitual, ya que tendrá que descargar un considerable número de archivos, destinados a facilitarnos la vida de aquí en adelante, por lo que no deberías inmpacientarnos. En mi caso en particular, tuve que abrir una segunda pestaña en mi consola, para asegurarme de que no se había quedado bloqueada la descarga, podemos usar cualquiera de las siguientes opciones:

yarn
npm install

 

Emulsify Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Paso 6 Construcción del Tema base

     Ya que tenemos descargardo, todo lo que vamos a necesitar para comenzar con nuestra implementación, nos toca construir la estructura, antes de poder utilizarlos en nuestro proyecto, también tenemos dos opciones a elegir:

yarn build
npm run build

 

Emulsify Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Paso 7 - Habilitar el base theme y sus dependencias

     Como ya tenemos todo a punto y listo para comenzar, nos toca activar el theme y sus dependencias, para ello utilizaremos la herramienta Drush, además tendremos que movernos a la carpeta principal para poder ejecutar el comando, fíjate que en lugar de utlizar en se emplea then, que es el comando correcto a partir de las versiones de drush =>9:

drush then base_theme_name -y && drush en components emulsify_twig -y

   Paso 8 - Activación del Tema Base

     Ahora sí, ya podemos activar nuestro theme para comenzar a soltar nuestra imaginación y creatividad, para ello, volveremos a utlizar la herramienta Drush:

drush config-set system.theme default base_theme_name -y

 

Emulsify Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

  Comprobación

    Si nos vamos a la página principal de nuestro proyecto, ahora podremos ver el cambio en la estructura y diseño para comenzar con esta nueva aventura...

Emulsify Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Arrancando la Guía de Estilos

     Si todo funciona correctamente, podremos arrancar nuestra guía de estilos, para comenzar a trabajar con el diseño, en paralelo con el desarrollo de nuesro proyecto Drupal, ejecutando el siguiente comando desde dentro de la carpeta de nuestro tema personalizado

npm run develop

Patternlab en Drupal | Metología BEM

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

       Uno de los cambios más significativos, al utilizar Emulsify y Pattern Lab en nuestros desarrollos, con respecto todo lo conocido hasta ahora, en cualquier proyecto de Drupal, es la implementación de la Metodología BEM, que afecta a todas las plantillas y componentes que vayamos creando a medida que generamos nuestra estructura.

     El objetivo principal de esta metodología, es simplificar al máximo, tanto la estructura de cada componente, como la gestión de sus clases y estilos, dentro de nuestros archivos css, facilitando de esta forma, el mantenimiento y comprensión de todas las posibles variantes o transformaciones de color, tamaño, dimensiones, etc., sobre cualquiera de los elementos de nuestro proyecto. 

     En la siguiente imagen, a pesar de que se trata de un proyecto Drupal 9, con un diseño a medida, creado a partir de un Subtheme personalizado con Bootstrap Barrio, puedes apreciar la intrincada estructura de <DIV></DIV>, que se ha generado, para que poder llegar hasta el elemento Botón.

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

   ¿Qué cambios implica la metodología BEM?

      El concepto principal es simplificar cualquier estructura en tres partes fundamentalmente, que son el Bloque, el Elemento y los Modificadores. Esto permitirá dividir todo en componentes más fáciles de reutilizar y mantener.

     La metodología BEM, propone la siguiente forma para nombrar nuestros componentes:

     class="nombrebloque": Para identificar el elemento padre o div principal.

     class="nombrebloque--elemento": Se añaden dos guiones bajos para el nombre del elemento, es decir, aquello que esté contenido dentro del bloque

     class="nombrebloque--elemento-modificador": Esta nueva clase, permitirá introducir la variaciones, por ejemplo, de color, tamaño, etc, para un elemento que se comparte dentro de varios componentes. 

     En la siguiente imagen, sacada desde su página oficial, nos explican una propuesta de implementacíon, en el caso de configurar un componente ATOM, del tipo botón. El nombre del Bloque, en este caso sería la clase button, que cómo puedes ver está presente al pricipio, en los tres elemementos.

     El Elemento, sería la clase button--state, que hace a la posibilidad de añadir una característica específica, a medida que vayamos utilizando dicho componente y por último está el Modificador de esta clase, que añade un dichas variaciones al estado del botón, button--state-danger. Presta atención a la nomemclatura en cada uno de los casos, para que tengas claro, a qué se refiere cada uno de ellos.    

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Si quieres conocer más sobre la Metodología BEM, visita su Página Oficial.

   ¿Cómo aplicar BEM con Emulsify en Drupal 9?

       En el caso de Drupal, al implentar Emulsify, en algunos casos, los guiones medios son sustituidos por guiones bajos, y como utilizaremos SASS, ya que es compatible con Emulsify, podremos aplicar estilos de manera muy simplificada.

       Ya que tenemos instalado y arrancado nuestra guía de estilos Storybook, que explicamos en el capítulo Emulsify Drupal, podremos echar un vistazo al componente BOTON, dentro de la carpeta de componentes ATOMS:

 

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Ahora, vamos a utilizar nuestro IDE para explorar y explicar un poco, la implementación de BEM que nos propone Emulsify, en este proyecto desarrollado con Drupal 9, para ello navegaremos hasta la carpeta dentro de /themes/custom/MISUBTHEME/components/01-atoms/buttons y a continuación abriremos el archivo button.twig, donde veremos lo siguiente:

{#
/**
 * Available variables:
 * - button_content - the content of the button (typically text)
 *
 * Available blocks:
 * - button_content - used to replace the content of the button with something other than text
 *   for example: to insert an icon
 */
#}

{% set button_base_class = button_base_class|default('button') %}

{% set additional_attributes = {
  class: bem(button_base_class, button_modifiers, button_blockname),
} %}

<button {{ add_attributes(additional_attributes) }}>
  {% block button_content %}
    {{ button_content }}
  {% endblock %}
</button>

 

   Explicación:

{% set button_base_class = button_base_class|default('button') %}

     Lo primero que podemos observar es la declaración una variable, cuyo valor es el nombre del Bloque, en este caso será la clase button_base_class, una vez importemos este bloque dentro de nuestras plantillas de Drupal, podremos asignarle un valor dinámico, dependiendo de las necesidades para nuestro proyecto, la forma de realizar este paso lo explicaremos en detalle más adelante.

{% set additional_attributes = { 
  class: bem(button_base_class, button_modifiers, button_blockname),
} %}

     En esta línea, en el caso específico del botón, se están definiendo las clases que generarán, de forma dinámica, los nombres equivalentes, para el Bloque, Elemento y el Modificador, respectivamente, concatenando la clase button_base_class y añadiendo los guiones correspondientes; esto quiere decir, que si explorarmos el código en el navegador, verás que se han generado, el nombre del Bloque, y luego, con dos guiones, en el caso del Elemento y uno el el caso del Modificador.

     Quizás el botón, al ser una de las estructuras más simples, no te permite ver todo lo que genera Drupal automáticamente, pero si exploras la molécula, llamada Main, encargada de generar la plantilla de ejemplo para el menú principal, en el navegardor, verás un claro ejemplo de todo. donde la clase toggle-expand es el nombre del bloque, toggle-expand__open, es el nombre del elemento y si quisiéramos aplicar un cambio de color, toggle-expand__open_red

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

  Añadiendo las clases personalizadas en nuestros componentes en Drupal

    Una vez hayamos declarado las variables, podremos añadir valores personalizados, dinámicamente en nuestros componentes, mediante la funcionalidad de Twig para agregar atributos.

    Si te fijas en el nombre que está entre los paréntesis, podrás comprobar que es el mismo que se declara al principio, en la variable, por lo que podrás pasar como parámetros los nuevos valores, para cada uno de estos "atributos adicionales" y adaptarlos a las necesidades específicas del proyecto.

<button {{ add_attributes(additional_attributes) }}>

   En la siguiente imagen, podrás ver cómo se puede alterar uno de los valores, declarados en un componente, que en este caso está dentro de otro, llamado CARD y cuál es el resultado final, al explorar el código generado en el navegador:

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

Patternlab en Drupal | Prerrequisitos

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     IMPORTANTE: Emulsify nos permite crear un THEME a partir de Emulsify NO un Subtheme     

     Desde la aparición de Pattern Lab y su adaptación para poder implementarlo con Drupal 8, se han ido realizando un gran número de cambios, tanto en la estructura de todos los módulos relacionados, especialmente Emulsify Drupal, como en la manera de activar y utilizar comandos, librerías y el código dentro de las plantillas, que permiten conectar nuestro diseño con el proyecto.

     En este capítulo trataré de abarcar todos los prerrequisitos, que necesitarás conocer, antes de comenzar a trabajar de lleno con Pattern Lab y Emulsify en Drupal 9. Y que tengas la información más actual relacionada, ya que en el momento en que escribo este artículo, si visitas la Página Oficial de Emulsify, y ves sus videos, te darás cuenta, de que no están actualizados desde su lanzamiento en 2016, a pesar de que casi todo ha sido modificado para adaptarlo a Drupal 9 y posteriores.

   Novedades y Prerrequisitos en Pattern Lab para Drupal 9

     El módulo Pattern Lab no es compatible para Drupal 9

        La primera noticia es bastante impactante, ya que los primeros cuatro videos, que están publicados en la Página Oficial de Emulsify, en el apartado de Videos y tutoriales, nos muestran las pantallas y algunos comandos y ejemplos, implementando el módulo Pattern Lab, compatible con Drupal 8, pero que ha sido totalmente sustituido por el nuevo módulo Emulsify Drupal, cuya instalación ya tienes disponible dentro de este curso y que nos permite generar un Theme basado en Emulsify, no un Subtheme, como estábamos acostumbrados.

     Las Páginas de referencia para Twig ya no son de Sensiolbas sino de Symfony

        Esto también es bastante importante, ya que lo enlaces que aparecen en casi todos los videos relacionados con Pattern Lab y Drupal, nos llevan a los enlaces de la documentación de la empresa Sensiolabs, que ahora ya están bajo el dominio de Symfony. Por lo tanto, si quieres aprender sobre el uso de las funcionalidades como include, embed o extends de Twig deberías visitarte la Página Oficial de Synfony para Twigs

     La compatibilidad con Drush ha cambiado

        Como todo evoluciona, también es el turno de actualizarnos, con respecto a los comandos drush de los videos, relacionados con la instalación y ejecución de Emulsify Drupal, el cambio más importante es que el comando yarn start o npm start, que nos permitía arrancar nuestra Guía de estilos, ha sido cambiado por el siguiente comando:

npm run storybook
yarn develop
npm run develop

 

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Nuevos módulos para trabajar con las plantillas Twig y Emulsify

     Otro de los cambios más importantes en esta evolución, sobre la implementación de Pattern Lab en Drupal 9, es la creación de varios módulos, que nos facilitarán la compatibilidad entre las plantillas y el código, y que al principio teníamos que instalar desde el repositorio github de four kichen, a continuación te añado el enlace a las páginas de cada uno de ellos:

  • Components! El módulo Componentes facilita que un tema organice sus componentes. Permite que los temas (y módulos) registren los espacios de nombres de Twig y proporciona algunas funciones y filtros adicionales de Twig para usar en las plantillas de Drupal.

  • Twig Attributes Twig Attributes permite a los desarrolladores establecer atributos HTML (como clases o una identificación) en una plantilla Twig principal a elementos en una plantilla secundaria, eliminando la necesidad de crear una anulación de plantilla o implementar un enlace de preproceso solo para agregar un atributo.

  • Emulsify Twig Este módulo proporciona dos extensiones Twig utilizadas en el Emulsify Design System.

  • Twig Field Value Twig Field Value permite a los usuarios de Drupal 8 obtener datos parciales de matrices de renderizado de campo.

  • Twig Typography Este módulo proporciona un filtro Twig que integra la biblioteca PHP Typography y la aplica a cadenas.

  • Twig Render This Este módulo le permite representar campos y entidades en sus plantillas Twig.

  • More Global Variables Este es un pequeño módulo que brinda a los usuarios algunas variables globales que luego pueden imprimirse en cualquier plantilla de ramitas.

  • Twig Tweak Twig Tweak es un pequeño módulo que proporciona una extensión Twig con algunas funciones y filtros útiles que pueden mejorar la experiencia de desarrollo.

  • BEM Un tema base de Drupal obstinado que proporciona clases de estilo BEM en todas partes.

  • Devel Que nos servirá para depurar nombres de las variables

  • Devel Kint Extras Los complementos de Kint responsables de mostrar los métodos disponibles de los objetos y las propiedades de las clases estáticas se eliminaron del módulo Devel para Drupal 8 desde la versión 3.0. Este módulo vuelve a agregar esas características como un módulo externo.

  • kint-php/kint: Añade funcionalidades a Devel y se instala con composer "composer require kint-php/kint"

 

     Requisitos de instalación implementación Guia o Storybook en Drupal 9

        Como ya sabrás, esta clase de implementación está pensada para que los diseñadores y desarrolladores puedan trabajar en paralelo, por lo tanto, una vez esté funcionando el Drupal9 y se haya generado el Theme basdo en Emulsify, podremos acceder a la guía de diseño con el comando mencionado al principio e instalar y configurar algunas herramientas para comenzar a diseñar.

      El Preprocesador de CSS Sass

      Node Version Manager

   Errores con Twig

     En toda implementación existe la posibilidad de encontrarnos con algunos errores, uno de ellos es el uso del include en las plantillas Twig. Te dejo el enlace al issue reportado en la Página de Drupal https://www.drupal.org/project/drupal/issues/2817553

Atomic Desing | ¿Qué es el Diseño Atómico?

Video de Youtube
URL de Video remoto
Texto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     En el desarrollo de páginas web, existen múltiples escenarios y posibilidades, que nos permiten especializarnos en determinadas herramientas o procedimientos, de acuerdo con nuestras destrezas y/o formación. De ahí que, es cada vez más habitual, encontrar algunos profesionales, que aunque inicialmente se habían formado o especializado en el Diseño Gráfico, hayan decidido experimentar o reinventarse, dedicándose a la maquetación web o Diseño Frontend, como se conoce hoy en día.

     Uno de los problemas más frecuentes, al inicio de esta nueva experiencia, es la rapidez con la que puede cambiar, todo lo relacionado con la apariencia y funcionalidades de la web, ya que intervienen factores como la experiencia de usuiaro (UX), la velocidad de respuesta de la web al conectarse al servidor, o la posilidad de adaptarse a múltiples dispositivos.

     De ahí que resulte casi imposible, mantenerse al día en una herramienta específica o procedimiento, pensado para facilitar o mejorar el diseño Frontend, ya que constantemente se efectúan cambios y mejoras, que nos pueden crear una sensación de frustración, a pesar de que hayan pasado a penas, un par de años desde que aprendimos, por ejemplo, un framework como angular, react, vue.js, next, nuxt o cualquier otro.

     Por suerte, hace ya varios años, a un señor de nombre Brad Frost, se le ocurrió una idea revolucionaria, que todavía se aplica a día de hoy, y que nos facilitará mantener el ritmo de evolución, acorde con cualquier herramienta o procedimiento relacionado con la maquetación o Frontend. Se trata de la metodología llamada Diseño Atómico o Atomic Design, cuyo propósito fundamental es, según sus propias palabras:

"Atomic Design detalla todo lo que se necesita para crear y mantener sistemas de diseño sólidos, lo que le permite implementar interfaces de usuario más consistentes y de mayor calidad más rápido que nunca. " 

     ¿Qué es el Diseño Atómico?

        En resumen, el objetivo de esta metodología es establecer una jerarquía, que nos permita analizar y dividir,  nuestros proyectos web, en varios elementos y/o estructuras, comenzando por el más sencillo, al que llamaremos átomo, ejemplo un icono, hasta ir al más complejo que sería la unión de todos en un Sistema, ejemplo una página completa.

       La siguiente imagen muestra de forma más gráfica el conjunto de fases, o elementos que forman esta metodología:

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Nuestro proyecto web es un proyecto de piezas Lego

        Todos conocemos el famoso juego para niños, conocido como Lego, formado por varias piezas que permiten crear, prácticamente toda clase de estructuras complejas, a partir de la unión de éstas. Si comparamos el juego con un proyecto web en este caso, podríamos entender, más fácilmente, de qué se trata esta metodología y lo mucho que puede aportarnos ante cualquier reto de desarrollo.

        A continuación te cuento en qué consiste cada una de las "Piezas" con las que deberíamos trabajar a partir de ahora, para sacar el mayor provecho de este nuevo enfoque. 

        Recuerda que esto es sólo una guía, para simplificar la categorización de tu proyecto, no obstante, puedes añadir tanto como necesites de acuerdo a tus propias necesidades de análisis y estructura.

      Atomo

         Son aquellos elementos más pequeños o con una jerarquía menor. Un átomo es aquel elemento que por sí mismo no significa nada y necesitará ser acompañado por otros átomos para tener sentido. Un ejemplo de un átomo podría ser un título, un texto, un área, un icono, una línea. El átomo debe ser nombrado, definido y acotado con márgenes para conocer cómo se comporta al ser juntado con otros átomos y no crear una lucha entre ellos.

     Moléculas

        Cuando dos o más átomos se juntan, crean moléculas. Las moléculas es el mínimo elemento que empieza a poder ser usado de manera aislada. Una molécula ofrece información suficiente como para guiar una acción dentro de la interfaz. Se debe evitar sobrecargar la molécula de átomos. Éstas son secciones en nuestra interfaz una cabecera, un footer, un post, etcétera. Como ocurre con los átomos, la molécula debe ser definida y acotada de nuevo para poder saber como se comporta en convivencia con sus semejantes.

    Organismos

        Formados por dos o mas moléculas, los organismos forman una sección o parte de nuestro producto. Los organismos ofrecen una experiencia completa al usuario. En productos digitales sencillos como una web, organismos serían todas aquellas páginas (homecontactabout, etc.) que la forman.

     Sistema

        El sistema, por lo tanto, sería el todo. La web, aplicación, software o cualquier producto digital que estemos construyendo.

     Aplicado a un entorno web, en la siguiente imagen podrás ver la diferencia entre átomo y molécula, en el caso de un carrusel de imágenes, que a su vez, forma parte de un organismo mayor, que sería la página Home o principal del proyecto.

Curso Pattern Lab Drupal 9 | www.drupaladicto.com - Consultor especializado en drupal y symfony

     El diseño atómico es una metodología compuesta por cinco etapas distintas que trabajan juntas para crear sistemas de diseño de interfaces de una manera más deliberada y jerárquica. Las cinco etapas del diseño atómico son:

  1. Átomos
  2. Moléculas
  3. Organismos
  4. Plantillas
  5. Paginas

     El diseño atómico no es un proceso lineal , sino un modelo mental que nos ayuda a pensar en nuestras interfaces de usuario como un todo cohesivo y una colección de partes al mismo tiempo . Cada una de las cinco etapas juega un papel clave en la jerarquía de nuestros sistemas de diseño de interfaces. Vamos a sumergirnos en cada etapa con un poco más de detalle.

     Si a partir de ahora, en cada nuevo proyecto o renovación de algún proyecto existene, aplicamos y manteneos este tipo de organización de elementos en nuestro trabajo de diseño, ahorraremos esfuerzo y malentendidos entre nuestro diseño y el departamento de programación. Además, facilitará su trabajo, haciendo que puedan visualizar y traducir el diseño a código de una manera más directa.

     Si quieres aprende más sobre el Diseño Atómico visita la Web Oficial de su creador

 

PatterLab en Drupal | Introducción

Video de Youtube
URL de Video remoto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     En este Curso Introducción a Drupal 9 con Pattern Lab, quiero compartir contigo LA REVOLUCIONARIA MANERA DE TRABAJAR EL DISEÑO CON DRUPAL, se trata de la implementación del Diseño Atómico, que te permitirá crear una guía de estilos, que posteriormente podrá ser aplicada al proyecto en Drupal, sin la necesidad de que tengas conocimientos previos de Drupal, además de minimizar de forma exponencial el tiempo de carga de tu Drupal, facilitando el mantenimiento mediante el uso de componentes y muchas otras opciones que deberías conocer.

Gatsby con Drupal | Trabajando con imágenes desde Drupal 9

Video de Youtube
URL de Video remoto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     Tratar con imágenes de Drupal

        Uno de los beneficios de usar Gatsby es su soporte integrado para la optimización de imágenes. Gatsby facilita el uso de técnicas de mejores prácticas como el desenfoque o el rastreo de svg para garantizar que las imágenes no ralenticen la carga de la página. Gatsby también proporciona utilidades que permiten a los desarrolladores solicitar una imagen en un tamaño específico o un conjunto de tamaños.

    Como funciona todo esto

        En un nivel alto, cuando Gatsby obtiene datos de Drupal, extrae los archivos de imagen sin procesar adjuntos a cualquier campo de imagen. Los archivos se almacenan localmente y la información se agrega a GraphQL. Los complementos gatsby-plugin-sharp y gatsby-plugin-transform trabajan juntos para exponer varias funciones de procesamiento de imágenes en GraphQL. Cuando consulta GraphQL por una imagen, puede usar estas funciones para decir: "Use esta imagen, pero devuelva todas las variantes de imagen necesarias para técnicas avanzadas de carga de imágenes, como desenfoque o marcador de posición SVG con trazado". Finalmente, los datos devueltos se pueden pasar literalmente al componente Img de gatsby-image, que contiene la lógica requerida para mostrar las imágenes.

        Es una gran cantidad de lógica de visualización y manipulación de imágenes realmente compleja envuelta en un patrón reutilizable que requiere que haga muy poco trabajo adicional en su código para aumentar potencialmente drásticamente la velocidad.

     Instale los complementos necesarios

        Tradicionalmente, los filtros que se encargan del tratamiento de las imágenes, para trabajar con Drupal como Backend en nuestro caso, deberían ser gatsby-imagegatsby-plugin-sharp y gatsby-transformer-sharp; su funcionalidad es codificar nuestras imágenes dinámicas, extraídas desde drupal, a través de consultas con Graphql y mostrarlas, dentro de nuestra aplicación, de manera optimizada para no interferir en el tiempo de carga de nuestra web, además de añadir otras opciones disponibles como el efecto Blur, mientras se carga la imagen y convertirlas en Responsives, además de cargar diferentes tamaños, dependiendo del dispositivo desde el cual accedamos a nuestra aplicación.

        Al momento de escribir este artículo, algunas cosas han cambiado, con respecto a lo que todavía se muestra en la documentación oficial de Gatsby, una de ellas es el hecho de que, si abrimos el archivo de configuración de Gatsby, encontraremos que ya están añadidos los plugins necesarios, con la novedad de que el primero de ellso, ahora se llama "gatsby-plugin-image" en lugar de "gatsby-images" y que además, se han realizado varios cambios y mejoras que implican tomarnos un tiempo para conocerlo.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Cambios a tomar en cuenta

        Una de las razones relacionadas con este cambio, es el cambio en Drupal 9, del campo field_image por el campo field_media_image, que como comenté en artículos anteriores, permite añadir otros formatos además de imágenes, como videos o audios. 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

        Este nuevo campo, pasa a ser referenciado, al igual que las taxonomías y por esta razón, al construir la consulta en Graphql, debemos tomar en cuenta que para acceder hasta la URL que utilizaremos en nuestra aplicacion, emplearemos varios niveles de anidación, que no eran necesarios con el antiguo field_image.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

        Otra de las aclaraciones, es que aunque en Graphql realicemos una consulta hasta llegar a la url de la imagen, cuando nuestro objetivo sea mostar dicha imagen dentro de nuestra aplicación, tendremos que sustituir algunas partes de la consulta, para emplear los recurso de Gatsby.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
...GatsbyImageSharpFluid

        Los tres puntos que vemos en la anterior imagen, son parte de la configuración interna de Gatsby, que compacta toda la información que hayamos seleccionado en el entorno gráfico Graphql, relacionada con nuestra imagen ej.: (src, srcset, url) y se la pasa como parámetros al plugin, para que este la complile de la manera adecuada. 

     Uso de los componentes de la imagen de Gatsby

        El complemento Gatsby Image incluye dos componentes de imagen: uno para imágenes estáticas y otro para imágenes dinámicas. La forma más sencilla de decidir cuál necesita es preguntarse: "¿Esta imagen será la misma cada vez que se utilice el componente o la plantilla?". Si siempre será el mismo, utilice StaticImage. Si cambia, ya sea a través de datos provenientes de un CMS o de diferentes valores pasados a un componente cada vez que lo usa, entonces es una imagen dinámica y debe usar el componente GatsbyImage.

     Como en nuestro caso, las imágenes que queremos utilizar serán dinámicas, porque vendrán desde nuestro Drupal 9, tendremos que optar por el componente para imágenes dinámicas.

    Actualice sus consultas GraphQL

        A continuación, actualice sus consultas GraphQL para hacer uso de las funciones y fragmentos proporcionados por los complementos gatsby-plugin-sharp y gatsby-transform-sharp.

        En src/templates/recipe.js modifique el código para que se vea así:

importar React desde 'react';
importar {graphql} de 'gatsby';
importar casco desde 'react-helmet';
importar {makeStyles} desde "@mui/styles";
importar papel desde '@mui/material/Paper';
importar { GatsbyImage, getImage } desde "gatsby-plugin-image"
importar diseño desde '../components/layout';
importar Receta desde '../components/Recipe/Recipe';


const usarEstilos = hacerEstilos({
    raíz: {
        espaciado: [3, 2],
        relleno: '30px',
    },
});


const RecipeTemplate = (accesorios) => {
    const clases = useStyles();
    const { nodoRecipe: receta } = props.data;
    const image = getImage(receta.relaciones.imagen.relaciones.field_media_image.localFile.childImageSharp)
    consola.log(receta)
    devolver (
        <Diseño>
            <Casco
                title={`Umami - ${receta.título}`}
                meta={[
                    {nombre: 'descripción', contenido: receta.título},
                ]}
            />
            <Nombre de clase de papel={clases.raíz}>
                <GatsbyImage image={imagen} alt={receta.título} />
                <Receta
                    {...receta}
                    categoría={receta.relaciones.categoría[0].nombre}
                    tags={receta.relaciones.tags}
                    instrucciones={receta.instrucciones.procesado}
                    resumen={receta.resumen.procesado}
                />
            </Papel>
        </Diseño>
    )
};

exportar plantilla de receta predeterminada;

// La variable $drupal_id aquí se obtiene del objeto "contexto" pasado a
// la API createPage() en gatsby-node.js.
//
// Tenga en cuenta también el uso de alias de nombre de campo en la consulta. esto se hace para
// ayuda a normalizar la forma de los datos de la receta.
exportar consulta const = graphql`
  consulta RecipeTemplate($drupal_id: String!) {
    nodoRecipe(drupal_id: {eq: $drupal_id}) {
      Drupal_id,
      título,
      tiempo_cocina: campo_tiempo_cocina,
      dificultad: campo_dificultad,
      ingredientes: campo_ingredientes,
      tiempo_de_preparación: tiempo_de_preparación_del_campo,
      numero_de_raciones: campo_numero_de_raciones,
      instrucciones: field_recipe_instruction {
        procesada,
      },
      resumen: campo_resumen {
        procesada,
      },
      relaciones {
        categoría: campo_receta_categoría {
          nombre,
        }
        etiquetas: campo_etiquetas {
          nombre,
        }
        imagen: campo_media_imagen {
          relaciones {
            imagen_de_medios_de_campo {
              archivo local {
                childImageSharp {
                  gatsbyImageData(
                    ancho: 1250
                    marcador de posición: BORROSO
                    formats: [AUTO, WEBP, AVIF]
                  )
                }
              }
            }
          }
        }
      }
    }
  }
`;

     Explicación:

          1.- En la parte superior, hemos importado el nuevo Plugin 

importar { GatsbyImage, getImage } desde "gatsby-plugin-image"

         2.- Hemos creado la constante image, con la ruta indicada en la query que hemos actualizado, para añadir el campo de media de Drupal 9.

const image = getImage(receta.relaciones.imagen.relaciones.field_media_image.localFile.childImageSharp)

        3.- Hemos añadido el nuevo componente relacionado con el tratamiento de la imagen

<GatsbyImage image={imagen} alt={receta.título} />

             El resultado final es el siguiente:

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

        Felicidades!!!

            Ahora ya tienes todo el conocimiento necesario, para poder comenzar a desarrollar proyectos web, con Drupal 9 Headless y Gatsby, conjuntamente con las librerías de Material UI.

Gatsby con Drupal | Mostrando datos desde Drupal (2da Parte)

Video de Youtube
URL de Video remoto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

        Llegados a este punto, ya nos queda muy poco para completar un listado de artículos en nuestra página, aplicando un diseño atractivo y funcional, gracias a la implementación de Material UI, en nuestra aplicación de Gatsby y, además, gracias al plugin gatsby-source-drupal,  obtenemos toda la información mostrada, desde un Drupal 9, que podremos administrar en paralelo, para ampliarlo con tipos de contenido, permisos de usuarios, taxonomías, entre otras.

        En el camino hasta este momento, hemos conocido muchos de los principios, técnicas y herramientas que nos permitirán desarrollar grandes proyectos, uniendo Gatsby en la parte de frontend y Drupal 9, encargándose del backend; por lo tanto, sólo es cuestion de invertir el suficiente tiempo y esfuerzo, para convertirnos en desarrolladores competitivos y actualizados, a diferencia de muchos otros que se mantienen dentro de su zona de confort, sin continuar evolucionando.

      Crear listas de contenido en Gatsby

         Probablemente deba proporcionar a los usuarios listas para que puedan ver qué contenido está disponible en su aplicación. Esas listas deberán mantenerse actualizadas a medida que se agregue, edite o elimine el contenido. Esto requiere consultar GraphQL para obtener los títulos y las rutas de las páginas a las que desea vincular, y luego usar el componente Enlace proporcionado por gatsby-link para crear enlaces en los que se puede hacer clic a esas páginas en el momento de la compilación.

     Page query vs. Static query  

         Hay dos formas diferentes de hacer que Gatsby ejecute una consulta GraphQL durante el tiempo de compilación. Cuál use depende principalmente del contexto en el que está realizando la consulta.

      Page queries: Las consultas de página son variables especiales exportadas desde un archivo cuyo contenido es una consulta GraphQL envuelta con la función de etiqueta graphql proporcionada por Gatsby. Si esta variable existe, Gatsby buscará, ejecutará e inyectará automáticamente los resultados de la consulta en el componente predeterminado exportado desde el mismo archivo.

       Static queries: Las consultas estáticas se implementan a través del componente StaticQuery. Proporcionan una forma para que cualquier componente emita una consulta y recupere los datos que necesita. Esto ayuda a reducir la necesidad de pasar datos por la pila como accesorios y, en cambio, permite que los componentes que lo necesitan declaren exactamente qué datos necesitan.  

     Agregar una lista de recetas a la página principal

        Para agregar una lista de contenido a la página principal, o cualquier página generada a partir de un archivo en src/pages/ necesitamos:

  • Exportar una función etiquetada en graphql que contenga nuestra consulta
  • Actualizar el componente para usar los datos props.data. * De la consulta que Gatsby inyecta automáticamente para nosotros
  • Utilizar el componente Enlace para todos los enlaces internos

     Comenzaremos definiendo un nuevo componente RecipeCard que podemos usar para mostrar recetas en la página principal. No hay nada especial en este código; solo necesita existir para que podamos tener una buena forma de mostrar el contenido.

     Así que nos colocaremos en la carpeta correspondiente y crearemos el archivo, dentro de src/components/RecipeCard/RecipeCard.js y pegaremos el código dentro de él:

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
import React from 'react'
import PropTypes from 'prop-types';
import { Link } from 'gatsby'
import { makeStyles } from '@mui/styles';
import Button from '@mui/material/Button';
import { Card } from '@mui/material';
import { CardActions } from '@mui/material';
import { CardContent } from '@mui/material';
import Typography from '@mui/material/Typography';

const useStyles = makeStyles(theme => ({
    card: {
        maxWidth: 345,
        minHeight: 310,
    },
    bullet: {
        display: 'inline-block',
        margin: '0 2px',
        transform: 'scale(0.8)',
    },
    title: {
        marginBottom: 16,
        fontSize: 14,
    },
    pos: {
        marginBottom: 12,
    },
}));

const RecipeCard = (props) => {
    const classes = useStyles();
    const RecipeLink = props => <Link to={props.path} {...props}>Read more</Link>;

    return (
        <Card className={classes.card}>
            <CardContent>
                <Typography className={classes.title} color="textSecondary">
                    {props.category}
                </Typography>
                <Typography variant="h5" component="h2">
                    {props.title}
                </Typography>
                <Typography className={classes.pos} color="textSecondary" dangerouslySetInnerHTML={{ __html: props.summary }} />
            </CardContent>
            <CardActions>
                <Button size="small" path={props.path} component={RecipeLink}>Read more</Button>
            </CardActions>
        </Card>
    );
};

RecipeCard.propTypes = {
    classes: PropTypes.object.isRequired,
    title: PropTypes.string.isRequired,
    summary: PropTypes.string.isRequired,
    category: PropTypes.string.isRequired,
    path: PropTypes.string.isRequired,
};

export default RecipeCard;

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

      Lo que hemos hecho en este código es:

        Exportamos una nueva variable llamada consulta, usando la función de etiqueta graphql, con una consulta que obteniene detalles, sobre todas las recetas que queremos mostrar en la página principal. También se conoce como page query. Esto es recogido automáticamente por Gatsby y ejecutado. Los resultados de la consulta se inyectan en el componente IndexPage como props.data.allNodeRecipe.

         En el componente IndexPage recorremos los datos devueltos, utilizando props.data.allNodeRecipe.edges.map () y generamos una <RecipeCard /> para cada elemento.       

        Por lo tanto, cada vez que se crea el sitio con gatsby build, se actualiza el contenido de la página de inicio. Si se agregaron recetas adicionales a nuestro CMS, se introducirán en la base de datos GraphQL de Gatsby y luego se mostrarán.

     Crear un componente RecipeList

        Creemos también un nuevo componente RecipeList, en la ubicación src/components/RecipeList/RecipeList.js, que muestra una lista de enlaces a las 3 recetas agregadas más recientemente que podemos usar en cualquier lugar de nuestra aplicación, no solo al generar páginas. Por ejemplo, podríamos agregar una lista como esta al final de cada página de receta.

        Para ello, seguiremos los siguientes pasos:

  1. Crear un nuevo componente RecipeList
  2. Utilice el componente StaticQuery proporcionado por Gatsby para ejecutar nuestra consulta; esto sigue la técnica estándar de "render prop".
  3. Incluya el componente RecipeList en algún lugar de nuestro sitio para que se procese

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Copia y pega el siguiente código dentro del componente RecipeList.js:

import React from 'react';
import PropTypes from 'prop-types';
import { StaticQuery, Link, graphql } from "gatsby"

const RecipeListWrapper = () => (
    <StaticQuery
        query={graphql`
      query {
        allNodeRecipe(limit: 3) {
          edges {
            node {
              drupal_id,
              title,
              path {
                alias,
              }
            }
          }
        }
      }
    `}
        render={data => <RecipeList recipes={data.allNodeRecipe.edges} />}
    />
);

const RecipeList = ({recipes}) => (
    <ul>
        {
            recipes.map(({ node: recipe }) => (
                <li key={recipe.drupal_id}>
                    <Link to={recipe.path.alias}>
                        {recipe.title}
                    </Link>
                </li>
            ))
        }
    </ul>
);

RecipeList.propTypes = {
    recipes: PropTypes.arrayOf(
        PropTypes.shape({
            node: PropTypes.shape({
                drupal_id: PropTypes.string.isRequired,
                title: PropTypes.string.isRequired,
                path: PropTypes.shape({
                    alias: PropTypes.string.isRequired,
                }).isRequired,
            }).isRequired,
        }),
    ).isRequired,
};

export default RecipeListWrapper;

     Mostrar el listado

        Edite el componente Recipe, que creamos en el artículo anterior, y agreguegaremos el nuevo componente RecipeList, en la parte inferior para mostrar recetas adicionales, para que alguien las lea cuando complete la que está viendo.  

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Error de Cache

        Puede que algunas veces, veas un error de caché parecido al de la siguiente imagen, si esto te sucede, deten el proyecto con las teclas Ctrl + C, y luego borra el contenido de la carpeta .cache; a continuación vuelve a arrancar el proyecto con el comando develop

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

Gatsby con Drupal | Mostrando datos desde Drupal (1era Parte)

Video de Youtube
URL de Video remoto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

     A estas alturas ya podemos presumir de que conocemos, al menos lo básico, para montar y poner en funcionamiento, una aplicación desarrollada con Gatsby conectada a Drupal 9; pero con esto a penas, habremos avanzado el primer paso, ya que todavía nos faltará lo más importante que consistirá en mostrar dichos datos de forma dinámica, dentro de nuestro Gatsby utilizando como base de datos, nuestro Drupal.

     Ya hemos comprobado que si entramos en "http://gatsbymobile.lndo.site/_graphql", que es la url de nuestra instalación actual, explicada en el Capítulo Conectando Gatsby con Drupal 9,  accederemos al panel gráfico de GraphsQL y podremos comenzar a crear nuestras propias consultas, seleccionando los campos que nos hagan falta y a continuación, presionando el botón del Play, colocado en la parte superior, se mostrarán los contenidos relacionados en la pantalla de la derecha.

Gatsby con Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

        Si todo funcionó, deberías poder ejecutar consultas aquí que muestren los datos que Gatsby extrajo de Drupal. Ten en cuenta que Gatsby crea colecciones GraphQL, a partir del contenido de Drupal, siguiendo una convención de nomenclatura específica: allNode {CONTENT-TYPE}. El patrón es el texto "allNode", seguido del nombre de la máquina del tipo de contenido de Drupal.

     Puedes probar copiando el siguiente código y pegándolo en el apartado de Queries, a continuación presiona el botón Play y verás que el resultado será el listado de nodos, con su Título, Id y el campo Body, la fecha de creación del contenido y su url, todo desde Drupal.

query MiQuery {
  allNodeArticle {
    edges {
      node {
        id
        title
        body {
          processed
        }
        created
        path {
          alias
        }
      }
    }
  }
}

     El módulo gatsby-source-drupal permite realizar, diversas configuraciones como filtros, cargas rápidas, autenticación entre Drupal y Gatsby, así como otras muchas que puedes conocer visitando su Documentación de Gatsby

     UUID vs drupal_id vs drupal_internal__nid

        Cada nodo de Drupal en la base de datos GraphQL de Gatsby tiene 3 ID únicos diferentes que debe tener en cuenta:

  • uuid: Esto lo genera Gatsby al obtener contenido y es único internamente, pero no tiene ninguna relación con Drupal.
  • drupal_id: Este es un UUID generado por Drupal, es único tanto en Gatsby como en Drupal, y debe preferirse cuando necesite una forma única de hacer referencia al contenido de Drupal. Esto asegura que la ID que se usa dentro de Gatsby sea también la misma que la que usa Drupal y hace que sea más fácil razonar
  • drupal_internal__nid: Este es el node.nid de Drupal, en la mayoría de los casos puede hacer referencia a la entidad en Drupal a través del campo drupal_id, pero en los casos en que lo necesite, puede usarlo.

     Drupal entity reference fields

        En el modelo de datos de Drupal, las piezas de contenido (entidades) pueden declarar relaciones con otras piezas de contenido utilizando lo que se conoce como referencias de entidad. Cuando Gatsby obtiene datos de Drupal, estas referencias de entidad se migran a las "relationships" de GraphQL, por lo que no ve esos campos donde podría esperarlos en el esquema GraphQL. No se preocupe, todavía están ahí, solo necesita mirar en el campo "relationships".

        Un ejemplo de relaciones, podemos encotrarlo al intentar utilizar imágenes, ya que el campo "media" permite hacer referencia a diversos tipos de contenido, como video, audio e imágenes.

Gatsby con Drupal | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Añadir Material UI para modificar el aspecto de Gastby

        Para darle a nuestra aplicación algo de estilo, usaremos la popular biblioteca de Material UI component. Es un conjunto de componentes de React que implementan el lenguaje de diseño de la interfaz de usuario de Google Material.

     NOTA:
        Para evitar posibles errores, antes de instalar Material UI, asegúrate de actualizar tu versión de Gatsby Haz clic aqui

     Puedes comprobar la versión que de gatsby que tienes instalada, ejecutando el siguiente comando:

lando npm outdated

     En pantalla verás un resultado parecido a la siguiente imagen, con las versiones actuales y las que deberías actualizar:

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Y para actualizar a la versión más reciente, ejecutar el siguiente comando:

lando npm i gatsby@latest

     Instalar la biblioteca de componentes de Material UI

        Si estamos ejecutando Gatsby, antes de poder instalar, tendremos que detenerlo utilizando la combinación de teclas:

Ctrl + C

        La forma más rápida de comenzar a usar Material UI con Gatsby es a través del gatsby-plugin-material-ui plugin. Para ello lo primero que tendremo que hacer es descargarlo utilizando el siguiente comando, al igual que hicimos con el gatsby-drupal-source, ya que estamos trabajando con Lando:

lando npm install --save gatsby-plugin-material-ui @mui/material @emotion/react @emotion/styled @mui/styles

     Y a continuación, abriremos el archivo de configuración de Gastsby y colocaremos el siguiente código, en el apartado de plugins, para que podamos acceder a sus opciones.

`gatsby-plugin-material-ui`,

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

    Ahora podremos volver a ponerlo en funcionamiento con el comando:

lando gatsby develop --host 0.0.0.0

     Actualizando el Layout Component

        Actualice el componente Layout predeterminado, para hacer uso de los componentes Material UI Container y Box para proporcionar un diseño de página básico. Para ello, buscaremos el archivo y sustituiremos su contenido por el siguiente código, está ubicado en la ruta: src/components/layout.js

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import { StaticQuery, graphql } from 'gatsby'
import Box from '@mui/material/Box';
import Container from '@mui/material/Container';

import Navigation from './Navigation/Navigation';

const Layout = (props) => {
    const {children} = props;

    return (
        <StaticQuery
            query={graphql`
        query SiteTitleQuery {
          site {
            siteMetadata {
              title
            }
          }
        }
      `}
            render={data => (
                <>
                    <Helmet
                        title={data.site.siteMetadata.title}
                        meta={[
                            {name: 'description', content: 'Sample'},
                            {name: 'keywords', content: 'sample, something'},
                        ]}
                    >
                        <html lang="en"/>
                    </Helmet>
                    <Container maxWidth="lg">
                        <Navigation siteTitle={data.site.siteMetadata.title}/>
                        <Box component="main">
                            {children}
                        </Box>
                    </Container>
                </>
            )}
        />
    )
}

Layout.propTypes = {
    children: PropTypes.node.isRequired,
}

export default Layout;

        En el ejemplo anterior, estamos importando los componentes Box y Container del paquete @ material-ui / core y luego los usamos para envolver el contenido de cada página que usa el componente Layout.

     Agregue un componente de navegación.

        Agregue el archivo src / components / Navigation / Navigation.js. Usaremos esto como encabezado y navegación para nuestra aplicación:

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
import React from 'react';
import { Link } from 'gatsby';
import { makeStyles } from '@mui/styles';
import AppBar from '@mui/material/AppBar';
import Button from '@mui/material/Button';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';

const useStyles = makeStyles({
    root: {
        flexGrow: 1,
    },
    menuButton: {
        marginRight: 2,
    },
    title: {
        flexGrow: 1,
    },
});

function Navigation(props) {
    const classes = useStyles();

    return (
        <AppBar position="static" className={classes.root}>
            <Toolbar>
                <Typography
                    variant="h6"
                    className={classes.title}
                >
                    {props.siteTitle}
                </Typography>
                <div>
                    <Button
                        component={Link}
                        to="/"
                        color="inherit"
                    >
                        Home
                    </Button>
                </div>
            </Toolbar>
        </AppBar>
    );
}

export default Navigation;

     Agregue un poco de estilo a la página de inicio

        Actualice la página de inicio, src / pages / index.js, para usar los componentes Paper y Typography para darle un poco más de estilo:

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
import React from 'react'
import PropTypes from 'prop-types';
import { Link } from 'gatsby'
import { makeStyles } from '@mui/styles';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
import Layout from '../components/layout'

const useStyles = makeStyles({
    root: {
      spacing: [3, 2],
      padding: '30px',
    },
});

const IndexPage = (props) => {
    const classes = useStyles();

    return (
        <Layout>
            <Paper className={classes.root}>
                <Typography variant="h2">Hi people</Typography>
                <Typography variant="subtitle1" paragraph>
                    Welcome to your new Gatsby site using <a href="https://material-ui.com">Material UI</a> for the UI.
                </Typography>
                <Typography variant="subtitle1" paragraph>
                    Now go build something great.
                </Typography>
                <Link to="/page-2/">Go to page 2</Link>
            </Paper>
        </Layout>
    );
};

IndexPage.propTypes = {
    classes: PropTypes.object.isRequired,
};

export default IndexPage;

        SI arrancamos nuevamente nuestra aplicación de Gatsby, veremos un resultado mucho más moderno y atractivo:

lando gatsby develop --host 0.0.0.0

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Agregar una nueva página estática en Gatsby

        Para añadir una nueva página estática en Gatsby, bastará con crear un archivo con la extensión .js, y colocarlo dentro de la carpeta src/pages/. A continuación, una vez completados los datos que queremos mostrar, gatsby se encargará de generar la url para que podamos acceder a esa pagina.

        Hagamos una prueba, vamos a crear una página llamada Sobre Nosotros, para ello, abriremos nuestro IDE y crearemos el archivo correspondiente, dentro de la carpeta src/pages/sobre-nosotros.js, luego pegaremos el siguiente código y comprobaremos el resultado.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
import React from 'react'
import { Link } from 'gatsby'

import Layout from '../components/layout'

const SobreNosotrosPage = () => (
    <Layout>
        <h1>Sobre Nosotros</h1>
        <p>Esta aplicación es un conjunto seleccionado de las mejores recetas, cuidadosamente
            seleccionados solo para nuestros miembros.</p>
        <Link to="/">Home</Link>
    </Layout>
)

export default SobreNosotrosPage

        Suponiendo que el servidor de desarrollo de gatsby se está ejecutando, cuando guarde este archivo, Gatsby debería encontrarlo automáticamente, compilar la versión actualizada de su aplicación y hacer que la página esté disponible para su visualización.

        Para acceder a esta nueva página estática de Gatsby, escribiremos en el navegador la siguiente url:

http://gatsbymobile.lndo.site/sobre-nosotros

        El resultado, debería ser uno parecido al de la siguiente imagen.

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Mostrar contenido dinámico en Gastby desde Drupal 9

        Ahora que tenemos el "Master en Creación de Páginas Estáticas", podremos pasar al siguiente nivel, que consistirá en la generación de listados con el contenido importado desde Drupal 9. Para esta parte

        Para generar páginas estáticas para el contenido en la base de datos GraphQL de Gatsby, necesitamos hacer un par de cosas. Primero, necesitamos consultar la base de datos y hacer una lista de qué páginas queremos que Gatsby genere en qué ruta. Para hacer esto, implementamos la API de nodo createPages () de Gatsby; consultar la base de datos GraphQL para obtener una lista de las páginas que queremos generar; y luego proporcione a Gatsby información sobre esas páginas. Esta información incluye la ruta en la que queremos que viva la página, la plantilla que queremos usar para representar el HTML de la página y suficiente información contextual para que el componente de la plantilla pueda extraer el resto de la información que necesita de la base de datos en Tiempo de construcción.

        Luego, necesitamos escribir un componente React para usar como plantilla para renderizar cada página individual, así como una consulta de página GraphQL que Gatsby ejecutará para obtener los datos necesarios para construir la página, y luego inyectar automáticamente como props.data en nuestro componente.

     Implementar la API createPages () de Gatsby

        Cuéntale a Gatsby sobre las páginas que quieres que represente implementando la API createPages (). Esto se hace exportando un createPages, con nombre funcional desde el archivo gatsby-node.js,  con nombre especial en la raíz de su proyecto. Continúe y cree el archivo si aún no existe.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

        Una vez abierto, copiaremos el siguiente código y lo añadiremos justo debajo del código actual.

const path = require(`path`);

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;

  return new Promise((resolve, reject) => {
    graphql(`
      {
        allNodeRecipe {
          edges {
            node {
              drupal_id,
              title,
              path {
                alias,
              }
            }
          }
        }
      }
    `).then(result => {
      result.data.allNodeRecipe.edges.forEach(({ node }) => {
        let path_alias;
        if (node.path.alias == null) {
          path_alias = `recipe/${node.drupal_id}`;
        } else {
          path_alias = node.path.alias;
        }

        createPage({
          // This is the path, or route, at which the page will be visible.
          path: path_alias,
          // This the path to the file that contains the React component
          // that will be used to render the HTML for the recipe.
          component: path.resolve(`./src/templates/recipe.js`),
          context: {
            // Data passed to context is available in page queries as GraphQL
            // variables.
            drupal_id: node.drupal_id,
          },
        })
      });

      resolve()
    })
  })
};

     Definir una plantilla para esta "recipe" o receta de Gatsby

        A continuación, debemos definir la plantilla que se utiliza para representar el HTML de una "recipe". Según el código anterior, esto debería estar en src/templates/recipe.js. Necesitamos exportar un componente React y una consulta de página.

        Crearemos el archivo para la plantilla, en la dirección mencionada de la línea anterior y luego pegaremos el siguiente código:

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
import React from 'react';
import { graphql } from 'gatsby';
import Helmet from 'react-helmet';
import Paper from '@mui/material/Paper';
import Layout from '../components/layout';
import Recipe from '../components/Recipe/Recipe';
import {makeStyles} from "@mui/styles";

const useStyles = makeStyles({
    root: {
        spacing: [3, 2],
        padding: '30px',
    },
});


const RecipeTemplate = (props) => {
    const classes = useStyles();

    const { nodeRecipe: recipe } = props.data;

    return (
        <Layout>
            <Helmet
                title={`Umami - ${recipe.title}`}
                meta={[
                    {name: 'description', content: recipe.title},
                ]}
            />
            <Paper className={classes.root}>
                <Recipe
                    {...recipe}
                    category={recipe.relationships.category[0].name}
                    tags={recipe.relationships.tags}
                    instructions={recipe.instructions.processed}
                    summary={recipe.summary.processed}
                />
            </Paper>
        </Layout>
    )
};

export default RecipeTemplate;

// The $drupal_id variable here is obtained from the "context" object passed into
// the createPage() API in gatsby-node.js.
//
// Also note the use of field name aliasing in the query. This is done to
// help normalize the shape of the recipe data.
export const query = graphql`
  query RecipeTemplate($drupal_id: String!) {
    nodeRecipe(drupal_id: {eq: $drupal_id}) {
      drupal_id,
      title,
      cooking_time: field_cooking_time,
      difficulty: field_difficulty,
      ingredients: field_ingredients,
      preparation_time: field_preparation_time,
      number_of_servings: field_number_of_servings,
      instructions: field_recipe_instruction {
        processed,
      },
      summary: field_summary {
        processed,
      },
      relationships {
        category: field_recipe_category {
          name,
        }
        tags: field_tags {
          name,
        }
      }
    }
  }
`;

     Por último, crearemos el componente para mostrar el contenido individual de cada receta, dentro del listado que acabamos de construir, para ello, generaremos un nuevo archivo en la siguiente ruta: src/components/Recipe/Recipe.js

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
import React from 'react';
import PropTypes from 'prop-types';
import ImageList from '@mui/material/ImageList';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import Typography from '@mui/material/Typography';
import RecipeList from "../RecipeList/RecipeList";


const Recipe = (props) => (

    <>
        <Typography variant="h2" paragraph>{props.title}</Typography>
        <ImageList cols={5} cellHeight="auto">
            <ListItem>
                <ListItemText primary="Difficulty" secondary={props.difficulty} />
            </ListItem>
            <ListItem>
                <ListItemText primary="Cooking time" secondary={`${props.cooking_time} minutes`} />
            </ListItem>
            <ListItem>
                <ListItemText primary="Preparation time" secondary={`${props.preparation_time} minutes`} />
            </ListItem>
            <ListItem>
                <ListItemText primary="Category" secondary={props.category} />
            </ListItem>
            {props.tags &&
            <ListItem>
                <ListItemText primary="Tags" secondary={props.tags.map(item => item.name)}/>
            </ListItem>
            }
        </ImageList>

        <Typography variant="subtitle1">Summary:</Typography>
        <Typography variant="body1" paragraph dangerouslySetInnerHTML={{ __html: props.summary }} />

        <Typography variant="subtitle1">Ingredients:</Typography>
        <List dense={true}>
            {
                props.ingredients.map((item, index) => <ListItem key={index}>{item}</ListItem>)
            }
        </List>

        <Typography variant="subtitle1">Preparation:</Typography>
        <Typography variant="body1" paragraph dangerouslySetInnerHTML={{ __html: props.instructions }} />
        <RecipeList />
    </>
);

Recipe.propTypes = {
    title: PropTypes.string.isRequired,
    difficulty: PropTypes.string.isRequired,
    cooking_time: PropTypes.number.isRequired,
    preparation_time: PropTypes.number.isRequired,
    ingredients: PropTypes.arrayOf(PropTypes.string),
    summary: PropTypes.string.isRequired,
    instructions: PropTypes.string.isRequired,
    category: PropTypes.string.isRequired,
    tags: PropTypes.array,
};

export default Recipe;

     Cuando hayamos terminado, ejecutaremos el código para reconstruir Gastby y realizaremos la coprobación accediendo a una págiana no existente, escriendo cualquier cosa después del dominio de nuestra pagina. Con esto deberíamos ver un listado de las Recetas del Drupal 9.

lando gatsby develop --host 0.0.0.0

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

        Con los cambios anteriores en su lugar, reinicie el servidor de desarrollo de Gatsby con gatsby Develop. Cuando se reconstruye el contenido estático de la aplicación, ahora debería incluir las páginas de recetas obtenidas de Drupal. Pruébelo navegando directamente a la ruta de una receta o navegando a una página 404 conocida como http: // localhost: 8000 / asdf. Gatsby tiene un truco útil en el que las páginas 404 en el servidor de desarrollo le darán una lista de todas las páginas que Gatsby conoce internamente.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

Gatsby con Drupal 9 | Configurar de conexión

Video de Youtube
URL de Video remoto

Si no ves el video, puedes refrescar el navegador, presionando (Ctrl+Shift+R | Ctrl+F5 o Shift+F5), o abrirlo directamente desde el Canal de Youtube... HAZ CLIC AQUI

        Ha llegado el momento de conectar nuestra web de Gatsby, con un proyecto Drupal 9, con el objetivo de utilizar este último como Backend, para la gestion de nuestros contenidos y usuarios. 

      Drupal 9 Headless con Gatsby

          Antes de pasar al tema principal de este artículo, quiero aclararte que ya existe una forma de trabajar en Drupal 9, utilizando tu Theme personalizado basado en React.js, sin necesidad de desacoplarlo, aportando las mismas ventajas de velocidad de carga, posibilidades de personalización, aplicación de la metodología BEM para simplificar el uso de las plantillas Twig, entre otras muchas novedades. 

        Esta nueva manera de trabajar con Drupal y React integrados es gracias a módulo Emulsify, que te explico con detalle en otra serie de artículos, si quieres aprender más sobre ello HAZ CLIC AQUÍ

     Requisitos para este ejercicio

     Paso 1 - Instalación y configuración del Drupal 9

        En este ejercicio, utilizaremos la instalación de Demostración: Umami Food Magazine (Experimental), ya que nos ofrece múltiples contenidos con imágenes que nos servirán perfectamente para explicar y evaluar la implementación con Gatsby. Además ya viene por defecto al descargar los archivos de Drupal 9.

       Una vez descargado Drupal 9 usando Composer y hayas configurado la base de datos que quieres utilizar, tendrás que seleccionar la última opción de las tres disponibles, para que comience le proceso de configuración.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Cuando se haya terminado la instalación, tendrás un Drupal ejecutándose con varios contenidos y tipos ideal para realizar cualquier ejercicio, o demostración sobre el potencial de Drupal.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Paso 2 - Desarga de la estuctura base Gastby Starter Default

        Aunque al principio de este curso, había planteado que utilizaríamos LAMP con WSL2 y aprovechando que ya sabemos cómo configurar e instalar Lando, en nuestro ordenador, vamos a sacar partido a este conocimiento haciendo lo mismo para instalar nuestra aplicación de Gatsby.

        Para ello, sólo tendremos que crear una nueva carpeta, con el nombre que prefieras, yo le he pueso - gatsby - y colocarla en el mismo lugar que hemos guardado nuestro proyecto Drupal "/home/TU_USUARIO/proyectos/formacion", a continuación, descargaremos la distribuición de Gatsby para que nos sirva de base de nuestra aplicación.

git clone https://github.com/gatsbyjs/gatsby-starter-default.git/ gatsby

     Con este comando, además de descargarnos la estructura, se guardará dentro de una carpeta llamada - gatsby - . Una vez terminada la descarga los archivos, podremos pasar a al siguiente paso. Si quieres visitar el repositorio original Haz clic aquí

     Paso 3 - Creación del archivo de configuración para Lando

        Nos moveremos dentro de la carpeta recién creada con la estrucutura base de - gastsby - ; inmediatamente después, crearemos dentro un archivo de confinguración de Lando, con el nombre: ( .lando.yml ), para configurar algunos detalles relacioandos con nuestra aplicación.

        Ahora, abriremos el archivo con el editor de texto, usaremos nano que viene con nuestra distrubución de ubuntu.

cd gatsby

sudo touch .lando.yml

sudo nano .lando.yml 

       Una vez dentro del archivo, colocaremos dentro el siguiente código, guardaremos los cambios y cerraremos:

name: gatsbymobile

proxy:
  appserver:
    - gatsbymobile.lndo.site:8000

services:
  appserver:
    type: node:14
    port: '8000'
    #command: gatsby develop --host 0.0.0.0
    install_dependencies_as_me:
      - yarn global add gatsby-cli
      - yarn

tooling:
  yarn:
    service: appserver
  gatsby:
    service: appserver
  node:
    service: appserver
  npm:
    service: appserver

   A continuación, guardaremos el archivo, abriremos una pestaña nueva de nuestra Consola mejorada de windows, iniciaremos sesión con nuestro usuario NOROOT, igual que hemos hecho con el Drupal 9, nos colocaremos dentro de la carpeta correspondiente y ejecutaremos el comando de arranque de lando para gatsby:

lando rebuild
lando gatsby develop --host 0.0.0.0

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Corrección de posible error

        Si al ejecutar el comando anterior, el resultado no ha sido el de la imagen, deberás ejecutar el comando de reconstrucción para que se corrija el fallo:

lando rebuild

     En este caso, para acceder a nuestra web de Gatsby y a la de Graphql, en lugar de utilizar las que nos muestra la consola, accederemos escribiendo en el navegador el dominio que hemos configurado en el archivo de lando.

http://gatsbymobile.lndo.site/

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
http://gatsbymobile.lndo.site/__graphql

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

    Paso 4 - Conectando Drupal 9 con Gatsby

       En este caso, ya tenemos funcionando una aplicación de Gastby, pero aún no la hemos conectado con ninguna web de Drupal para completar el ejercicio. Así, que abriremos la instalación de Drupal que habíamos hecho y utilizaremos la distribución de Umami, que viene por defecto en Drupal 9 y que viste en las imágenes del principio.

     Si haz realizado la instalación siguiedo el ejercicio de Instalar Drupal 9 en Ubuntu 20.04 con Lando y WSL2 en Windows 11, deberás volver instalar Drupal para que esta vez puedas activar la distribución de Umami Food Magazine, para ello, solo tendrás que ejecutar el siguiente comando (CUIDADO PORQUE BORRA TODO), y así podrás elergir la nueva opción de instalación.

lando destroy

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

         Tendrás que confirmar que quieres ejecutar el comando "DESTROY" y una vez terminado el proceso, podrás volver a instalar Drupal 9 desde cero, esta vez seleccionando el Perfil de Instalación Umami Food Magazine.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

        Ahora si vuelves a ejecutar el comando de arranque, podrás acceder a la url y seleccionar tu nueva instalación.

lando start

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     A continuación, deberás activar los módulos Json Api y Json Extras, además de la configuración que te permitirá servir los contenidos de Drupal en formato Json, y que puedas mostrarlos al conectar Drupal 9 con Gatsby.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

     Una vez tengas el Drupal 9 configurado correctamente y con el Perfil de Instalación Umami Food Magazine instalado, nos colocaremos dentro de la carpeta de nuestro Gatsby, para proceder con la instalación del plugin gatsby-source-drupal, primero tendremos que detener la ejecución de Gatsby con con las teclas:

Ctrl + C

  y a continuación, ejecutaremos el comando siguiente, ya que estamos utilizando Lando.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
lando npm install gatsby-source-drupal

     Una vez terminada la descarga, podremos abrir el archivo de configuración de Gastsby, llamado: gatsby-config.js y añadiremos el siguiente código debajo del apartado de plugins:

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony
{
  resolve: `gatsby-source-drupal`,
  options: {
    baseUrl: `http://drupal-gatsby.lndo.site/`,
    apiBase: `jsonapi`, // optional, defaults to `jsonapi`
  },
},

 

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

         Una vez hayamos confirmado los datos de conexión, susituyendo el valor de "baseUrl", por la url que nos haya generado Gatsby, y volveremos a poner en marcha nuestra aplicación con el comando:

lando gatsby develop --host 0.0.0.0

        Si refrescamos el navegador donde tenemos abierto el Grafql, podremos comprobar que ya estamos conectados, porque nos aparecerán todos los contenidos de la web Drupal 9, para generar nuestras consultas.

Drupal 9 headless Gatsby  | www.drupaladicto.com - Consultor especializado en drupal y symfony

   Posibles fallos y correcciones

      En el caso de que al instalar el plugin gatsby-source-drupal, al entrar a la url de graphql, no veas el listado de los contenidos de Drupal, puedes ejecutar los siguientes comandos.

lando rebuild

sudo rm -Rf .cache

sudo rm -Rf public

lando gatsby clean

     Los cuatro comandos anteriores se encargarán de reconstruir tu aplicación, borrar los archivos de caché y la carpeta pública, que se regenerarán una vez vuelvas a ejecutar el comando de arranque del Gatsby. Con esto deberías ver todos los contenidos del Drupal en tu Graphql.