typememo.jp

gatsby-theme-blog タグページの追加方法

2020.08.31

#tech#gatsby

Contents


まとめ

本ページに足を運んでくださり,ありがとうございます!

お忙しい方はこの “まとめ” だけお読みいただければ幸いです.

  • Creating Tags Pages for Blog Posts をコピペする
  • コピペしたコードを適宜修正する
  • post.js にタグページへの Link タグを追加する

気になったらこの先も読み進めていただければと思います.

はじめに

gatsby-theme-blog でタグページを追加する方法についての紹介です.

基本的には gatsby 公式の Creating Tags Pages for Blog Posts に載っている手順を踏んでいます. でも手順通りに実装するとタグページを作ることはできません. 記事中にタグページへのリンクを貼ることもできませんし,そもそもタグページを生成できません.

え,じゃあダメじゃん.タグページ作れないじゃん.勘弁してよ.

と思った方のために,実際にタグページを作る方法を Creating Tags Pages for Blog Posts との差分を明らかにしながら紹介します! この記事の手順に従えば,タグページが出来上がるようにデザインしました. 筆者サイト特有の実装部分については割愛して紹介します. ご自身のサイトを実装するときは必要に応じて実装してください.

それでは,参りましょう!

まずはコピペする

まずは Creating Tags Pages for Blog Posts をコピペしましょう! Creating Tags Pages for Blog Posts に書かれていることをざっくりと要約すると,

  1. markdown のフロントマターに tags: [hogehoge] を追加する
  2. タグページのテンプレートを作成する
  3. gatsby-node.js にタグページを生成する
  4. タグ一覧ページを作成する

です.

コピペするのは以下の3ファイルです.

  • src/templates/tags.js
  • gatsby-node.js
  • src/pages/tags.js

3ファイルをコピペしたらこの先へお進みください.

コピペしたソースコードを修正する

src/templates/tags.js の修正内容

src/templates/tags.js に加えた修正は次の通りです.

// Components
import { Link, graphql } from "gatsby"
+import Layout from "gatsby-theme-blog/src/components/layout"
+import Footer from "gatsby-theme-blog/src/components/home-footer"

タグページを記事ページなどと同じレイアウトにするために LayoutFooter タグをインポートしています. Layout タグでタグページを囲わないとサイト全体の体裁が崩れますので必須ですね. Footer タグは最悪無くても構いません.

-const Tags = ({ pageContext, data }) => {
+const Tags = ({
+ pageContext,
+ data,
+ location,
+}) => {
const { tag } = pageContext

Layout タグの引数に location を渡す必要があるので定義しています.

return (
<div>
- <ul>
+ <Layout location={location} title={data.site.siteMetadata.title}>

Layout タグでタグページ全体を囲います.

- const { slug } = node.fields
+ const { slug } = node.frontmatter

node.fields は graphQL のクエリにありません. その代わり node.frontmatter を使います.

- </ul>
- {/*
- This links to a page that does not yet exist.
- You'll come back to it!
- */}
- <Link to="/tags">All tags</Link>
+ <Footer />
+ </Layout>
</div>
)
}

Layout タグで閉じます.

@@ -46,8 +78,6 @@
node: PropTypes.shape({
frontmatter: PropTypes.shape({
title: PropTypes.string.isRequired,
- }),
- fields: PropTypes.shape({
slug: PropTypes.string.isRequired,
}),
}),

node.fields はないので削除してしまいましょう.

@@ -61,6 +91,11 @@
export const pageQuery = graphql`
query($tag: String) {
+ site {
+ siteMetadata {
+ title
+ }
+ }
allMarkdownRemark(
limit: 2000
sort: { fields: [frontmatter___date], order: DESC }
@@ -69,14 +104,13 @@
totalCount
edges {
node {
- fields {
- slug
- }
frontmatter {
title
+ slug
}
}
}
}
}
`

graphQL に必要なクエリを書いています.

gatsby-node.js の修正内容

続いて gatsby-node.js に加えた修正は次の通りです.

- const blogPostTemplate = path.resolve("src/templates/blog.js")
const tagTemplate = path.resolve("src/templates/tags.js")

gatsby-node.js に記事を作成する処理が不要な方は削除してください. ちなみに筆者は必要ないので削除しました.

) {
edges {
node {
- fields {
- slug
- }
frontmatter {
tags
+ slug
}
}
}
@@ -38,16 +35,6 @@
return
}

node.fields.slug は無いので,node.frontmatter.slug に変更しました.

- const posts = result.data.postsRemark.edges
-
- // Create post detail pages
- posts.forEach(({ node }) => {
- createPage({
- path: node.fields.slug,
- component: blogPostTemplate,
- })
- })
-
// Extract tag data from query
const tags = result.data.tagsGroup.group

投稿記事を作成する処理は必要ないので削除しました.

src/pages/tags.js の修正内容

src/pages/tags.js の修正内容は次の通りです.

// Components
import { Helmet } from "react-helmet"
import { Link, graphql } from "gatsby"
+import Layout from "gatsby-theme-blog/src/components/layout"
+import Footer from "gatsby-theme-blog/src/components/home-footer"

LayoutFooter タグをインポートしました. 他のページと整合性を取るためです.

const TagsPage = ({
data: {
@@ -15,22 +18,38 @@
siteMetadata: { title },
},
},
+ location,
}) => (
+ <Layout location={location} title={title}>

Layout タグに必要な location をクエリに追加して,Layout タグで囲いました.

</div>
+ <Footer />
+ </Layout>
)
TagsPage.propTypes = {

Footer タグを追加して,Layout タグを閉じます.

以上でコピペしたソースコードの修正は完了です. 微調整は各自よろしくお願いします!

記事ページにタグを追加する

(optional) Render tags inline with your blog posts には記事ページにタグを追加するための具体的な方法は記載されていません.

ということで記事ページにタグを追加する一例を紹介します.

そのために src/gatsby-theme-blog/components/post.js に次の修正を加えます. もし post.js がない場合は,node_modules/gatsby-theme-blog/src/components/post.js をコピペでいいのでシャドーイングしてきてください.

@@ -38,6 +38,25 @@
<Flex>
<PostDate>{post.date}</PostDate>
+ <small>{
+ post.tags.map(tag => (
+ <Link to={`/tags/${tag}/`}>
+ #{tag}
+ </Link>
+ ))
+ }
+ </small>
</Flex>
<MDXRenderer>{post.body}</MDXRenderer>
</main>

実装内容は post.tags をループ処理して Link タグの to 属性に埋め込むだけです. Link タグは #{tag} として表示されます. 具体的には,本記事の冒頭部分を見ていただければと思います.

おわりに

以上,とても長くなりましたが gatsby-theme-blog にタグページとタグリンクを追加する方法の紹介でした.

筆者自身,

graphQL のクエリって何? createPage API って何? gatsby ってどうやってデータの受け渡ししてるんだ?

という感じで苦しみながらタグページを実装しました.

結果的にタグページが実装できたので良かったですが,正直言って絶望的に React とか諸々の知識が無くて投げ出す寸前でした. 何度も中断してコーヒー飲んで気持ちを切り替えて,机に向かって試行錯誤し続けました. とにかく最後まで実装し終えることは大事ですね. 今後も,やり切っていこうと思います.

もし良ければ OFUSE で支援していただけると,飛んで喜びます!

最後までお読みいただきありがとうございました!


山田 武尊 / 立教大学(理学) / ACCESS CO LTD