Disable filter in GraphQL query

Viewed 38

I have a website in which I sort my photographs into different categories based on their sim. I then create different pages with MDX posts—

astia.mdx:

---
key: photography
title: Foto / Astia
sim: astia
---

I then grab the sim and use it as a variable filter, so that I dynamically create several categorical pages—

FilteredPhotoPageTemplate.jsx:

import React from "react"
import { graphql } from "gatsby"
import PhotoPageLayout from "@layouts/PhotoPageLayout"

export default function FilteredPhotoPageTemplate({ data }) {
  return (
    <PhotoPageLayout
      title={data.mdx.frontmatter.title}
      description={data.photoPagesMetadataYaml.description}
      photos={data.allPhotosYaml.nodes}
    />
  )
}

export const data = graphql`
  query ($id: String!, $sim: String) {
    mdx(id: { eq: $id }) {
      frontmatter {
        key
        title
        sim
      }
    }
    photoPagesMetadataYaml {
      description
    }
    allPhotosYaml(
      filter: { sim: { eq: $sim } }
      sort: { fields: date, order: DESC }
    ) {
      nodes {
        alt
        date
        id
        photo {
          childImageSharp {
            gatsbyImageData
          }
        }
        sim
        size
      }
    }
  }
`

However, I also want a category "index" page that shows all the photos. I'm therefore wondering: is it possible to "disable" this filter for a given MDX file? Or do I have to create a new page/template component with a different query (the current solution)? Because this seems inefficient.

Here are the relevant parts of gatsby-node.js:

const path = require("path")
const { createFilePath } = require("gatsby-source-filesystem")

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

  // define MDX post templates
  // ...
  const filteredPhotoPageTemplate = path.resolve(
    "./src/templates/FilteredPhotoPageTemplate.jsx"
  )

  // query basic template data for MDX posts and YAML photography pages
  const { data } = await graphql(`
    {
      allMdx {
        nodes {
          id
          fields {
            slug
          }
          internal {
            contentFilePath
          }
          frontmatter {
            key
            sim
          }
        }
      }
    }
  `)

  // create MDX pages using different page templates, based on frontmatter "key" values
  data.allMdx.nodes.forEach(node => {
    if (node.frontmatter.key === "plain") {
      // ...
    } else if (node.frontmatter.key === "blog") {
      // ...
    } else if (node.frontmatter.key === "photography") {
      createPage({
        path: node.fields.slug,
        component: `${filteredPhotoPageTemplate}?__contentFilePath=${node.internal.contentFilePath}`,
        context: {
          id: node.id,
          sim: node.frontmatter.sim,
        },
      })
    } else {
      // ...
    }
  })
}

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === "Mdx") {
    const value = createFilePath({ node, getNode })

    createNodeField({
      name: "slug",
      node,
      value,
    })
  }
}

Thanks!

1 Answers

You can just create a static query to get all photos without filtering them:

import { useStaticQuery, graphql } from "gatsby";

export const useAllPhotos = () => {
  const { allPhotosYaml } = useStaticQuery(
    graphql`
    allPhotosYaml {
      nodes {
        alt
        date
        id
        photo {
          childImageSharp {
            gatsbyImageData
          }
        }
        sim
        size
      }
    }
  }
`
  );
  return allPhotosYaml.nodes;
};

Then in the index or the file you want to import all photos:

import React from "react"
import { useAllPhotos } from "../hooks/use-all-photos"

export default function Home() {
  const photos = useAllPhotos ()
  console.log("all photos here", photos)

  return <h1>Loop to display the photos here</h1>
}
Related