明日の自分のために

moon indicating dark mode
sun indicating light mode

GatsbyJSで作ったブログのフッターにタグを追加

June 09, 2020

タグを記事に表示するようにします。ここでは記事のフッターにその記事につけられているタグを付与します。

まず、タグを表示する部品を追加します。

src\gatsby-theme-blog\components\tag-label.js

import React, { Fragment } from "react"
import { Styled } from "theme-ui"
import { Link } from "gatsby"
import _ from "lodash"
const TagLabel = ({ tags }) => (
<Fragment style={{ marginTop: 20 }}>
タグ:
{tags.map((tag) => (
<Styled.a style={{ marginLeft: 10 }} as={Link} to={`/tags/${_.kebabCase(tag)}/`}>{tag}</Styled.a>
))}
</Fragment>
)
export default TagLabel

そして記事ページの下部にタグのリストを追加します。

src/gatsby-theme-blog/components/post.js

import React from "react"
import { MDXRenderer } from "gatsby-plugin-mdx"
import Layout from "gatsby-theme-blog/src/components/layout"
import SEO from "gatsby-theme-blog/src/components/seo"
import PostTitle from "gatsby-theme-blog/src/components/post-title"
import PostDate from "gatsby-theme-blog/src/components/post-date"
import PostFooter from "gatsby-theme-blog/src/components/post-footer"
import PostHero from "gatsby-theme-blog/src/components/post-hero"
import _ from "lodash"
import TagLabel from "./tag-label"
const Post = ({
data: {
post,
site: {
siteMetadata: { title },
},
},
location,
previous,
next,
}) => (
<Layout location={location} title={title}>
<SEO
title={post.title}
description={post.excerpt}
imageSource={
post.socialImage
? post.socialImage?.childImageSharp?.fluid.src
: post.image?.childImageSharp?.fluid.src
}
keywords={post.keywords}
imageAlt={post.imageAlt}
/>
<main>
<PostHero post={post} />
<PostTitle>{post.title}</PostTitle>
<PostDate>{post.date}</PostDate>
<MDXRenderer>{post.body}</MDXRenderer>
<TagLabel tags={post.tags} />
</main>
<PostFooter {...{ previous, next }} />
</Layout>
)
export default Post

それとタグの詳細を記事一覧と同じフォーマットに変更します。

src/templates/tag-detail.js

import React from "react"
import PropTypes from "prop-types"
import { Styled } from "theme-ui"
import Layout from "gatsby-theme-blog/src/components/layout"
import SEO from "gatsby-theme-blog/src/components/seo"
import PostLink from "gatsby-theme-blog/src/components/post-link"
// Components
import { Link, graphql } from "gatsby"
const TagDetail = ({ pageContext, data }) => {
const { tag } = pageContext
const { edges, totalCount } = data.allMdxBlogPost
const tagHeader = `${totalCount} post${
totalCount === 1 ? "" : "s"
} tagged with "${tag}"`
return (
<Layout location={`/tags/${tag}`} title={data.site.siteMetadata.title}>
<SEO title={`/tags/${tag}`} />
<Styled.h1>{tagHeader}</Styled.h1>
<Styled.ul>
{edges.map(({ node }) => {
return (
<PostLink key={node.slug} {...node} />
)
})}
</Styled.ul>
{/*
This links to a page that does not yet exist.
You'll come back to it!
*/}
<Link to="/tags">
<Styled.a>
All tags
</Styled.a>
</Link>
</Layout>
)
}
TagDetail.propTypes = {
pageContext: PropTypes.shape({
tag: PropTypes.string.isRequired,
}),
data: PropTypes.shape({
allMdxBlogPost: PropTypes.shape({
totalCount: PropTypes.number.isRequired,
edges: PropTypes.arrayOf(
PropTypes.shape({
node: PropTypes.shape({
title: PropTypes.string.isRequired,
slug: PropTypes.string.isRequired,
}),
}).isRequired
),
}),
}),
}
export default TagDetail
export const pageQuery = graphql`
query ($tag: String) {
site {
siteMetadata {
title
}
}
allMdxBlogPost(limit: 2000, sort: {fields: [date]}, filter: {tags: {in: [$tag]}}) {
totalCount
edges {
node {
title
slug
tags
date(formatString: "MMMM DD, YYYY")
excerpt
}
}
}
}
`
タグ:GatsbyJSblog-log