Configuración

CREANDO UN BLOG CON GATSBYJS Y WORDPRESS (PARTE 2) – HEADLESS CMS Y ESTRUCTURA

Por: Uriel Infante

CREANDO UN BLOG CON GATSBYJS Y 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.

img

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. Si para este punto ya se cuenta con un sitio de WordPress, podemos saltarnos la siguiente explicación, de lo contrario, en la siguiente parte veremos como configurar una instancia de WordPress local utilizando Docker. **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. **

CONFIGURACIÓN DE WORDPRESS LOCAL

Los siguientes pasos nos permitirán la creación de un sitio de WordPress de manera local con Docker, se debe considerar que cuando queramos publicar nuestro sitio estático (como se hará en la siguiente entrada) necesitaremos contar con una instancia de WordPress accesible desde Internet o realizar el build del sitio en un equipo con acceso a WordPress; este puede estar alojado en WordPress.com o en cualquier otro servidor:

  1. Instalar Docker en nuestro equipo. El instalador o las instrucciones se pueden encontrar en: https://www.docker.com/get-started. Si ya contamos con Docker, hay que asegurarnos de que se trate de una versión reciente. También asegurémonos de contar con el comando docker-compose. Para comprobar nuestra instalación, ejecutemos el siguiente comando en nuestra terminal:
$ docker-compose -v

Si vemos una salida como la siguiente, nuestro comando funcionó perfectamente, de lo contrario, revisemos la documentación específica para nuestro sistema, Docker puede ser ejecutado en macOS, Linux y Windows.

docker-compose version 1.26.2, build eefe0d31
  1. Posteriormente, vamos a crear una carpeta en la cual configuraremos la instancia de Docker para WordPress y vamos a generar un archivo llamado docker-compose.yml.

    $ mkdir wordpress-blog
    $ cd wordpress-blog
    $ touch docker-compose.yml
    

    El contenido de nuestro docker-compose.yml será el siguiente:

    version: '3.3'
    
    services:
      db:
        image: mysql:5.7
        volumes:
          - db_data:/var/lib/mysql
        restart: always
        environment:
          MYSQL_ROOT_PASSWORD: wordpress
          MYSQL_DATABASE: wordpress
          MYSQL_USER: wordpress
          MYSQL_PASSWORD: wordpress
    
      wordpress:
        depends_on:
          - db
        image: wordpress:latest
        ports:
          - "8001:80"
        restart: always 
        volumes:
          - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
        environment:
          WORDPRESS_DB_HOST: db:3306
          WORDPRESS_DB_USER: wordpress
          WORDPRESS_DB_PASSWORD: wordpress
          WORDPRESS_DB_NAME: wordpress
    volumes:
    

db_data: {}


Este documento se encarga de la creación de las imágenes para base de datos y servidor web de un proyecto de WordPress, podemos revisar nuestra configuración y cambiar las contraseñas y puertos. Para este caso específico utilizaremos las que aparecen arriba, se desplegará una instancia de un servidor de Apache con WordPress instalado y accesible desde el puerto 8001 de nuestro equipo, además de un servidor de Base de datos MySQL vinculado. Es importante notar que estamos haciendo referencia a un archivo llamado _./uploads.ini_, en este casi vamos a crear el archivo en la misma carpeta que el *docker-compose.yml*, lo cual nos permitirá cargar archivos mayores a la configuración por defecto como veremos más adelante. El contenido de _uploads.ini_ se muestra a continuación:

```php
file_uploads = On
memory_limit = 64M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 600
  1. Una vez creado nuestro archivo .yml, lo siguiente será levantar las instancias con el comando:

    $ docker-compose up -d
    

    El comando es ejecutado con la instrucción -d que nos indicará que el comando se ejecutará como un daemon en segundo plano. La primera vez que se ejecuta es posible que tarde unos segundos en terminar, debido a que se descargan las imágenes a utilizar, pero una vez que termine, podremos acceder a http://localhost:8001. Para más información sobre la sintaxis de docker-compose, consultar este enlace.

  2. Al entrar a http://localhost:8001, nos encontraremos una pantalla como la siguiente, donde realizaremos la configuración de acuerdo al lenguaje que deseemos:

Selección wordpress

  1. Al dar clic en siguiente, se nos solicitará acceder la información de un usuario y contraseña para nuestro blog, elegiremos las credenciales que deseemos y seleccionamos Instalar WordPress.

    Llenado de información

  2. Una vez instalado, se nos permitirá acceder a nuestra cuenta con el usuario y contraseña que configuramos previamente.

NUEVA ENTRADA DE 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.

Definición de entradas wordpress

Lo ideal sería que la entrada que creemos contenga al menos un título, suficiente contenido, etiquetas, categorías y una imagen destacada.

Entrada WordPress

Al terminar nuestra entrada la publicaremos y el sitio contará ya con contenido suficiente para experimentar.

VINCULANDO CON GATSBY

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 (http://localhost:8001/wp-admin/plugins.php). Seleccionaremos la opción de agregar nuevos y buscaremos el plugin con el nombre WPGatsby y daremos clic en Instalar ahora.

Agregar plugin gatsby

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.

Selección de archivo

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.

Gatsby integración

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.

GraphQL consultas

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`,
      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 (no confundir con http://localhost:8001/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.

Consulta GraphQL

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.

Blog Gatsby

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. Entrada Gatsby

Esta entrada concluye aquí, sin embargo, en la siguiente parte de esta serie estaremos hablando de cómo hacer el manejo de imágenes utilizando Gatsby para tener un sitio más dinámico y completo.

RECURSOS

El proyecto generado para esta entrada puede ser consultado en: https://github.com/ur13l/gatsby-blog

ENLACES DE REFERENCIA

https://www.cmscritic.com/cloud-first-headless-cms-what-it-is-and-why-you-should-use-it/

https://www.docker.com/get-started

https://docs.docker.com/compose/install/

https://docs.docker.com/compose/wordpress/

https://docs.docker.com/compose/

https://www.gatsbyjs.com/docs/page-query/

Av. Cerro Gordo del Campestre 201
Int. 303
Col. Las Quintas
León, Gto.
C.P. 37125

ROCKTECH R+D © 2020