L’utilisation de WordPress en tant que Headless CMS peut être une très bonne solution lorsqu’il s’agit de performance, d’optimisation ou même en terme de maintenance et évolution d’un site web. Nous allons voir aujourd’hui comment utiliser l’API de WordPress avec le générateur de site statique GatsbyJS et le framework React.js. L’ensemble de ces éléments constitue ce qu’on appelle une JAMstack (Javascript API Markup). Et c’est la stack avec laquelle on a choisit avec l’équipe pour la refonte du site Dotwiz.

Qu’est ce qu’un site statique ?

Un site statique, comme son nom l’indique est un site qui contient des pages statiques. C’est à dire qu’après le déploiement le contenu ne change pas et ce quelque soit le visiteur. Contrairement aux sites dynamiques il ne requiert aucun langage de programmation backend sauf bien sûr pour le développement de notre api qui est la source de nos données et c’est une chose à part. Pour répondre à ce besoin beaucoup de générateurs de sites statiques existent : Jekyll, Hugo, Hexo, Gatsby,…  Et pour les avoir testé j’ai vraiment aimé développer sur Gatsby.

Qu’est-ce que Gatsby ?

Gatsby est un générateur de site statique ou d’après ses créateurs un blazing-fast static site generator for React. Il permet ainsi de créer rapidement un  site sous React. Il est donc parfait pour des sites vitrines, portfolios, blog,…

Comme Gatsby est basé sur React avec une architecture PRPL, toutes les pages statiques sont générées et pas rechargées, ce qui procure une vitesse de chargement exceptionnelle.

gatsbyjs

Comment ça marche ?

Les pages statiques peuvent être sourcées à partir d’une énorme variété de data (Markdowns, CMS, APIs…), traduites en GraphQL, puis requêtées pour produire une collection de pages générées au moment de la construction (build).

Gatsby offre beaucoup de plugins permettant de varier les sources de data et rendre notre site/projet très modulable:

gatsbyjs-works

Mise en place de l’API

Dans cet article nous allons prendre pour exemple l’API de WordPress comme source de données. Pour ce faire je vous invite à lire mon article Utiliser l’API Rest de WordPress.

Création du projet avec Gatsby

Maintenant que notre API est mise en place nous passons au développement de notre site.

Pour pouvoir créer un projet Gatsby, il faut au préalable avoir Node d’installé et Gatsby CLI en global.

Installation de Gatsby

npm install -g gatsby-cli

Création du projet

Nous générons maintenant le projet avec la commande gatsby new:

gastby new gatsby-personal-blog

Lancement du serveur

# se déplacer dans le dossier
cd gatsby-personal-blog

# démarrer le serveur sur localhost:8000
gatsby-develop

gatsby-front-dev

Installation du plugin source WordPress

gatsby-source-wordpress est un plugin permettant de récupérer les données depuis l’API de WordPress à l’aide de sa couche d’abstraction des données avec GraphQL.

Installation du plugin

npm i gatsby-source-wordpress

Pour que ça marche le plugin doit être configuré dans le fichier gatsby-config.js

module.exports = {
  siteMetadata: {
      title: "Gatsby default starter"
  },
  plugins: [
    "gatsby-plugin-react-helmet",
    "gatsby-plugin-sass",
    {
      resolve: "gatsby-source-wordpress",
      options: {
        baseUrl: "abdessalam-benharira.me",
        hostingWPCOM: false,
        protocol: "https",
        useACF: false,
        verboseOutput: true
      },
    },
  ],
}

N’oubliez surtout pas de relancer le serveur pour que les changements soient pris en compte.

Page des articles

Dans la page d’accueil nous allons faire en sorte d’afficher les articles. La liste des fichiers js concernant les pages se trouve dans src/pages/ et la page en question est src/pages/index.js. Pour tester quels champs disponibles récupérer rien de plus simple qu’utiliser GraphiQL, un IDE GraphQL permettant de tester et générer nos requêtes GraphQL, disponible à cette adresse http://localhost:8000/___graphql  au lancement du serveur.

import React, { Component } from "react"
import PropTypes from "prop-types"
import Link from "gatsby-link"
import Helmet from "react-helmet"


class IndexPage extends Component {
  render() {
      const allPosts = this.props.data.allWordpressPost.edges
      return(
          <div>
            {allPosts.map(({node}) =>
                <div key={node.slug}>
                    <Link to={node.slug}>
                        <h3>{node.title}</h3>
                    </Link>
                </div>
                <div dangerouslySetInnerHTML={{__html: node.excerpt}}></div>
                <span>{node.date}</span>
            )}
          </div>
      )
  }
}

export default IndexPage

export const pageQuery = graphql`
    query IndexPageQuery {
        allWordpressPost {
            edges {
                node {
                    id
                    slug
                    title
                    content
                    excerpt
                    date
                    modified
                }
            }
        }
    }
`

L’export de la pageQuery, une requête GraphQL permet de récupérer la liste entière des articles avec les champs données sous un format JSON. La donnée retournée est mise dans une variable allPosts sur laquelle on va pourvoir boucler grâce à map() pour afficher les éléments un à un.

Voici le résultat :

gatsby-index-posts

Page d’un article

Pour l’instant nous arrivons à afficher la liste de tous les articles, c’est bien mais on peut faire mieux. Par exemple l’affichage d’un seul article.

const _ = require("lodash")
const Promise = require("bluebird")
const path = require("path")
const slash = require("slash")
const postsQuery = `
{
  allWordpressPost {
    edges {
      node {
        id
        slug
        title
        content
        excerpt
        date
        modified
      }
    }
  }
}
`

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

  return new Promise((resolve, reject) => {
    graphql(postsQuery)
      .then(result => {
        if (result.errors) {
          reject(result.errors)
        }
        const postTemplate = path.resolve("./src/templates/post.js")
        _.each(result.data.allWordpressPost.edges, (edge, index) => {
          const next =
            index === 0
              ? null
              : result.data.allWordpressPost.edges[index - 1].node
          const prev =
            index === result.data.allWordpressPost.edges.length - 1
              ? null
              : result.data.allWordpressPost.edges[index + 1].node
          createPage({
            path: `/${edge.node.slug}/`,
            component: slash(postTemplate),
            context: {
              id: edge.node.id,
              prev,
              next,
            },
          })
        })
      })
  })
}

Voici le résultat :

post gatsby wordpress

On peut très bien aller plus loin en récupérant les auteurs, les tags,… et les étapes à suivre restent les mêmes.

Avant de partir…
Merci pour votre lecture ! 😊