Sergi
Sergi

Reputation: 1240

In Gatsby, using Wordpress as a data source, create different pages with different templates

I have a Gatsby site that is pulling data from another Wordpress site. It creates pages dynamically fine for posts but as soon as I add a new custom post type, it only creates pages for this one, but not the posts. So basically, it only creates pages for the latest post I add to the "gatsby-node.js" file. Which looks like this:

const path = require(`path`)
exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return graphql(`
    {
      allWordpressPost(sort: { fields: [date] }) {
        edges {
          node {
            title
            excerpt
            content
            slug
          }
        }
      }
    }
  `).then(result => {
    result.data.allWordpressPost.edges.forEach(({ node }) => {
      createPage({
        path: node.slug,
        component: path.resolve(`./src/templates/blog-post.js`),
        context: {
          // This is the $slug variable
          // passed to blog-post.js
          slug: node.slug
        },
      })
    })
  })
}

//Create a page for each Property Post type
exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return graphql(`
    {
      allWordpressWpProperty {
        edges {
          node {
            slug
            title
            content
            featured_media {
              localFile {
                childImageSharp {
                  original {
                    width
                    height
                    src
                  }
                  }
              }
            }
            acf {
              size
            }
          }
        }
      }
    }
  `).then(result => {
    result.data.allWordpressWpProperty.edges.forEach(({ node }) => {
      createPage({
        path: node.slug,
        component: path.resolve(`./src/templates/property.js`),
        context: {
          // This is the $slug variable
          // passed to property.js
          slug: node.slug
        },
      })
    })
  })
}

The error I get is "cannot read "page" of undefined when I try to visit a blog post. Is there a way to create pages for both?

Upvotes: 0

Views: 287

Answers (2)

Sergi
Sergi

Reputation: 1240

Ended up adding both queries under the same function and using the createPage function twice with the different results:

const path = require(`path`)
exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  return graphql(`
    query {
      allWordpressPost {
        edges {
          node {
            title
            excerpt
            slug
            link
          }
        }
      }

      allWordpressWpProperty {
        edges {
          node {
            slug
            title
            content
            featured_media {
              localFile {
                childImageSharp {
                  original {
                    width
                    height
                    src
                  }
                  }
              }
            }
            acf {
              size
            }
          }
        }
      }
    }
  `).then(result => {
    result.data.allWordpressPost.edges.forEach(({ node }) => {
      createPage({
        path: node.slug,
        component: path.resolve(`./src/templates/blog-post.js`),
        context: {
          // This is the $slug variable
          // passed to blog-post.js
          slug: node.slug
        },
      })
    });

    result.data.allWordpressWpProperty.edges.forEach(({ node }) => {
      createPage({
        path: node.slug,
        component: path.resolve(`./src/templates/property.js`),
        context: {
          // This is the $slug variable
          // passed to property.js
          slug: node.slug
        },
      })
    });
  })
}

Upvotes: 0

C Lindsay
C Lindsay

Reputation: 209

So I don't think you should be exporting createPages twice.

Instead export it once and create pages for both types of post in the same function. You could easily abstract both into their own separate async functions and await them in createPages, just to give you that separation so you know what pages are being created each step of the way.

Something like this:

import createBlogPosts from "../somewhere";
import createPropertyPosts from "../somewhere";

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;

  await createBlogPosts({ graphql, createPage });
  await createPropertyPosts({ graphql, createPage });
}

Upvotes: 2

Related Questions