初心者による初心者のためのGatsbyJS覚書11（カテゴリーページの作成）

#この記事について
この記事はGatsbyJS初心者の新卒２年目が作成しています。
参考資料として書籍を使用していますが、筆者がビギナークラスのため読んでいて「？」となる部分や間違っている箇所もあるかと思います。
参考までに、そして間違えている箇所がありましたらご連絡いただけると嬉しいです。

##Chapter11：カテゴリーページの作成　備忘録メモ

1.ブログ一覧ページをコピーしてカテゴリーページを作成する
2.カテゴリーページの見出しを調整する
3.カテゴリーページにアクセスできるよう設定する
※他のチャプターで記載しているメタデータの設定については割愛します。

###ブログ一覧ページをコピーしてカテゴリーページを作成する

まず、`blog-template.js`をコピーして`cat-template.js`を作成します。
そして`gatsby-node.js`にクエリを追加していきます。
また前回ブログ一覧を作成するときに追加したようにcreatePageを使用して
ページ作成に必要なパス、テンプレート、テンプレートに渡すコンテキストを指定していきます。

```js
exports.createPages = async({ graphql, actions, reporter }) => {
  const { createPage } = actions
  const blogresult = await graphql(`
  query {
    allContentfulBlogPost(sort: {fields: publishDate, order: DESC}) {
 　　　　・・・
　　　　　　//下記を追加
    allContentfulCategory {
      edges {
        node {
          categorySlug
          id
          category
          blogpost {
            title
          }
        }
      }
    }
  }
  `)

blogresult.data.allContentfulBlogPost.edges.forEach(({ node, next, previous }) => {
//略
  })
Array.from({length: blogPages}).forEach((_, i) => {
//略
  })

//下記を追加
  blogresult.data.allContentfulCategory.edges.forEach(({ node }) => {
    const catPostsPerPage = 6 //１ページに表示する記事の数
    const catPosts = node.blogpost.length //カテゴリーに属した記事の総数
    const catPages = Math.ceil(catPosts / catPostsPerPage) //カテゴリーページの総数

    Array.from({ length: catPages }).forEach((_, i) => {
      createPage({
        path:
          i === 0
            ? `/cat/${node.categorySlug}/`
            : `/cat/${node.categorySlug}/${i + 1}/`,
        component: path.resolve(`./src/templates/cat-template.js`),
        context: {
          catid: node.id,
          catname: node.category,
          catslug: node.categorySlug,
          skip: catPostsPerPage * i,
          limit: catPostsPerPage,
          currentPage: i + 1, //現在のページ番号
          isFirst: i + 1 === 1, //最初のページ
          isLast: i + 1 === catPages, //最後のページ
        },
      })
    })
  })
)
```
カテゴリーページではカテゴリーに属した記事のみをリストアップするため、
コンテキストで渡されるcategory　idを使用して記事にフィルターをかけます。
`cat-template.js`のクエリ文を下記の様に変更。

```js
export const query = graphql`
query($catid: String!, $skip: Int!, $limit: Int!){
  allContentfulBlogPost(
    sort: {order: DESC, fields: publishDate}
    limit: $limit
    skip: $skip
    //フィルターの条件を追加
    filter:{ category: { elemMatch: { id: { eq: $catid } } } }
  ) {
    edges {
      node {
        title
        id
        slug
        eyecatch {
          gatsbyImageData(width: 500, layout: CONSTRAINED)
          description
        }
      }
    }
  }
}
`
```
また、`cat-template.js`のページネーションリンクを設定している部分も
指定されているカテゴリーでページ遷移ができるように設定していきます。

```jsx
<ul class="pagenation">
  {!pageContext.isFirst && (
    <li class="prev">
        <Link to={
          pageContext.currentPage === 2
          ? `/cat/${pageContext.catslug}/`
          : `/cat/${pageContext.catslug}/${pageContext.currentPage -1}/`} rel="prev">
            <FontAwesomeIcon icon={faChevronLeft}/>
            <span>前のページ</span>
        </Link>
    </li>
    )}
    {!pageContext.isLast && (
    <li class="next">
      <Link to={`/cat/${pageContext.catslug}/${pageContext.currentPage + 1}/`} rel="next">
            <span>次のページ</span>
            <FontAwesomeIcon icon={faChevronRight}/>
      </Link>
    </li>
    )}
</ul>
```
###カテゴリーページの見出しを調整する

ブログ一覧では`RECENT POSTS`となっている見出しをカテゴリーページ用に変更します。

```jsx
    <section className="content bloglist">
      <div className="container">
        <h1 className="bar">CATEGORY: {pageContext.catname}</h1>
        <div className="posts">
   ・・・
```
![スクリーンショット 2021-09-28 0.25.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281399/e87aa52f-5fa7-5c2b-0ec6-05ef65bbf9e2.png)

###カテゴリーページにアクセスできるよう設定する
`blogpost-template.js`のカテゴリーリンクを編集します。
![スクリーンショット 2021-09-28 0.28.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281399/77afd8bf-1ba1-bbaa-07cd-65e7df0632d1.png)


```jsx
<ul>
  {data.contentfulBlogPost.category.map(cat => (
    <li className={cat.categorySlug} key={cat.id}>
      <Link to={`/cat/${cat.categorySlug}/`}>{cat.category}</Link>
    </li>
  ))}
</ul>
```

これにて全行程完成です。