Récupérer les liens de menu d'un site drupal

Récupérer les liens de menu d'un site drupal
14 octobre 2021

Source : https://www.gatsbyjs.com/plugins/gatsby-source-drupal-menu-links/

Pour retrouver les liens de menu de notre site Drupal dans Gatsby il va falloir ajouter deux modules contributifs à votre installation Drupal.

jsonapi_resources : https://www.drupal.org/project/jsonapi_resources jsonapi_menu_items : https://www.drupal.org/project/jsonapi_menu_items

Puis dans votre projet Gatsby il vous suffit de lancer la commande

yarn install gatsby-source-drupal-menu-links

Dans votre fichier gatsby-config.js insérer dans le tableau des plugins ces nouvelles valeurs :

{
  resolve: `gatsby-source-drupal-menu-links`,
  options: {
    baseUrl: `http://local.9.d9-test.com/`,
    apiBase: `jsonapi`, // optional, defaults to `jsonapi`
    menus: ["main", "footer"], // Which menus to fetch, there are the menu IDs.
  },
},

Dans mon cas vous comprendrez en lisant le code que je souhaite récupérer les menus "main" et "footer".

Ajoutez autant de menus que vous souhaitez qui sont disponibles sur votre installation Drupal.

Ensuite pour récupérer les liens d'un menu nous allons faire une nouvelle requête GraphQL.

Comme je souhaite ré-utiliser plusieurs fois mon menu principal sur plusieurs pages, je vais créer un composant NavBar.js qui s'occupera du rendu du menu principal.

Dans src/components je crée donc ce fichier NavBar.js

/* src/components/NavBar.js */

import React from "react";
import { StaticQuery, graphql } from "gatsby";

const NavBar = () => {
  return (
    <div className="container">
      <header className="d-flex justify-content-center py-3">
        <ul className="nav nav-pills">
          <StaticQuery
            query={graphql`
            query MainMenu {
              allMenuItems(filter: {menu_name: {eq: "main"}, enabled: {eq: true}}) {
                edges {
                  node {
                    title
                    url
                    expanded
                  }
                }
              }
            }
            `}
            render={data => (
              data.allMenuItems.edges.map(({ node }) => (
                <li className="nav-item" key={node.title}>
                  <a className="nav-link" href={node.url}>{node.title}</a>
                </li>
              ))
            )}
          />
        </ul>
      </header>
    </div>
  );
};
export default NavBar;

Vous remarquerez que cette fois si, je ne passe aucune valeur en paramètre de mon rendu. Je vais faire une requête statique pour éviter d'avoir à passer mes liens de menu en paramètre de chaque page.

Si vous vous demandez pourquoi utiliser une requête statique, voici la description de la classe StaticQuery :

StaticQuery can do most of the things that page query can, including fragments. The main differences are:

  • page queries can accept variables (via pageContext) but can only be added to page components
  • StaticQuery does not accept variables (hence the name "static"), but can be used in any component, including pages
  • StaticQuery does not work with raw React.createElement calls; please use JSX, e.g. <StaticQuery />

Désormais votre menu est utilisable sur toutes vos pages en important votre composant.