August 5th, 2020
タグ別に記事を表示するページを実装します。
タグページが生成されるようにページ生成処理を修正します。
タグの一覧を取得するクエリを作成します。開発環境を立ち上げてhttp://localhost:8000/___graphql
へアクセスするとGraphQLのエディタを使えます。タグの一覧が取れれば良いので以下のようなクエリを作りました。
query MyQuery {
allContentfulBlogPost {
group(field: tags) {
fieldValue
}
}
}
元から書かれていたブログ記事取得用のクエリと、タグ一覧取得用のクエリがマージできそうだったので、マージして以下のように変更しました。
{
allContentfulBlogPost {
group(field:tags) {
fieldValue
}
edges {
node {
title
slug
}
}
}
}
ページのtemplateをまだ作成していないので、一旦コンソールにタグを表示するコードを書いて動作確認をします。
const tags = result.data.allContentfulBlogPost.group
tags.forEach((tag, index) => {
console.log(tag.fieldValue)
})
この状態でyarn run dev
を実行してコンソールにタグの一覧が出力されれば成功です。
タグ付けされた記事の一覧を表示するページのテンプレートを作成します。ブログ一覧用のtsxファイルの中身をコピペしてからpageQueryを修正します。filterを付けて記事をタグで選択するようにしています。
query TagArticle($tag: String!) {
site {
siteMetadata {
title
}
}
allContentfulBlogPost(sort: { fields: [publishDate], order: DESC }, filter: {tags: {eq: $tag}}) {
edges {
node {
title
slug
publishDate(formatString: "MMMM Do, YYYY")
tags
heroImage {
fluid(maxWidth: 350, maxHeight: 196, resizingBehavior: SCALE) {
...GatsbyContentfulFluid_tracedSVG
}
}
description {
childMarkdownRemark {
html
}
}
}
}
}
}
`
タグをコンソールに出力していた部分をページ生成のコードへ直します。
const tagArticle = path.resolve('./src/templates/tag-article.tsx')
.
.
.
const tags = result.data.allContentfulBlogPost.group
tags.forEach((tag, index) => {
createPage({
path: `/tag/${tag.fieldValue}/`,
component: tagArticle,
context: {
tag: tag.fieldValue
},
})
})
これでタグ付けされた記事の一覧ページが完成です。
せっかく作ったタグページへの動線がないので、既存のタグ表示箇所をリンクに変えます。まずはコンポーネントを作成します。
import React from 'react'
import { Link } from 'gatsby'
const styles = require('./article-preview.module.css')
type Props = {
tag: string
}
const Component: React.FC<Props> = props => {
return (
<p className={styles.tag} key={props.tag}>
<Link to={`/tag/${props.tag}`}>{props.tag}</Link>
</p>
)
}
export default Component
あとは既存のタグ表示箇所をこのコンポーネントに置き換えれば無事ページ遷移もできるようになります。
{props.tags &&
props.tags.map(tag => (
<Tag tag={tag} />
))}