PersonalAugust 26, 2018
Calendar for gatsby
Posted by
Łukasz Marek SielskiRelated reading
I've just updated my blog by adding something that is essential for traditional blogging: chronological indexing.
Won't spend much time explaining as you may see this messy blog source code on my GitHub
Idea
-
Need to added field
frontmatter.yearWithMonth
to the page- That can be done by various plugins or simply in
onCreateNode
of/gatsby-node.js
(see on GitHub)
gatsby-node.js
// .. // Create slugs for files. // Slug will used for blog page path. exports.onCreateNode = ({ node, actions, getNode }) => { // ... // exptract date elements for indexing // yearWithMonth allows concatenation otherwise difficult/impossible while // graphql aggregation/filtering if (node.frontmatter && node.frontmatter.updatedDate) { const parts = node.frontmatter.updatedDate.split('-') node.frontmatter.year = parts[0] node.frontmatter.month = parts[1] node.frontmatter.day = parts[2] node.frontmatter.yearWithMonth = parts.slice(0, 2).join('-') } // ... }
- That can be done by various plugins or simply in
-
Can query by that field to show year/month pages
- You can add that query to any page you want to show calendar on (see on GitHub)
# Get calendar calendar: allMarkdownRemark { group(field: frontmatter___updatedDate) { fieldValue totalCount } }
- Also you can create component printing list of months like categories (see on GitHub)
-
You can build pages for each month by groupingby newly created field
- That can be done using
createPages
of/gatsby-node.js
(Example on GitHub)
exports.createPages = ({ graphql, actions }) => { const { createPage } = actions return new Promise((resolve, reject) => { // added monthsPage to the templates const templates = ['blogPost', 'tagsPage', 'blogPage', 'monthsPage'].reduce( (mem, templateName) => { return Object.assign({}, mem, { [templateName]: path.resolve( `src/templates/${kebabCase(templateName)}.jsx` ), }) }, {} ) // added yearWithMonth to frontmatter graphql( ` { posts: allMarkdownRemark { edges { node { fields { slug } frontmatter { tags yearWithMonth } } } } } ` ).then(result => { if (result.errors) { return reject(result.errors) } const posts = result.data.posts.edges.map(p => p.node) // ... // Create months pages posts .reduce( (mem, post) => cleanArray(mem.concat(get(post, 'frontmatter.yearWithMonth'))), [] ) .forEach(month => { createPage({ path: `/blog/months/${kebabCase(month)}/`, component: slash(templates.monthsPage), context: { month, }, }) }) resolve() }) }) }
- That can be done using