diff --git a/gatsby-node.js b/gatsby-node.js
index 7688abe..92bd55f 100644
--- a/gatsby-node.js
+++ b/gatsby-node.js
@@ -1,3 +1,4 @@
+const _ = require('lodash')
const path = require('path')
const { createFilePath } = require('gatsby-source-filesystem')
@@ -14,6 +15,7 @@ exports.createPages = ({ boundActionCreators, graphql }) => {
slug
}
frontmatter {
+ tags
templateKey
}
}
@@ -26,10 +28,13 @@ exports.createPages = ({ boundActionCreators, graphql }) => {
return Promise.reject(result.errors)
}
- result.data.allMarkdownRemark.edges.forEach(edge => {
+ const posts = result.data.allMarkdownRemark.edges
+
+ posts.forEach(edge => {
const id = edge.node.id
createPage({
path: edge.node.fields.slug,
+ tags: edge.node.frontmatter.tags,
component: path.resolve(
`src/templates/${String(edge.node.frontmatter.templateKey)}.js`
),
@@ -39,6 +44,30 @@ exports.createPages = ({ boundActionCreators, graphql }) => {
},
})
})
+
+ // Tag pages:
+ let tags = []
+ // Iterate through each post, putting all found tags into `tags`
+ posts.forEach(edge => {
+ if (_.get(edge, `node.frontmatter.tags`)) {
+ tags = tags.concat(edge.node.frontmatter.tags)
+ }
+ })
+ // Eliminate duplicate tags
+ tags = _.uniq(tags)
+
+ // Make tag pages
+ tags.forEach(tag => {
+ const tagPath = `/tags/${_.kebabCase(tag)}/`
+
+ createPage({
+ path: tagPath,
+ component: path.resolve(`src/templates/tags.js`),
+ context: {
+ tag,
+ },
+ })
+ })
})
}
diff --git a/package.json b/package.json
index 92fa01b..68793f4 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,8 @@
"gatsby-source-filesystem": "^1.5.23",
"gatsby-transformer-remark": "^1.7.33",
"gatsby-transformer-sharp": "^1.6.21",
+ "lodash": "^4.17.5",
+ "lodash-webpack-plugin": "^0.11.4",
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-helmet": "^5.2.0"
diff --git a/src/cms/preview-templates/BlogPostPreview.js b/src/cms/preview-templates/BlogPostPreview.js
index ca3505a..7677323 100644
--- a/src/cms/preview-templates/BlogPostPreview.js
+++ b/src/cms/preview-templates/BlogPostPreview.js
@@ -6,6 +6,7 @@ const BlogPostPreview = ({ entry, widgetFor }) => (
)
diff --git a/src/layouts/all.sass b/src/layouts/all.sass
index 32e9e81..9e87d7b 100644
--- a/src/layouts/all.sass
+++ b/src/layouts/all.sass
@@ -7,6 +7,21 @@ $kaldi-red-invert: #fff
$primary: $kaldi-red
$primary-invert: $kaldi-red-invert
+.content .taglist
+ list-style: none
+ margin-bottom: 0
+ margin-left: 0
+ margin-right: 1.5rem
+ margin-top: 1.5rem
+ display: flex
+ flex-wrap: wrap
+ justify-content: left
+ align-items: center
+ li
+ padding: 0 2rem 1rem 0
+ margin-bottom: 1.5rem
+ margin-top: 0
+
// Helper Classes
.full-width-image-container
width: 100vw
diff --git a/src/pages/blog/2016-12-17-making-sense-of-the-scaas-new-flavor-wheel.md b/src/pages/blog/2016-12-17-making-sense-of-the-scaas-new-flavor-wheel.md
index 5d3036a..ca4b004 100644
--- a/src/pages/blog/2016-12-17-making-sense-of-the-scaas-new-flavor-wheel.md
+++ b/src/pages/blog/2016-12-17-making-sense-of-the-scaas-new-flavor-wheel.md
@@ -3,6 +3,9 @@ templateKey: blog-post
title: Making sense of the SCAA’s new Flavor Wheel
date: 2016-12-17T15:04:10.000Z
description: The Coffee Taster’s Flavor Wheel, the official resource used by coffee tasters, has been revised for the first time this year.
+tags:
+ - flavor
+ - tasting
---

diff --git a/src/pages/blog/2017-01-04-a-beginners-guide-to-brewing-with-chemex.md b/src/pages/blog/2017-01-04-a-beginners-guide-to-brewing-with-chemex.md
index 8889c48..f06dd8a 100644
--- a/src/pages/blog/2017-01-04-a-beginners-guide-to-brewing-with-chemex.md
+++ b/src/pages/blog/2017-01-04-a-beginners-guide-to-brewing-with-chemex.md
@@ -3,6 +3,9 @@ templateKey: blog-post
title: A beginners’ guide to brewing with Chemex
date: 2017-01-04T15:04:10.000Z
description: Brewing with a Chemex probably seems like a complicated, time-consuming ordeal, but once you get used to the process, it becomes a soothing ritual that's worth the effort every time.
+tags:
+ - brewing
+ - chemex
---

