Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to filter siteMetadata? #13989

Closed
karanrajpal14 opened this issue May 12, 2019 · 8 comments
Closed

How to filter siteMetadata? #13989

karanrajpal14 opened this issue May 12, 2019 · 8 comments
Labels
type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@karanrajpal14
Copy link

Summary

I seem to be unable to filter siteMetadata nodes. I've got a separate JSON file that has the content but I'm able to use filters on the allNavJson query.

Relevant information

Here's the JSON file:
src/content/nav.json

[
	{
		"label": "Home",
		"link": "/"
	},
	{
		"label": "Blog",
		"link": "/blog/"
	},
	{
		"label": "Projects",
		"link": "/projects/"
	}
]

The same JSON is present in gatsby-config.js as well like so:

module.exports = {
  siteMetadata: {
    ...
    nav: [
      {
        label: "Home",
        link: "/",
      },
      {
        label: "Blog",
        link: "/blog/",
      },
      {
        label: "Projects",
        link: "/projects/",
      },
    ],
  },
  plugins: [
	  ...
  ],
}

Here is the query I'm trying to run

query {
  allNavJson(filter: { label: { eq: "Projects" } }) {
    edges {
      node {
        label
      }
    }
  }
  allSite(
    filter: {
      siteMetadata: { nav: { elemMatch: { label: { eq: "Projects" } } } }
    }
  ) {
    edges {
      node {
        siteMetadata {
          nav {
            label
          }
        }
      }
    }
  }
}

And here is the output of the query

{
  "data": {
    "allNavJson": {
      "edges": [
        {
          "node": {
            "label": "Projects"
          }
        }
      ]
    },
    "allSite": {
      "edges": [
        {
          "node": {
            "siteMetadata": {
              "nav": [
                {
                  "label": "Home"
                },
                {
                  "label": "Blog"
                },
                {
                  "label": "Projects"
                }
              ]
            }
          }
        }
      ]
    }
  }
}

As you can see, the filter works just fine for the allNavJson query but doesn't work at all for the allSite query. Am I doing something wrong here? Any help would be appreciated. Thank you!

Environment (if relevant)

  System:
    OS: Linux 4.15 Ubuntu 16.04.6 LTS (Xenial Xerus)
    CPU: (4) x64 Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
    Shell: 5.1.1 - /bin/zsh
  Languages:
    Python: 2.7.12 - /usr/bin/python
  Browsers:
    Chrome: 74.0.3729.131
  npmPackages:
    gatsby: ^2.3.25 => 2.3.32 
    gatsby-image: ^2.0.40 => 2.0.40 
    gatsby-plugin-catch-links: ^2.0.13 => 2.0.13 
    gatsby-plugin-react-helmet: ^3.0.12 => 3.0.12 
    gatsby-plugin-remove-trailing-slashes: ^2.0.11 => 2.0.11 
    gatsby-plugin-sass: ^2.0.11 => 2.0.11 
    gatsby-plugin-sharp: ^2.0.35 => 2.0.35 
    gatsby-remark-images: ^3.0.10 => 3.0.11 
    gatsby-remark-relative-images: ^0.2.2 => 0.2.2 
    gatsby-source-filesystem: ^2.0.29 => 2.0.32 
    gatsby-transformer-json: ^2.1.11 => 2.1.11 
    gatsby-transformer-remark: ^2.3.8 => 2.3.12 
    gatsby-transformer-sharp: ^2.1.18 => 2.1.18 

File contents (if changed)

gatsby-config.js:

module.exports = {
  siteMetadata: {
    nav: [
      {
        label: "Home",
        link: "/",
      },
      {
        label: "Blog",
        link: "/blog/",
      },
      {
        label: "Projects",
        link: "/projects/",
      },
    ],
  },
  plugins: [
    "gatsby-plugin-react-helmet",
    "gatsby-plugin-sass",
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "src",
        path: `${__dirname}/src/`,
      },
    },
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "images",
        path: `${__dirname}/src/content/img/`,
      },
    },
    "gatsby-plugin-sharp",
    "gatsby-transformer-sharp",
    {
      resolve: "gatsby-transformer-remark",
      options: {
        plugins: [
          "gatsby-remark-relative-images",
          {
            resolve: "gatsby-remark-images",
            options: {
              maxWidth: 1000,
              linkImagesToOriginal: false,
            },
          },
        ],
      },
    },
    {
      resolve: "gatsby-transformer-json",
      options: {
        name: `data`,
        path: `${__dirname}/src/content/`,
      },
    },
    "gatsby-plugin-remove-trailing-slashes",
    "gatsby-plugin-catch-links",
  ],
}

