GatsbyJS + WordPress (PARTE 2) – HEADLESS CMS Y ESTRUCTURA

En la entrada anterior, pudimos entender cuál es la finalidad del framework Gatsby, definir qué son los sitios estáticos y cómo crear uno. Para esta segunda parte se mostrará cómo es posible desplegar el contenido de un blog creado en WordPress en un sitio estático de GatsbyJS, además de algunos conceptos referentes al funcionamiento del framework; para esto vamos a trabajar con el proyecto creado en la última entrada y vamos a modificarlo para que cumpla con este nuevo objetivo, pero primero vamos a definir un concepto importante, el headless CMS.

WORDPRESS COMO HEADLESS CMS

Antes de comenzar a codificar, hay que tener claro cuál será la fuente que utilizaremos para extraer la información y cómo publicarla en el sitio estático, para esto vamos a aprovechar las bondades que nos brinda WordPress (la creación de páginas y entradas de blog con etiquetas, categorías, imágenes, etc.). Tradicionalmente un CMS (Sistema gestor de contenidos, por sus siglas en inglés) nos da la capacidad de gestionar elementos digitales para su publicación en sitios web estructurados de manera intuitiva (en muchos casos, sin requerir conocimiento de programación), y con varias características de navegación y SEO incluídas. Al utilizar WordPress como nuestro CMS podemos acceder a todo esto, pero en este caso, lo haremos de manera desacoplada (Headless), esto quiere decir que nuestro CMS solo fungirá como back-end, y nuestro proyecto de Gatsby será el front-end de la aplicación, esta es una arquitectura que ha ganado popularidad debido a las ventajas que ofrecen los frameworks y herramientas de desarrollo para front-end, además de la considerable mejora de seguridad al tener la lógica del front-end separada del back-end. Para consultar más información sobre Headless CMS accede aquí. En el siguiente diagrama podemos observar cómo sería una arquitectura Headless CMS.

Conceptualizando lo anterior, vamos a crear un sitio de WordPress, esto puede hacerse de manera gratuita desde wordpress.com, o bien, podemos levantar nuestro sitio de WordPress en un servidor web. **Nota: Los pasos mostrados aquí solo son ilustrativos y pueden variar si se tiene configurado el hosting desde WordPress.com, si se cuenta con el plan gratuito se pueden presentar ciertas restricciones. **

Trabajando en el BLOG

Al tener arriba nuestro sitio de WordPress ahora pasaremos a la creación de nuestra entrada. Lo cual haremos desde el Dashboard de WordPress, en la sección de Entradas, donde vamos a borrar la entrada de prueba existente y generaremos una nueva. Lo ideal sería que la entrada que creemos contenga al menos un título, suficiente contenido, etiquetas, categorías y una imagen destacada. Al terminar nuestra entrada la publicaremos y el sitio contará ya con contenido suficiente para experimentar.

Después de haber concluido con los pasos anteriores y tener listo WordPress, pasaremos a la configuración del proyecto de Gatsby para que este pueda consultar la información desde el sitio.

Instalación de plugins

El siguiente paso consiste en la instalación de los plugins wp-gatsby, wp-graphql y wp-graphiql en nuestra instancia de WordPress. Para el primero, se puede realizar la búsqueda desde la sección de Plugins del sitio de administración. Seleccionaremos la opción de agregar nuevos y buscaremos el plugin con el nombre WPGatsby y daremos clic en Instalar ahora.

La instalación de los otros dos plugins se realiza de forma manual, de modo que se descargará el contenido desde sus respectivos repositorios. WP Graphql nos ayudará a implementar consultas de GraphQL para obtener información del sitio de WordPress, mientras que wp-graphiql nos brindará un entorno visual sobre el cual podemos trabajar para hacer pruebas con las consultas. Los enlaces de descarga son:

Para el proceso de instalación solo es necesario que descarguemos el código como .zip, y asegurarnos que tengamos habilitada un tamaño de carga de archivos suficiente en nuestro servidor de WordPress. Después procederemos a la pantalla de Agregar Plugins y se elegirá la opción Cargar Plugin, en donde subiremos el archivo .zip para su instalación en el sistema. Después de hacer el proceso con los dos plugins, nos aseguraremos de activarlos y veremos que ya contamos con ellos en la sección de Plugins.

