Catégories
Astuces et Design

Comment créer des pages de taxonomie avec Gatsby et Sanity.io

Dans ce didacticiel, nous allons voir comment créer des pages de taxonomie avec Gatsby avec du contenu structuré de Sanity.io. Vous apprendrez à utiliser les API de création de nœuds de Gatsby pour ajouter des champs à vos types de contenu dans l'API GraphQL de Gatsby. Plus précisément, nous allons créer des pages de catégorie pour le démarrage du blog de Sanity.

Cela étant dit, il n'y a rien de spécifique à Sanity dans ce que nous couvrons ici. Vous pouvez le faire quelle que soit la source de contenu dont vous disposez. Nous cherchons juste à Sanity.io pour des raisons de démonstration.

Soyez opérationnel avec le blog

Si vous souhaitez suivre ce didacticiel avec votre propre projet Gatsby, allez-y et passez à la section pour créer un nouveau modèle de page dans Gatsby. Sinon, rendez-vous sur sanity.io/create et lancez le démarreur du blog Gatsby. Il mettra le code de Sanity Studio et du frontal Gatsby dans votre compte GitHub et configurera le déploiement pour les deux sur Netlify. Toute la configuration, y compris le contenu d'exemple, sera en place afin que vous puissiez plonger directement dans l'apprentissage de la création de pages de taxonomie.

Une fois le projet initié, assurez-vous de cloner le nouveau référentiel sur GitHub en local et installez les dépendances:

git clone (email protected):username/your-repository-name.git
cd your-repository-name
npm i

Si vous souhaitez exécuter localement Sanity Studio (le CMS) et le front-end de Gatsby, vous pouvez le faire en exécutant la commande npm run dev dans un terminal à partir de la racine du projet. Vous pouvez également cd dans le dossier Web et exécutez simplement Gatsby avec la même commande.

Vous devez également installer la CLI Sanity et vous connecter à votre compte depuis le terminal: npm i -g @sanity/cli && sanity login. Cela vous donnera des outils et des commandes utiles pour interagir avec les projets Sanity. Vous pouvez ajouter le --help pour obtenir plus d'informations sur ses fonctionnalités et ses commandes.

Nous allons personnaliser le gatsby-node.js fichier. Pour voir le résultat des modifications, redémarrez le serveur de développement de Gatsby. Cela se fait dans la plupart des systèmes en appuyant sur CTRL + C dans le terminal et en cours d'exécution npm run dev encore.

Se familiariser avec le modèle de contenu

Regardez dans le /studio/schemas/documents dossier. Il existe des fichiers de schéma pour nos principaux types de contenu: auteur, catégorie, paramètres du site et publications. Chacun des fichiers exporte un objet JavaScript qui définit les champs et les propriétés de ces types de contenu. À l'intérieur de post.js est la définition de champ pour les catégories:

{
  name: 'categories',
  type: 'array',
  title: 'Categories',
  of: (
    {
      type: 'reference',
      to: {
        type: 'category'
      }
    }
  )
},

Cela créera un champ de tableau avec des objets de référence aux documents de catégorie. À l'intérieur du studio du blog, cela ressemblera à ceci:

Un champ de tableau avec des références aux documents de catégorie dans le studio de blog
Un champ de tableau avec des références aux documents de catégorie dans le studio de blog

Ajout de slugs au type de catégorie

Rendez-vous sur /studio/schemas/documents/category.js. Il existe un modèle de contenu simple pour une catégorie qui se compose d'un titre et d'une description. Maintenant que nous créons des pages dédiées aux catégories, il serait également utile d'avoir un champ de slug. Nous pouvons définir cela dans le schéma comme ceci:

// studio/schemas/documents/category.js
export default {
  name: 'category',
  type: 'document',
  title: 'Category',
  fields: (
    {
      name: 'title',
      type: 'string',
      title: 'Title'
    },
    {
      name: 'slug',
      type: 'slug',
      title: 'Slug',
      options: {
        // add a button to generate slug from the title field
        source: 'title'
      }
    },
    {
      name: 'description',
      type: 'text',
      title: 'Description'
    }
  )
}

Maintenant que nous avons changé le modèle de contenu, nous devons également mettre à jour la définition du schéma GraphQL. Pour ce faire, exécutez npm run graphql-deploy (alternativement: sanity graphql deploy) dans le dossier studio. Vous obtiendrez des avertissements sur les changements de rupture, mais comme nous ajoutons uniquement un champ, vous pouvez continuer sans souci. Si vous souhaitez que le champ soit accessible dans votre studio sur Netlify, vérifiez les modifications dans git (avec git add . && git commit -m"add slug field") et le pousser vers votre référentiel GitHub (git push origin master).

Maintenant, nous devons parcourir les catégories et générer des slugs pour elles. N'oubliez pas d'appuyer sur le bouton de publication pour rendre les modifications accessibles à Gatsby! Et si vous exécutiez le serveur de développement de Gatsby, vous devrez également le redémarrer.

Sidenote rapide sur le fonctionnement du plugin source Sanity

Lors du démarrage de Gatsby dans le développement ou la construction d'un site Web, le plugin source récupérera d'abord les définitions de schéma GraphQL à partir de l'API GraphQL déployée par Sanity. Le plugin source l'utilise pour indiquer à Gatsby quels champs devraient être disponibles pour l'empêcher de se casser si le contenu de certains champs venait à disparaître. Ensuite, il atteindra le point de terminaison d'exportation du projet, qui diffusera tous les documents accessibles dans le magasin de données en mémoire de Gatsby.

En d'autres termes, l'ensemble du site est construit avec deux requêtes. L'exécution du serveur de développement mettra également en place un écouteur qui transmettra en temps réel les modifications apportées par Sanity à Gatsby, sans effectuer de requêtes d'API supplémentaires. Si nous donnons au plugin source un jeton avec la permission de lire les brouillons, nous verrons les changements instantanément. Cela peut également être expérimenté avec Gatsby Preview.

Ajout d'un modèle de page de catégorie dans Gatsby