package.json: N/A
gatsby-node.js: N/A
gatsby-browser.js: N/A
gatsby-ssr.js: N/A

@gatsbot gatsbot bot added the type: question or discussion Issue discussing or asking a question about Gatsby label May 12, 2019
@jonniebigodes
Copy link

@karanrajpal14 i've been testing this out all afternoon and i can confirm that the issue is present. Now upon some digging i'm inclined to believe that the issue you're experiencing is related to this and the subsequent feature request i might be wrong about it but it seems that this is the case. Now if you can elaborate on this matter, do you really need the two sources of truth? Do you really need to replicate both structures in both places? Based on the information at hand you could probably achieve what you want to achieve with only the json data in the file. But again this is based on the information you supplied, like i said if you can share more context we can probably offer a simpler solution for what you're trying to achieve.

@karanrajpal14
Copy link
Author

Thanks for the response @jonniebigodes. Okay I'll provide some context first. As you can tell, I'm trying to have my site's navigation links as a JSON just to make it easier to change. I then use this JSON in my header and footer components.

My initial attempt led me to creating a separate JSON file and then use the gatsby-transformer-json to query it. Later on, I realized that I could have the JSON within the siteMetadata in the config as it makes sense to keep it there and I could also remove gatsby-transformer-json and reduce my dependencies.

Additionally, I filter the nav links in and use it in my main page as a prefix to the slugs for navigation. It might be a tad overkill but it makes things a bit easier for me to change, if I need to. Is there any other way to filter the nav array within the metadata? I could just go on and use gatsby-transformer-json since it works but if this is a bug or my implementation is incorrect, I'd like to know.

I do not need two sources of truth. I'm trying to migrate from the gatsby-transformer-json implementation to something a tad bit simpler. That's it.

@jonniebigodes
Copy link

@karanrajpal14 if you don't mind a third option. You can import the JSON file directly to where you want and it will be processed by Gatsby and the underlying bundler webpack. With that you eliminate the plugin in question, solely based on the fact that you're using one file and also remove the extra content in gatsby-config.js file, leaving it to handle what's supposed to do. The JSON file will be picked up at build time and you can manipulate it as you wish. See here for a implementation of what i'm saying. That code is used on a pull request i'm currently working on.

@karanrajpal14
Copy link
Author

Hey @jonniebigodes, thank you for the sample. That does work for my current use case and I'll probably do it this way as I can shave off the dependency at least. I still am curious though, filtering the siteMetadata should work, correct? Is this a bug? Or is the current behaviour working as intended?

@jonniebigodes
Copy link

@karanrajpal14 to the best of my knowledge, technically not a bug, but a feature that is still not implemented, as you can see in the links i posted in my earlier comment. No need to thank, glad that i was able to offer you a alternative and see that the work you're doing will continue to progress.

@karanrajpal14
Copy link
Author

If that's the case then maybe @KyleAMathews or @jlengstorf can look into this and change the label accordingly as this a (low-priority) feature that I'd like to see, eventually. Thank you once again, @jonniebigodes!

@jonniebigodes
Copy link

@karanrajpal14 like i said before, no need to thank, just glad i was able to help you out

@jlengstorf
Copy link
Contributor

To clarify, site filters will find any site node that matches the filters. It isn't intended to filter the subfields of the node.

One way to solve this problem is to filter in your JS:

const nav = data.site.siteMetadata.nav;

nav.filter(navItem => /* whatever filter you need */);

Sub-filtering on field nodes probably won't get added as a default feature, but you can add this on your own using schema customization APIs.

Hope that helps! I'm going to mark this as closed, but please hit us up if you have additional questions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

3 participants