How to add support for multiple authors per page on GatsbyJS

By | Aug 4, 2019

While working on a Gatsby site, we have a requirement to provide support for multiple authors/contributors per page. We got this working by following the excellent Gatsby documentation Mapping node types. In this post, I will be describing the steps we followed.

Adding gatsby-transformer-yaml dependency using npm

Run this on your Gatsby project within the root directory.

npm install --save gatsby-transformer-yaml

Configuring the plugins

For this example, we are going to have a contributor.yaml file located at src/data.

- id: jane_doe 
  name: Jane Doe 
  twitter: jane_doe
  github: //github.com/jane_doe
  drupal: //www.drupal.org/u/jane_doe
  wordpress: //profiles.wordpress.org/jane_doe
  linkedin: //www.linkedin.com/in/jane_doe
  bio: CEO
- id: john_doe
  name: John Doe 
  twitter: john_doe
  linkedin: //www.linkedin.com/in/john_doe
  github: //github.com/john_doe
  bio: Technical Manager, Training and Certification

To make sure Gatsby can read this file, we need to have the gatsby-source-filesystem installed and configured to point to a path where our YAML files are.

plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/src/data`,
        name: `data`,
      },
    },
    `gatsby-transformer-yaml`,
]

Adding a map between the author field in frontmatter to the id in the contributor.yaml objects by adding to your gatsby-config.js:

mapping: {
  "Mdx.frontmatter.author": "ContributorYaml",
},

Fetching the data

After implementing this, we can fetch get all the linked authors per page using this GraphQL query.

export const pageQuery = graphql`
  query DocBySlug($slug: String!) {
    mdx(fields: { slug: { eq: $slug } }) {
      id
      code {
        body
      }
      fields {
        slug
      }
      frontmatter {
        title
        description
        getfeedbackform
        contributors {
          id
          name
          twitter
          bio
          avatar
          url
        }
        featuredcontributor
      }
      fileAbsolutePath
    }
  }
`

As you can see on this query, the property contributors within frontmatter contain each one the properties of the contributor relation even when is saved as an array of string values on the markdown file.

contributors: ['contributor-id']

Showing the contributor data

We created the Contributors component to render the data on the page template.

<Contributors contributors={contributors} />

this is the content of that component.

import React from 'react';
import { Link } from 'gatsby';

const Contributors = ({ contributors }) => {
 if (contributors == null || contributors.length < 1) {
  return null;
 }

 return (
  <React.Fragment>
   <p>
    <small>
     <i className="fa fa-users" /> Contributors:{' '}
     {contributors.map((contributor, i, arr) => {
      let lastCharacter = '.';
      if (arr.length - 1 !== i) {
       lastCharacter = ', ';
      }
      return (
       <React.Fragment key={i}>
        <Link to={`/contributors/${contributor.id}`} title={contributor.id}>
         {contributor.name}
        </Link>
        {lastCharacter}
       </React.Fragment>
      );
     })}
    </small>
   </p>
  </React.Fragment>
 );
};

export default Contributors;

Display all the posts by a contributor

Create a page template at src/templates/contributor.js and add the following GraphQL query to pull all of the posts by contributor/author. Theme as desired.

export const pageQuery = graphql`
  query ContributorById($id: String!) {
    contributorYaml(id: { eq: $id }) {
      id
      name
      avatar
      url
      github
      drupal
      wordpress
      twitter
      linkedin
    }
    allDocs: allMdx(
      filter: {
        frontmatter: { contributors: { elemMatch: { id: { eq: $id } } } }
      }
    ) {
      edges {
        node {
          id
          frontmatter {
            title
          }
          fields {
            slug
          }
        }
      }
    }
  }

In those queries, we are filtering the data using the id context variable.

Filtering the contributorYaml query by the contributor equal to the id

 contributorYaml(id: { eq: $id }) 

Filtering allDocs when the contributors frontmatter field matches and contains id in one of then values.

    allDocs: allMdx(
      filter: {
        frontmatter: { contributors: { elemMatch: { id: { eq: $id } } } }
      }
    ) 

Add a GraphQL query on create-node.js to pull all of the contributors

 allContributorYaml {
    edges {
         node {
             id
         }
     }
}

Create the contributor pages and passing the contributor id as a context variable.

const contributors = result.data.allContributorYaml.edges
contributors.forEach(contributor => {
     createPage({
         path: `contributors/${contributor.node.id}`,
        component: path.resolve(`./src/templates/contributor.js`),
         context: {
             id: contributor.node.id,
         },
     })
})

Are you interested in knowing more about GatsbyJS?

This series does not end here, so we invite you to visit our site frequently as we continue. We will be sharing some nice tips & tricks that we have learned during the development of this project. We will be sharing with you:

  • How to load templates based on your front-matter field.
  • How to create page navigation based on directory structure. How to use the parent directory as the base. Finally, how to show all of the children files as clickable links to separate pages.

So stay tuned and keep on learning with us. If you want to learn more about what we do and how we may help your business, don't think about it twice and reach out to us!

Tags:
LinkedIn
Reddit
WhatsApp

Related Posts

Gatsby YAML
How to create a text/markdown node to process content using Gatsby

By WeKnow | June 1, 2019

In this post, We will show you how you can consume markdown content from a JSON file to create a text/markdown node

Sometimes when building Gatsby sites, there is a need to consume and transform markdown content from a source that is not a markdown file…

- READ MORE
Gatsby YAML
How to embed React components in markdown using Gatsby, MDX, and short-codes

By WeKnow | June 4, 2019

In this post you will learn how to embed JSX/React components in Markdown using short-codes.

After finishing a project that involved migrating a Sculpin site to GatsbyJS using MDX to allow embeding React components in markdown files…

- READ MORE
Are you interested in knowing more about GatsbyJS and JAMstack?

We can provide support. Feel free to contact us, we will be more than glad to help you.

Contact Us