diff --git a/src/pages/blog/2017-01-04-just-in-small-batch-of-jamaican-blue-mountain-in-store-next-week.md b/src/pages/blog/2017-01-04-just-in-small-batch-of-jamaican-blue-mountain-in-store-next-week.md
index 9007f16..9f899b0 100644
--- a/src/pages/blog/2017-01-04-just-in-small-batch-of-jamaican-blue-mountain-in-store-next-week.md
+++ b/src/pages/blog/2017-01-04-just-in-small-batch-of-jamaican-blue-mountain-in-store-next-week.md
@@ -5,6 +5,11 @@ date: 2017-01-04T15:04:10.000Z
description: >-
We’re proud to announce that we’ll be offering a small batch of Jamaica Blue
Mountain coffee beans in our store next week.
+tags:
+ - jamaica
+ - green beans
+ - flavor
+ - tasting
---
We expect the shipment of a limited quantity of green beans next Monday. We’ll be offering the roasted beans from Tuesday, but quantities are limited, so be quick.
diff --git a/src/pages/tags/index.js b/src/pages/tags/index.js
new file mode 100644
index 0000000..06580a7
--- /dev/null
+++ b/src/pages/tags/index.js
@@ -0,0 +1,49 @@
+import React from 'react'
+import { kebabCase } from 'lodash'
+import Helmet from 'react-helmet'
+import Link from 'gatsby-link'
+
+const TagsPage = ({
+ data: { allMarkdownRemark: { group }, site: { siteMetadata: { title } } },
+}) => (
+
+
+
+
+
+
Tags
+
+ {group.map(tag => (
+ -
+
+ {tag.fieldValue} ({tag.totalCount})
+
+
+ ))}
+
+
+
+
+
+)
+
+export default TagsPage
+
+export const tagPageQuery = graphql`
+ query TagsQuery {
+ site {
+ siteMetadata {
+ title
+ }
+ }
+ allMarkdownRemark(limit: 1000) {
+ group(field: frontmatter___tags) {
+ fieldValue
+ totalCount
+ }
+ }
+ }
+`
diff --git a/src/templates/blog-post.js b/src/templates/blog-post.js
index c5de9e7..8437026 100644
--- a/src/templates/blog-post.js
+++ b/src/templates/blog-post.js
@@ -1,12 +1,15 @@
import React from 'react'
import PropTypes from 'prop-types'
+import { kebabCase } from 'lodash'
import Helmet from 'react-helmet'
+import Link from 'gatsby-link'
import Content, { HTMLContent } from '../components/Content'
export const BlogPostTemplate = ({
content,
contentComponent,
description,
+ tags,
title,
helmet,
}) => {
@@ -23,6 +26,18 @@ export const BlogPostTemplate = ({
{description}
+ {tags && tags.length ? (
+
+
Tags
+
+ {tags.map(tag => (
+ -
+ {tag}
+
+ ))}
+
+
+ ) : null}
@@ -46,7 +61,8 @@ const BlogPost = ({ data }) => {
content={post.html}
contentComponent={HTMLContent}
description={post.frontmatter.description}
- helmet={}
+ helmet={}
+ tags={post.frontmatter.tags}
title={post.frontmatter.title}
/>
)
@@ -69,6 +85,7 @@ export const pageQuery = graphql`
date(formatString: "MMMM DD, YYYY")
title
description
+ tags
}
}
}
diff --git a/src/templates/tags.js b/src/templates/tags.js
new file mode 100644
index 0000000..0879a7b
--- /dev/null
+++ b/src/templates/tags.js
@@ -0,0 +1,71 @@
+import React from 'react'
+import Helmet from 'react-helmet'
+import Link from 'gatsby-link'
+
+class TagRoute extends React.Component {
+ render() {
+ const posts = this.props.data.allMarkdownRemark.edges
+ const postLinks = posts.map(post => (
+
+
+ {post.node.frontmatter.title}
+
+
+ ))
+ const tag = this.props.pathContext.tag
+ const title = this.props.data.site.siteMetadata.title
+ const totalCount = this.props.data.allMarkdownRemark.totalCount
+ const tagHeader = `${totalCount} post${
+ totalCount === 1 ? '' : 's'
+ } tagged with “${tag}”`
+
+ return (
+
+
+
+
+
+
{tagHeader}
+
+
+ Browse all tags
+
+
+
+
+
+ )
+ }
+}
+
+export default TagRoute
+
+export const tagPageQuery = graphql`
+ query TagPage($tag: String) {
+ site {
+ siteMetadata {
+ title
+ }
+ }
+ allMarkdownRemark(
+ limit: 1000
+ sort: { fields: [frontmatter___date], order: DESC }
+ filter: { frontmatter: { tags: { in: [$tag] } } }
+ ) {
+ totalCount
+ edges {
+ node {
+ fields {
+ slug
+ }
+ frontmatter {
+ title
+ }
+ }
+ }
+ }
+ }
+`
diff --git a/static/admin/config.yml b/static/admin/config.yml
index 35d0a2b..020c0db 100644
--- a/static/admin/config.yml
+++ b/static/admin/config.yml
@@ -17,6 +17,7 @@ collections:
- {label: "Publish Date", name: "date", widget: "datetime"}
- {label: "Description", name: "description", widget: "text"}
- {label: "Body", name: "body", widget: "markdown"}
+ - {label: "Tags", name: "tags", widget: "list"}
- name: "pages"
label: "Pages"
diff --git a/yarn.lock b/yarn.lock
index 16707c1..2ceb48f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5761,6 +5761,12 @@ lodash-id@^0.14.0:
version "0.14.0"
resolved "https://registry.yarnpkg.com/lodash-id/-/lodash-id-0.14.0.tgz#baf48934e543a1b5d6346f8c84698b1a8c803896"
+lodash-webpack-plugin@^0.11.4:
+ version "0.11.4"
+ resolved "https://registry.yarnpkg.com/lodash-webpack-plugin/-/lodash-webpack-plugin-0.11.4.tgz#6c3ecba3d4b8d24b53940b63542715c5ed3c4ac5"
+ dependencies:
+ lodash "^4.17.4"
+
lodash._basecopy@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
@@ -5965,7 +5971,7 @@ lodash@3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
-lodash@4, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.4:
+lodash@4, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.4:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"