Instructor: Let's add the ability to browse all of our posts by tag. We're going to create a couple of new templates. Inside of source/templates, we'll create an all tags index.js and a single tag index.js. This file is our main home page index, which is this here.
Just for the sake of simplicity, we're going to make basically a copy of this for a tags page. We'll open up our all tags index template. We'll import React and link from Gatsby. We'll create a constant for our all tags template.
We'll go ahead and destructure data right now, because we know that we're going to eventually use it. For the time being, we'll just return a div with another div inside of it that will just save tags here for now.
Close these out. We'll export default all tags template. Our single tag index page will be pretty much the same. For the time being, we'll just copy that over to. Now, let's open up gatsby-node.js. We're going to write a new function called createTagPages.
As parameters, createTagPages will take createPage which we'll pass in as well as the list of posts. Similar to what we did down here on line 11 where we bring in our blogPostTemplate, we're going to do that here. We'll do const all tags index template equals path.result, and we'll aim this at our template.
Similarly, here we'll do our single tag index template. The technique that we're going to use here is, we're going to create an empty object called posts by tag, and the idea here is that we'll dynamically create a key for each of our tags. Each of those keys will have an array of the posts that use that tag.
It will make more sense in a second. What we'll do is, we'll do posts.forEach. Like usual, we're going to destructure the node. If there are tags in the node, so if node.frontmatter.text, we're going to process each of them. We'll do node.frontmatter.text.forEach. Bring this in its tag.
Now we're going to check, if posts by tag does not have this tag as a key. We'll create it. If there is not posts by tag with the tag as a key, we'll set it to be an empty array and we'll push on the node, and a typo here.
After we've called this forEach on all of our posts, we should have a built up object that has each of our tags represented with an array of nodes for each one. Now, we'll create a master list of all of the tags. We'll do const tags equals object.keys posts by tag.
Now, we'll call createPage. Our path will be /tags. The component will be the all tags index template. The context that we're going to pass will be called tags and it will be tags.sort, so this will be a sorted list of all of our tags.
At this point, with this createPage call in place, we need to actually call this function. Down here in our main createPage that we've written earlier, we have our variable for posts, which is all of our Markdown posts.
Now before we process each of our posts, we're going to call our createTagPages function with our createPage action and all the posts that we created.
Since I've updated gatsby-node.js, I need to restart gatsby develop. I have that running in a separate tab by the way. Now on our /tags page, I can hit reload, and we see tags here from our template, which is good. That means that our tags page is being created.
Let's go ahead and open our all tags index template. Now let's console.log our data, actually this will be under pageContext is what this gets passed to from gatsby-node.js. Data is what's used for a query that would be inside of this template and pageContext is what gets passed from gatsby-node.js.
I need a console.log pageContext. We have tags with an empty array. That must mean that I don't have any tags coming through. Ah! The reason why I don't have any tags coming through is, because in my markdown query, I'm only grabbing a path title and text.
Since I have updated gatsby-node.js, I have to rerun gatsby develop. Reload this. Now we see that, we have some tags coming through here. The three tags that I have in my demo markdown files are this, that, and the other obviously in alphabetical order instead.
Just to recap what's going on here, this is our main createPages export. What we're doing here is we're looking for all of the Markdown files inside of the source/pages directory. I've added tags down here, that way we actually are returning tags from our query that we search for.
The result of our query are passed down to this then. We're calling our createTagPages function which is creating this index of all tags.