Multiple Post Type with MarkdownRemark
Asked Answered
I

4

5

I was wondering if I could have multiple post types in a gatsby static site.

On gatsby-config.js I have the following code.

{
resolve: `gatsby-source-filesystem`,
options: {
  path: `${__dirname}/content/books`,
  name: `books`,
}

{
resolve: `gatsby-source-filesystem`,
options: {
  path: `${__dirname}/content/posts`,
  name: `posts`,
}

Both the folders have relevant markdown files and I could not find any examples of graphql to retrieve both.

Thanks in advance.

Inconvenient answered 7/10, 2017 at 7:59 Comment(0)
H
5

Also see this (1) and this (2) issue/comment which clarifies things:

1.

In retrospect it was a mistake adding that field to gatsby-transformer-remark and will be removed in the future

2.

Using regex is a great solution as well which we use a lot on gatsbyjs.org for example.

Example: So this is the way to go in order to get only posts:

{
   allMarkdownRemark(
    sort: { order: DESC, fields: [frontmatter___date]},
    filter: {fileAbsolutePath: {regex: "/(\/content\/posts)/.*\\.md$/"}}
  ) {
      edges {
        node {
          excerpt(pruneLength: 250)
          id
          frontmatter {
            title
            date(formatString: "MMMM DD, YYYY")
            path
          }
        }
      }
    }
}
Hard answered 27/10, 2017 at 20:58 Comment(1)
"/(\/content\/posts)/.*\\.md$/" results in GraphQLError: Syntax Error: Invalid character escape sequence: \..Muscle
T
1

Once they are in grapqhl (via gatsby-source-filesystem) like you have it set up now, gatsby-transformer-remark will pull them all into the AllMarkdownRemark query, regardless of where they come from. The gatsbyjs.org docs do the same thing too, check the source here.

Try creating your query for the markdown content, as in part 4 of the official tutorial, and you should have access to all the pages from both folders. Now if you want to split them in some way, you'll have to do a check. See the gatsby-node.js file in the link above for an example on how that might look.

Tother answered 10/10, 2017 at 15:1 Comment(0)
A
0

Above solution will work. However there is another approach:

{
  allFile(sort: {order: DESC, fields: [name]}, filter: {internal: {mediaType: {eq: "text/markdown"}}, sourceInstanceName: {eq: "articles"}}) {
    edges {
      node {
        sourceInstanceName
        childMarkdownRemark {
          excerpt(pruneLength: 250)
          frontmatter {
            title
            date(formatString: "MMMM DD, YYYY")
          }
        }
      }
    }
  }
}
Asberry answered 8/4, 2018 at 9:1 Comment(2)
Can you describe in words what this approach does and why it solves the question?Banded
All these solutions come from a github issue in the gatsby repo. Basically one uses the allMarkdownRemark field exposed and the difference with allFile is that allMarkdown lets you also sort the md files returned, while with allFile you can't. The differences in terms of code is that allMarkdown returns all the md files we setup in gatsby-config and filters them based on a regex against the path (that includes the filename too). With allFile we query using the sourceInstanceName we set up in gatsby-config (under the name option).Steffaniesteffen
V
0

Considering your gatsby-config.js configuration

{
  resolve: `gatsby-source-filesystem`,
  options: {
    path: `${__dirname}/content/books`,
    name: `books`,
  }
}

Use your gatsby-node.js's onCreateNode hook to add a field to the MarkdownRemark object

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;
  if (node.internal.type === `MarkdownRemark`) {
    createNodeField({
      name: "_collectionType",
      node,
      value: getNode(node.parent).sourceInstanceName,
    })
  }
}

This gives you the ability to filter your document queries like this:

{
  allMarkdownRemark(filter: { _collectionType: { eq: "books" } }) {
     edges {
       node {
        frontmatter {
          title
          date(formatString: "MMMM DD, YYYY")
        }
        html
      }
    }
  }
}
Venturous answered 6/2, 2023 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.