Getting started with GridSome and Drupal 8

One of my biggest gripes about Drupal is how complicated it can be to do a simple task. Drupal 8’s JSON API has made giant gains in having a pretty close to “out of the box” solution for a robust JSON API. With GridSome, you barely even need to know how to use Drupal. GridSome magically exposes the data from the JSON API to Vue pages/components by writing GraphQL queries.

The finished prototype

I’m going to assume that you already somewhat know what GridSome and Drupal 8 are and/or you are a good Googler, so let’s get going.

The “Getting Started” section of the GridSome docs is fantastic and succinct for getting up and running. You can find most of the info here within the GridSome docs and the source-drupal plugin docs, but this is my approach and a step by step on how to get a basic site up and running.

First, install the global CLI for GridSome, use the gridsome CLI to create a new project, cd into that directory and run gridsome develop

npm install --global @gridsome/cli
gridsome create my-gridsome-site
cd my-gridsome-site
npm install @gridsome/source-drupal
gridsome develop

At this point if all is well, you can open up http://localhost:8080 and the starter site should be there.

Let’s get Drupal-y

For this post, I’m going to use the default data that comes with the repo, which can be found referenced in the official docs:

baseUrl: 'https://dev-cctd8.pantheonsite.io'

This Drupal site has the JSON API turned on and has a bunch of fake articles generated. I’m going to grab a list of articles from the Drupal site’s JSON API, list them out, then make the title clickable to go to a single article page.

Configure the options

Open up gridsome.config.js and add:

// default exclude can be imported
const { defaultExcludes } = require('@gridsome/source-drupal')

module.exports = {
  plugins: [
    {
      use: '@gridsome/source-drupal',
      options: {
        baseUrl: 'https://dev-cctd8.pantheonsite.io',
        exclude: [ ...defaultExcludes, 'user--user' ], // include the defaults
        routes: {
          'node--article': '/articles/:slug',
          'taxonomy_term--tags': '/tags/:slug'
        }
      }
    }
  ]
}

After adding this, remember that you have to Ctrl + C the terminal you ran gridsome develop in and re-run gridsome develop so the new config becomes active.

Get data from Drupal

There’s going to be two queries that have to happen, one in the page template that grabs all of the articles, then a single article query.

In this page, I’m using a quick and dirty page query and then using the global $page variable that is magically exposed for me to use in the <template>. For the single article template, I’m going to use a different method.

For the page query I’m going to open up src/pages/Index.vue and add the following (keep the existing <script> and <style> tags):

<template>
  <Layout>
    <h1>Gridsome + Drupal 8</h1>
    <div v-for="edge in $page.articles.edges" :key="edge.node.id">
      <h2><g-link :to="`${edge.node.path}`">{{ edge.node.title }}</g-link></h2>
      <img :src="`https://dev-cctd8.pantheonsite.io${edge.node.fieldImage.uri.url}`">
      <div v-html="edge.node.body.processed"></div>
    </div>    
  </Layout>
</template>

<page-query>
  query Articles {
    articles: allDrupalNodeArticle (perPage:100) {
      edges {
        node {
          id,
          title,
          slug,
          path,
          body {
            processed
          },
          fieldImage {
            title,
            filename,
            uri {
              url
            }
          },
        }
      }
    }
  }
</page-query>

So, now the index page of the site has a list of articles.

GridSome pulling a list of articles from Drupal 8

Next, we need to make the single page template. Digging around the project, I found this message in the src/templates folder:

Templates for **GraphQL collections** should be added here. To create a template for a collection called `WordPressPost`create a file named `WordPressPost.vue` in this folder.

Learn more: https://gridsome.org/docs/templates

The templates in this folder determine how collections are templated. By using the “schema” tab in the GraphQL explorer that comes with the project, you can view which collections are available.

Example of using the GraphQL explorer.

In the GraphQL explorer, there is a DrupalNodeArticle schema, so within /src/templates, make a DrupalNodeArticle.vue file. Here’s mine:

<template>
  <Layout>
    <div class="article">
      <h1>{{$page.drupalNodeArticle.title}}</h1>
      <img :src="`https://dev-cctd8.pantheonsite.io${$page.drupalNodeArticle.fieldImage.uri.url}`">
      <div v-html="$page.drupalNodeArticle.body.processed"></div>
    </div>
  </Layout>
</template>


<page-query>
  query Article ($path: String!) {
    drupalNodeArticle (path: $path) {
      title,
      date,
      slug,
      body {
        processed
      },
      fieldImage {
        title,
        filename,
        uri {
          url
        }
      },
      fieldTags {
        name,
        path
      }
    }
  }
</page-query>

<script>
    export default {
        
    }
</script>

<style scoped>
.article {
    max-width: 900px;
    margin: auto;
}
</style>

This doesn’t take into account many things, but it should fill in some gaps and help get you up and running pretty quick.

Leave a comment

What do you think?

%d bloggers like this: