GatsbyJS で作ったブログに Category を追加する(.md)

2020-08-12

こんにちは、0371です。

mdファイルで書いているブログに、Categoryを追加しようと思ったけど、Graphqlでどういう風にやればいいのかわからなかったので、解法を備忘録として残しておきます。

必要なもの

  1. GatsbyJSで作った、mdファイルで記事を書くタイプのブログ
  2. GatsbyJSを触ったことのある記憶
  3. やる気、元気、ウッキウキ

追加方法

まずはgatsby-source-filesystemgatsby-transformer-remarkをインストールします。

yarn add gatsby-source-filesystem gatsby-transformer-remark

次にgatsby-config.jsgatsby-transformer-remarkgatsby-source-filesystemを追加します。

module.exports = {
/* Your site config here */
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `markdown`,
        path: `${__dirname}/content/blog/`, 
        // pathはmdファイルを置いているディレクトリを参照するようにしてね。
      },
    },
    `gatsby-transformer-remark`,
  ],
}
// 他の設定は省略してます。

gatsby-source-filesystemで指定したディレクトリに、任意のmdファイルを作成し、先頭行に以下のコードを差し込みます。

この---の間に記述したコードをFront matterと呼びます。
主に、ブログ記事の本文以外の情報をここに記述します。
titleなどの項目はタクソノミー (taxonomy)と呼ぶそうです。
タクソノミーの右側の値はターム (term)です。

---
+++
title: "GatsbyJS で作ったブログに Category を追加する(.md)"
+++
date: "2020-08-12"
---

タームを複数割り当てたい場合はこう書きます。

---
---

その後、Graphqlで以下のqueryを実行します。

export const query = graphql`
  query($slug: String!) {
    markdownRemark(frontmatter: { slug: { eq: $slug } }) {
      excerpt(format: PLAIN) // ブログ記事の概略 description
      html                   // ブログ記事の中身
      frontmatter {          // ここに差し込んだ情報が格納されている
        title                // ブログ記事タイトル
        date(formatString: "YYYY年MM月DD日") // 日付
        slug                 // 記事のURL部分
        category             // カテゴリー
      }
    }
  }
`

実際に見れるかどうかをgatsby developした後にhttp://localhost:8000/___graphqlで確かめてみてください。
これはブログ記事単体の場合です。

ちなみに、先ほどの2つのプラグインをインストールすることで、markdownRemarkを参照できるようになります。

実践編

各記事ごとのカテゴリーを呼び出すにはこうします。
適当にindex.jsを作り、以下をコピペしてみてください。

import React from "react"
import { graphql } from "gatsby"

const Home = ({ data }) => (
  <div>
    {data.allMarkdownRemark.edges.map(({ node }) => (
      <div>
        <p>タイトル: {node.frontmatter.title}</p>
        <p>日付: {node.frontmatter.date}</p>
        <p>記事URL: {node.frontmatter.slug}</p>
        <p>カテゴリー: {node.frontmatter.category}</p>
        <p>記事の説明: {node.excerpt}</p>
        <br />
      </div>
    ))}
    </div>
  
)
export const query = graphql`
  query {
    allMarkdownRemark (sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        node {
          frontmatter {
            title
            date(formatString: "YYYY年MM月DD日")
            slug
            category
          }
          excerpt
        }
      }
    }
  }
`
export default Home

ついでなので、いろんなものを表示させてみました。 記事ごとの場合は、markdownRemarkではなく、allMarkdownRemarkであることに注意しましょう。

記事単体の場合はこうします。
blogpost.jsなど、記事単体用のjsファイルがあると思うので、それを複製してから試してみてください。

import React from "react"
import { graphql } from "gatsby"

const Post = ({ data }) => (
  <div>
    <h1>{data.markdownRemark.frontmatter.title}</h1>
    <p>{data.markdownRemark.frontmatter.date}</p>
    <p>{data.markdownRemark.frontmatter.slug}</p>         
    <p>{data.markdownRemark.frontmatter.category}</p>
    <p>{data.markdownRemark.excerpt}</p>
    <br />
    <div dangerouslySetInnerHTML={{ __html: data.markdownRemark.html }} />
  </div>
)
export const query = graphql`
  query($slug: String!) {
    markdownRemark(frontmatter: { slug: { eq: $slug } }) {
      excerpt(format: PLAIN)
      html
      frontmatter {
        title
        date(formatString: "YYYY年MM月DD日")
        slug
        category
      }
    }
  }
`
export default Post

これで、必要な情報を取得できるはずです。

どうなってるの?

先ほどの

---
+++
title: "GatsbyJS で作ったブログに Category を追加する(.md)"
+++
date: "2020-08-12"
// 任意のタクソノミー: "任意のターム"
---

タクソノミータームを記述することで、{data.markdownRemark.frontmatter.任意のタクソノミー}を指定し、タームを取得することができます。

感想

Graphqlqueryallってついてるやつは、一覧で使う。
allってついてないやつは、単体で使うということがようやくわかった。

カテゴリー一覧は実装しないことにしました(白目)