見出し画像

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で見ると以下のような結果が返ってきます。

スクリーンショット 2021-11-13 10.15.53

MDXファイルで設定した3つのカテゴリーがあることがわかります。

result.errorはGraphQLのクエリーに問題があった時に、エラーを発生させてビルドを中止します。

categoriesはクエリーから取得したカテゴリーのリストを入れており、forEachでそれぞれのカテゴリーのページをcreatePageで作成する処理を行っています。

スクリーンショット 2021-11-13 10.20.14

createPageでは実際にページを作成します。pathで作成するページのURLを指定し、componentでページを作成するのに使うテンプレートを指定します。

このようにpathを設定することで、以下のようなアドレスでそれぞれのカテゴリーページにアクセスできるようになります。

http://localhost:8000/blogs/categories/カテゴリー名

contextは、この後作成するテンプレートで利用する値を渡しておきます。category.fieldValueにはカテゴリー名が入っています。この値をテンプレートで処理することで、カテゴリ名によって表示が変わるようにします。

あとはカテゴリーページのテンプレートを作成すれば、ページが生成されることになります。

Gatsbyでカテゴリーページの作成

gatsby-node.jsで利用するテンプレートのpathに、テンプレートを作成しましょう。以下のように設定していましたね。

スクリーンショット 2021-11-13 10.24.59

srcフォルダ内にtemplatesフォルダを作成し、その中にcategory.jsファイルを作成しましょう。

スクリーンショット 2021-11-13 9.38.50

そしてカテゴリーページのテンプレートを以下のように作成します。

# 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
         }
       }
     }
   }
 }
`

スクリーンショット 2021-11-13 10.32.24

先程、gatsby-node.jsでcontextに渡していたcategoryを、上記のようにして取り出すことができます。

スクリーンショット 2021-11-13 10.33.27

GraphQLではそのcategoryを利用して、そのカテゴリーに該当するMDXファイルをフィルターしています。

スクリーンショット 2021-11-13 10.35.31

最後にGraphQLで受け取った情報のedgesにそのカテゴリーのMDXファイルの情報があるので、記事へのリンクとタイトルを書き出しています。

これでローカル開発環境を実行して、アクセスしてみると以下の結果が表示されます。

http://localhost:8000/blogs/categories/マーケティング

スクリーンショット 2021-11-13 10.44.34

2番目と3番目の記事の日付をわざと逆にしたので、順番がちゃんと日付順になっていることがわかります。

http://localhost:8000/blogs/categories/開発

スクリーンショット 2021-11-13 10.45.55

http://localhost:8000/blogs/categories/データ分析

スクリーンショット 2021-11-13 10.46.11

マーケティングに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/

スクリーンショット 2021-11-13 11.00.21

実装結果

まとめ

ブログ記事にカテゴリーを追加することができました。同じようにすることで、例えば、ブログのサムネイルを追加したり、ブログ記事に関連のある記事を表示するなど、様々な応用方法があります。

ぜひ、いろいろ試してみてくださいね!


ここまで読んでいただけたなら、”スキ”ボタンを押していただけると励みになります!(*´ー`*)ワクワク


この記事が気に入ったらサポートをしてみませんか?