Maintenant que nous avons la définition du schéma GraphQL et du contenu prêt, nous pouvons plonger dans la création de modèles de page de catégorie dans Gatsby. Nous devons faire deux choses:

  • Dites à Gatsby de créer des pages pour les nœuds de catégorie (c'est le terme de Gatsby pour «documents»).
  • Donnez à Gatsby un fichier modèle pour générer le code HTML avec les données de la page.

Commencez par ouvrir le /web/gatsby-node.js fichier. Le code sera déjà là qui peut être utilisé pour créer les pages des articles de blog. Nous exploiterons largement ce code exact, mais pour les catégories. Prenons-le étape par étape:

Entre le createBlogPostPages fonction et la ligne qui commence par exports.createPages, nous pouvons ajouter le code suivant. J'ai mis des commentaires ici pour expliquer ce qui se passe:

// web/gatsby-node.js

// ...

async function createCategoryPages (graphql, actions) {
  // Get Gatsby‘s method for creating new pages
  const {createPage} = actions
  // Query Gatsby‘s GraphAPI for all the categories that come from Sanity
  // You can query this API on http://localhost:8000/___graphql
  const result = await graphql(`{
    allSanityCategory {
      nodes {
        slug {
          current
        }
        id
      }
    }
  }
  `)
  // If there are any errors in the query, cancel the build and tell us
  if (result.errors) throw result.errors

  // Let‘s gracefully handle if allSanityCatgogy is null
  const categoryNodes = (result.data.allSanityCategory || {}).nodes || ()

  categoryNodes
    // Loop through the category nodes, but don't return anything
    .forEach((node) => {
      // Desctructure the id and slug fields for each category
      const {id, slug = {}} = node
      // If there isn't a slug, we want to do nothing
      if (!slug) return

      // Make the URL with the current slug
      const path = `/categories/${slug.current}`

      // Create the page using the URL path and the template file, and pass down the id
      // that we can use to query for the right category in the template file
      createPage({
        path,
        component: require.resolve('./src/templates/category.js'),
        context: {id}
      })
    })
}

Enfin, cette fonction est nécessaire en bas du fichier:

// /web/gatsby-node.js

// ...

exports.createPages = async ({graphql, actions}) => {
  await createBlogPostPages(graphql, actions)
  await createCategoryPages(graphql, actions) // <= add the function here
}

Maintenant que nous avons la machinerie pour créer le nœud de page de catégorie en place, nous devons ajouter un modèle pour qu'il ressemble réellement dans le navigateur. Nous le baserons sur le modèle de publication de blog existant pour obtenir un style cohérent, mais restons assez simples dans le processus.

// /web/src/templates/category.js
import React from 'react'
import {graphql} from 'gatsby'
import Container from '../components/container'
import GraphQLErrorList from '../components/graphql-error-list'
import SEO from '../components/seo'
import Layout from '../containers/layout'

export const query = graphql`
  query CategoryTemplateQuery($id: String!) {
    category: sanityCategory(id: {eq: $id}) {
      title
      description
    }
  }
`
const CategoryPostTemplate = props => {
  const {data = {}, errors} = props
  const {title, description} = data.category || {}

  return (
    
      
        {errors && }
        {!data.category && 

No category data

}

Category: {title}

{description}

) } export default CategoryPostTemplate

Nous utilisons l'ID transmis dans le contexte dans gatsby-node.js pour interroger le contenu de la catégorie. Ensuite, nous l'utilisons pour interroger le title et description les champs qui sont sur le type de catégorie. Assurez-vous de redémarrer avec npm run dev après avoir enregistré ces modifications, et dirigez-vous vers localhost:8000/categories/structured-content dans le navigateur. La page devrait ressembler à ceci:

Une page de catégorie barebones avec un titre de site, un lien d'archive, un titre de page, un contenu factice et un droit d'auteur dans le pied de page.
Une page de catégorie barebones

Truc cool! Mais ce serait encore plus cool si nous pouvions réellement voir quels messages appartenant à cette catégorie, parce que, bien, c'est un peu le point d'avoir des catégories en premier lieu, non? Idéalement, nous devrions pouvoir interroger un champ «pages» sur l'objet catégorie.

Avant d’apprendre à cela, nous devons prendre du recul pour comprendre le fonctionnement des références de Sanity.

Interroger les références de Sanity

Même si nous ne définissons les références que dans un seul type, le magasin de données de Sanity les indexera «bidirectionnellement». Cela signifie que la création d'une référence au document de la catégorie «Contenu structuré» à partir d'un message permet à Sanity de savoir que la catégorie a ces références entrantes et vous empêchera de les supprimer tant que la référence existe (les références peuvent être définies comme «faibles» pour remplacer Ce comportement). Si nous utilisons GROQ, nous pouvons interroger des catégories et joindre des publications qui les ont comme ça (voir la requête et entraîner une action sur groq.dev):

*(_type == "category"){
  _id,
  _type,
  title,
  "posts": *(_type == "post" && references(^._id)){
    title,
    slug
  }
}
// alternative: *(_type == "post" && ^._id in categories()._ref){

Cela génère une structure de données qui nous permet de créer un modèle de publication de catégorie simple:

(
  {
    "_id": "39d2ca7f-4862-4ab2-b902-0bf10f1d4c34",
    "_type": "category",
    "title": "Structured content",
    "posts": (
      {
        "title": "Exploration powered by structured content",
        "slug": {
          "_type": "slug",
          "current": "exploration-powered-by-structured-content"
        }
      },
      {
        "title": "My brand new blog powered by Sanity.io",
        "slug": {
          "_type": "slug",
          "current": "my-brand-new-blog-powered-by-sanity-io"
        }
      }
    )
  },
  // ... more entries
)

C'est bien pour GROQ, qu'en est-il de GraphQL?

Voici le kicker: pour l'instant, ce type de requête n'est pas possible avec l'API GraphQL de Gatsby prête à l'emploi. Mais n'ayez crainte! Gatsby possède une puissante API pour changer son schéma GraphQL qui nous permet d'ajouter des champs.

En utilisant createResolvers pour modifier l'API GraphQL de Gatsby

Gatsby conserve tout le contenu en mémoire lors de la création de votre site et expose certaines API qui nous permettent d'exploiter la façon dont il traite ces informations. Parmi celles-ci figurent les API Node. Il est probablement bon de préciser que lorsque nous parlons de «nœud» dans Gatsby - à ne pas confondre avec Node.js. Les créateurs de Gatsby ont emprunté «bords et nœuds» à la théorie des graphes où les «bords» sont les connexions entre les «nœuds» qui sont les «points» où se trouve le contenu réel. Puisqu'un bord est une connexion entre des nœuds, il peut avoir une propriété «suivant» et «précédent».

Les bords avec le suivant et le précédent, et le nœud avec les champs dans l'explorateur d'API de GraphQL
Les bords avec le suivant et le précédent, et le nœud avec les champs dans l'explorateur d'API de GraphQL

Les API Node sont utilisées par les plugins avant tout, mais elles peuvent également être utilisées pour personnaliser le fonctionnement de notre API GraphQL. L'une de ces API est appelée createResolvers. C'est assez nouveau et cela nous permet de savoir comment les nœuds d'un type sont créés afin que nous puissions effectuer des requêtes qui leur ajoutent des données.

Utilisons-le pour ajouter la logique suivante:

  • Vérifiez ceux avec le SanityCategory tapez lors de la création des nœuds.
  • Si un nœud correspond à ce type, créez un nouveau champ appelé posts et réglez-le sur SanityPost type.
  • Ensuite, exécutez une requête qui filtre tous les articles contenant des listes d'une catégorie qui correspond à l'ID de la catégorie actuelle.
  • S'il existe des ID correspondants, ajoutez le contenu des nœuds de publication à ce champ.

Ajoutez le code suivant à la /web/gatsby-node.js fichier, en dessous ou au-dessus du code qui s'y trouve déjà:

// /web/gatsby-node.js
// Notice the capitalized type names
exports.createResolvers = ({createResolvers}) => {
  const resolvers = {
    SanityCategory: {
      posts: {
        type: ('SanityPost'),
        resolve (source, args, context, info) {
          return context.nodeModel.runQuery({
            type: 'SanityPost',
            query: {
              filter: {
                categories: {
                  elemMatch: {
                    _id: {
                      eq: source._id
                    }
                  }
                }
              }
            }
          })
        }
      }
    }
  }
  createResolvers(resolvers)
}

Maintenant, redémarrons le serveur de développement de Gatsby. Nous devrions être en mesure de trouver un nouveau champ pour les postes à l'intérieur du sanityCategory et allSanityCategory les types.

Une requête GraphQL pour les catégories avec le titre de la catégorie et les titres des articles appartenant

Ajout de la liste des publications au modèle de catégorie

Maintenant que nous avons les données dont nous avons besoin, nous pouvons revenir à notre modèle de page de catégorie (/web/src/templates/category.js) et ajoutez une liste avec des liens vers les articles appartenant à la catégorie.

// /web/src/templates/category.js
import React from 'react'
import {graphql, Link} from 'gatsby'
import Container from '../components/container'
import GraphQLErrorList from '../components/graphql-error-list'
import SEO from '../components/seo'
import Layout from '../containers/layout'
// Import a function to build the blog URL
import {getBlogUrl} from '../lib/helpers'

// Add “posts” to the GraphQL query
export const query = graphql`
  query CategoryTemplateQuery($id: String!) {
    category: sanityCategory(id: {eq: $id}) {
      title
      description
      posts {
        _id
        title
        publishedAt
        slug {
          current
        }
      }
    }
  }
`
const CategoryPostTemplate = props => {
  const {data = {}, errors} = props
  // Destructure the new posts property from props
  const {title, description, posts} = data.category || {}

  return (
    
      
        {errors && }
        {!data.category && 

No category data

}

Category: {title}

{description}

{/* If there are any posts, add the heading, with the list of links to the posts */} {posts && (

Posts

    { posts.map(post => (
  • {post.title}
  • )) }
) }
) } export default CategoryPostTemplate

Ce code produira cette page de catégorie simple avec une liste de messages liés - tout comme nous voulions!

La page de catégorie avec le titre et la description de la catégorie, ainsi qu'une liste de ses publications

Allez faire des pages de taxonomie!

Nous venons de terminer le processus de création de nouveaux types de page avec des modèles de page personnalisés dans Gatsby. Nous avons couvert l'une des API Node de Gatsby appelée createResolver et l'a utilisé pour ajouter un nouveau posts champ aux nœuds de catégorie.

Cela devrait vous donner ce dont vous avez besoin pour créer d'autres types de pages de taxonomie! Avez-vous plusieurs auteurs sur votre blog? Eh bien, vous pouvez utiliser la même logique pour créer des pages d'auteur. La chose intéressante avec le filtre GraphQL est que vous pouvez l'utiliser pour aller au-delà de la relation explicite faite avec les références. Il peut également être utilisé pour faire correspondre d'autres champs à l'aide d'expressions régulières ou de comparaisons de chaînes. C'est assez flexible!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *