Gatsbyブログにカテゴリやタグを追加する
ブログの記事が増えてくると、読みたい分野の記事を探すのが大変になってきます。そうなると記事をカテゴリごとに分類して、整理しておきたいと思いますよね。
Gatsbyウェブサイトに訪れたユーザーも、興味のあるカテゴリの記事をまとめて読めるようになるので、利便性が高くなること間違いなしです。
今回はブログ記事に、カテゴリを追加して記事を読めるようにしましょう。これと同じようにすれば、ブログ記事に好きな情報を追加して、さまざまな使い方ができるようになるでしょう。
ブログ記事のMDXファイルの準備
まずは、ブログ記事の情報源となっているMDXファイルに、カテゴリ情報を追加する必要があります。今回は"マーケティング"、"開発"、"データ分析"の3つのカテゴリを作りましょう。
blog1.mdxからblog6.mdxまでの6つのファイルを作成し、blog1〜3は "マーケティング"、blog4〜5は"開発"、blog6を"データ分析"とします。
例えばblog1.mdxは以下のようになります。frontmatterにcategoryの項目を追加し、"マーケティング"というカテゴリーを設定しました。
せっかくなので投稿日(date)も一緒につけてしまいましょう。これによって投稿日順にブログを表示することなどができるようになります。
# blogs/blog1.mdx
---
title: "これは最初の記事です"
date: "2021-10-05"
category: "マーケティング"
---
はじめまして!
これは僕の初めてのブログ記事です
こうやって**強調**することもできますよ。
これをblog2〜6.mdxで同じように繰り返します。
gatsby-node.jsの設定変更
gatsby-node.jsはGatsbyウェブサイトをビルドする時に、一度だけ呼ばれるファイルです。この中でGatsbyのAPIを利用することで、新しいページを動的に作成したりすることができます。
gatsby-node.jsで利用できるAPIは以下リンク先に一覧があります。
今回はこの中のcreatePagesを利用します。
まずはgatsby-node.jsを以下のように変更します。
# gatsby-node.js
const path = require("path")
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions
const categoryTemplate = path.resolve("src/pages/category/category.js")
const result = await graphql(`
{
categoryGroup: allMdx {
group(field: frontmatter___category) {
fieldValue
}
}
}
`)
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`)
return
}
const categories = result.data.categoryGroup.group
categories.forEach(category => {
createPage({
path: `/blogs/categories/${category.fieldValue}/`,
component: categoryTemplate,
context: {
category: category.fieldValue,
},
})
})
}
categoryTemplateはページを作る時に、どのテンプレートを利用するかを指定しています。テンプレートはこの後作成します。
resultでは、GraphQLを利用して、現在Gatsbyウェブサイト上にあるカテゴリーの一覧を取得しています。GraphiQLで見ると以下のような結果が返ってきます。
MDXファイルで設定した3つのカテゴリーがあることがわかります。
result.errorはGraphQLのクエリーに問題があった時に、エラーを発生させてビルドを中止します。
categoriesはクエリーから取得したカテゴリーのリストを入れており、forEachでそれぞれのカテゴリーのページをcreatePageで作成する処理を行っています。
createPageでは実際にページを作成します。pathで作成するページのURLを指定し、componentでページを作成するのに使うテンプレートを指定します。
このようにpathを設定することで、以下のようなアドレスでそれぞれのカテゴリーページにアクセスできるようになります。
http://localhost:8000/blogs/categories/カテゴリー名
contextは、この後作成するテンプレートで利用する値を渡しておきます。category.fieldValueにはカテゴリー名が入っています。この値をテンプレートで処理することで、カテゴリ名によって表示が変わるようにします。
あとはカテゴリーページのテンプレートを作成すれば、ページが生成されることになります。
Gatsbyでカテゴリーページの作成
gatsby-node.jsで利用するテンプレートのpathに、テンプレートを作成しましょう。以下のように設定していましたね。
srcフォルダ内にtemplatesフォルダを作成し、その中にcategory.jsファイルを作成しましょう。
そしてカテゴリーページのテンプレートを以下のように作成します。
# src/templates/category.js
import React from "react"
import { Link, graphql } from "gatsby"
const Categories = ({ pageContext, data }) => {
const { category } = pageContext
const { edges, totalCount } = data.allMdx
const categoryHeader = `${category}カテゴリーで${totalCount}個の記事が見つかりました。`
return (
<div>
<h1>{categoryHeader}</h1>
<ul>
{edges.map(({ node }) => {
const { slug } = node.fields
const { title } = node.frontmatter
return (
<li key={slug}>
<Link to={"/blogs/"+slug}>{title}</Link>
</li>
)
})}
</ul>
<Link to="/blogs/categories/">カテゴリーページに戻る</Link>
</div>
)
}
export default Categories
export const pageQuery = graphql`
query($category: String) {
allMdx(
limit: 2000
sort: { fields: [frontmatter___date], order: DESC }
filter: { frontmatter: { category: { in: [$category] } } }
) {
totalCount
edges {
node {
slug
frontmatter {
title
}
}
}
}
}
`
先程、gatsby-node.jsでcontextに渡していたcategoryを、上記のようにして取り出すことができます。
GraphQLではそのcategoryを利用して、そのカテゴリーに該当するMDXファイルをフィルターしています。
最後にGraphQLで受け取った情報のedgesにそのカテゴリーのMDXファイルの情報があるので、記事へのリンクとタイトルを書き出しています。
これでローカル開発環境を実行して、アクセスしてみると以下の結果が表示されます。
http://localhost:8000/blogs/categories/マーケティング
2番目と3番目の記事の日付をわざと逆にしたので、順番がちゃんと日付順になっていることがわかります。
http://localhost:8000/blogs/categories/開発
http://localhost:8000/blogs/categories/データ分析
マーケティングに3つ、開発に2つ、データ分析に1つ記事がありますね。
実装結果
最後に[カテゴリーページに戻る]のリンク先がないので作っておきましょう。
Gatsbyでカテゴリー一覧ページを作る
カテゴリーの一覧ページは、以下のアドレスになるので、src/pages/blogsフォルダに、categories.jsを作成します。
http://localhost:8000/blogs/categories/
一覧ページはこれまでやったことの繰り返しですので、詳しい説明は省きます。GraphQLでカテゴリーの一覧をgroupで取得し、それをLinkに渡しているだけです。
# src/pages/blogs/categories.js
import React from "react"
import { Link, graphql } from "gatsby"
const CategoryList = ({ data }) => {
const { categories } = data.allMdx
return (
<div>
<h1>カテゴリ一覧</h1>
<ul>
{categories.map( category => {
return (
<li key={category.fieldValue}>
<Link to={category.fieldValue}>{category.fieldValue}</Link>
</li>
)
})}
</ul>
</div>
)
}
export default CategoryList
export const pageQuery = graphql`
query{
allMdx{
categories: group (field: frontmatter___category){
fieldValue
}
}
}
`
これを実行すると以下のようにカテゴリー名が一覧になって表示され、各カテゴリーのページにアクセスできるようになりました。
http://localhost:8000/blogs/categories/
実装結果
まとめ
ブログ記事にカテゴリーを追加することができました。同じようにすることで、例えば、ブログのサムネイルを追加したり、ブログ記事に関連のある記事を表示するなど、様々な応用方法があります。
ぜひ、いろいろ試してみてくださいね!
ここまで読んでいただけたなら、”スキ”ボタンを押していただけると励みになります!(*´ー`*)ワクワク
この記事が気に入ったらサポートをしてみませんか?