Si la instalación es exitosa, en la parte inferior de la barra de menú del sitio de administraición de WordPress aparecerá un elemento en la lista llamado GraphiQL, desde aquí podremos comprobar que la instalación fue exitosa y se pueden realizar pruebas de consultas de elementos de WordPress, en esta pantalla se mostrarán todos los esquemas de GraphQL disponibles.

Instalación de plugin en Gatsby

En la carpeta del proyecto vamos a instalar el complemento gatsby-source-wordpress-experimental:

$ npm install --save gatsby-source-wordpress-experimental

NOTA: A la fecha de publicación de esta entrada, el paquete gatsby-source-wordpress-experimental es el que contiene las últimas actualizaciones sustituyendo a gatsby-source-wordpress que pronto quedará obsoleto. Es posible que el paquete a instalar cambie de nombre en el futuro. Para mayor información: https://www.gatsbyjs.com/plugins/gatsby-source-wordpress-experimental/ y https://www.gatsbyjs.com/plugins/gatsby-source-wordpress/.

Este plugin nos permitirá utilizar WordPress como fuente de información para poder desplegar la información de nuestro blog. Una vez que se haya instalado y guardado, lo siguiente será modificar nuestro gatsby-config.js como se muestra a continuación:

plugins: [
  
  ...,
  
	{
      resolve: `gatsby-source-wordpress-experimental`,
      options: {
        url: `http://localhost:8001/graphql`,
      }
    },

 ...

Realizando consulta

Teniendo el plugin configurado apuntando al endpoint de GraphQL de nuestro sitio, vamos a ejecutar una prueba de nuestro sitio de Gatsby que se desplegará en el puerto 8000:

$ gatsby develop

Una vez corriendo el proyecto, podemos acceder a http://localhost:8000/__graphql, interfaz desde la cual podemos realizar consultas de graphql desde nuestro cliente y poder consultar la información que está obteniendo nuestro proyecto desde WordPress de manera estática.

Como podemos observar, del lado izquierdo se generan todos los esquemas que nos permiten acceder al contenido de WordPress, de esta forma, por ejemplo, si queremos acceder a todos los posts de WordPress, podemos generar consultas con el schema allWpPost, también tenemos a nuestra disposición elementos como las páginas, menús, comentarios, medios interactivos, etc.

RENDERIZANDO CONTENIDO EN GATSBY

Creando lista de entradas

Para este punto ya contamos con la capacidad de acceder a posts y otros elementos del sitio de WordPress, lo que haremos ahora, será modificar nuestra página principal para que muestre las entradas disponibles en el blog, para esto nos iremos al archivo /pages/index.js y lo modificaremos de tal forma que quede como el siguiente ejemplo.

import React from "react"
import { Link } from "gatsby"
import { graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"

const IndexPage = ({ data }) => (
  <Layout>
    <SEO title="Mi Blog"/>
    <h1>Blog de Uriel</h1>
    <p>Bienvenidos al blog de Uriel, aquí podrán aprender cosas sobre tecnología.</p>
    <ul>
      {
        data.allWpPost.edges.map((post, index) =>
          (
            <li key={index}>
              <Link to={post.node.slug}>
                {post.node.title}
              </Link>
            </li>
          )
        )
      }
    </ul>

  </Layout>
)

export const query = graphql`
    query {
        allWpPost {
            edges {
                node {
                    id
                    title
                    slug
                    content
                }
            }
        }
    }

`
export default IndexPage

Hay que considerar que se están tomando algunos detalles del sitio preconstruido por defecto, como es el caso del componente Layout y el componente SEO, que posteriormente podremos modificar para que el sitio tenga la estructura que deseamos. En este caso, en la estructura de nuestro componente de React solamente despliega un arreglo que está consumiendo la información de todas las entradas de blog disponibles y las está desplegando en una lista.

Existen varios detalles a considerar, primeramente, es necesario tener un conocimiento básico de React para comprender cómo está estructurado el componente funcional de la página Index. Después, hay que destacar que este componente está alojado en la carpeta pages, de manera que automáticamente se convierte en una ruta de nuestro sitio, y al ser llamado index.js, este es el componente que se despliega en cuanto abrimos http://localhost:8000.

La distinción entre componentes y páginas es muy importante en un proyecto de Gatsby, en este caso, index.js es una página, por lo tanto, su comportamiento será distinto que el de un componente reutilizable, esto lo podemos ver en la manera en que consulta información de GraphQL. En el bloque de código mostrado, en la parte inferior, se muestra una consulta de graphql que parece no estar asociada a nuestro componente, esto es porque, al tratarse de una página, las consultas realizadas aquí, se guardan automáticamente en los props de nuestro componente con el nombre de data, es por eso que en el renderizado podemos acceder a un objeto llamado data y aquí se encuentra la información obtenida desde la consulta. Para información más detallada: https://www.gatsbyjs.com/docs/page-query/.

Al final, deberíamos ver algo similar a esto.

Creando un template de React

Las modificaciones hechas en el index.js permiten desplegar la lista de entradas en nuestro blog de WordPress, sin embargo, al dar clic en el elemento, observaremos que somos redirigidos a la página 404. Para solucionar esto, tenemos que asegurarnos de crear una página por cada una de nuestras entradas de manera dinámica, esto lo haremos utilizando el archivo gatsby-node.js y generando un template que nos permitirá desplegar el contenido.

Comenzaremos escribiendo el código de nuestro template, creando un archivo en /src/templates/post.js, cuyo contenido será el siguiente:

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
import SEO from "../components/seo"

const PostPage = ({ data }) => {
  const { post } = data

  return (
    <Layout>
      <SEO title={post.title}/>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }}/>
    </Layout>
  )
}

export const query = graphql`
    query ($id: String!) {
        post: wpPost(id: {eq: $id}) {
            id
            title
            slug
            content
        }
    }
`

export default PostPage

Al igual que en el componente index.js, aquí se realiza una consulta de graphQL para obtener información sobre un post específico, por lo que estamos utilizando el esquema wpPost, al que además le agregamos el alias post, de manera que ahora podemos acceder a él consultando el atributo post de nuestro objeto data. Un detalle importante, es que nuestro template no está generado dentro de la carpeta src/pages, de modo que este no se renderizará, también podemos ver que en la consulta se está haciendo uso de la variable $id, que no tenemos definida en ningún lugar. Para que todo esto tenga sentido, vamos a realizar modificaciones a nuestro archivo gatsby-node.js, que nos permitirá crear dinámicamente las páginas que necesitamos de acuerdo a una consulta de las entradas disponibles en tiempo de compilación del proyecto. Nuestro archivo deberá tener una estructura como la siguiente.

const path = require(`path`)
const slash = require(`slash`)

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

  const result = await graphql(`
    query {
      allWpPost {
        edges {
          node {
            id
            slug
            title
            content
          }
        }
      }
    }
  `)

  const template = path.resolve(`./src/templates/post.js`)
  const {data: { allWpPost: {edges: posts}}} = result

  posts.forEach(({ node: post }) => {
    createPage({
      path: `/${post.slug}`,
      component: slash(template),
      context: {
        id: post.id,
      },
    })
  })
}

El archivo gatsby-node.js nos permite realizar ajustes que tengan que ver con los nodos que deseamos generar para nuestros esquemas de graphQL y nos ayudan a generar contenido a partir de estos. En este caso específico, lo que estamos haciendo en este archivo es realizar una consulta de todas las entradas de blog disponibles y posteriormente tomar el template y crear las páginas de cada una de las entradas basadas en el template.

Es importante observar como a cada una de estas páginas se les asignan atributos, como el path, que indicará la ruta desde la cual podremos acceder al contenido de la entrada, y un objeto llamado context, desde el cual podremos hacer consultas como la que se realiza en el template para obtener la entrada a partir de un id.

Al final de estos pasos nuestro blog ha quedado listo y ahora podemos acceder al contenido de nuestra entrada.