- Published on
タグの機能を実装してみる
- Authors
- Name
- Naoya 'noine' Sato
- @noineniya
公式サイトを参考に一通り実装してみる -> タグ毎の一覧ページはできたけどちょっと違う
カテゴリの実装例のブログがあったので真似してみる。graphQL の書き方がおかしくてうまくいかない。以前はそれで良かったのかも?そのブログ自体にも実装したと書いてあったけど機能していなかった
タグ機能を導入したというブログを見つけたので参考にしてみる。
自分の gatsby-node に合わせて記述してみる。Top ページのブログの表示と混ざっているけど、下記のようにしてみた。
title=gatsby-node.jsconst path = require(`path`) const _ = require("lodash") const { createFilePath } = require(`gatsby-source-filesystem`) exports.createPages = async ({ graphql, actions, reporter }) => { const { createPage } = actions const blogPost = path.resolve(`./src/templates/blog-post.js`) const tagTemplate = path.resolve(`./src/templates/tags.js`) const result = await graphql( ` { allMarkdownRemark( sort: { fields: [frontmatter___date], order: ASC } limit: 1000 ) { nodes { id fields { slug } } } tags: allMarkdownRemark(limit: 1000) { group(field: frontmatter___tags) { fieldValue } } } ` ) if (result.errors) { reporter.panicOnBuild( `There was an error loading your blog posts`, result.errors ) return } const posts = result.data.allMarkdownRemark.nodes if (posts.length > 0) { posts.forEach((post, index) => { const previousPostId = index === 0 ? null : posts[index - 1].id const nextPostId = index === posts.length - 1 ? null : posts[index + 1].id createPage({ path: post.fields.slug, component: blogPost, context: { id: post.id, previousPostId, nextPostId, }, }) }) } const tags = result.data.tags.group tags.forEach(tag => { createPage({ path: `/tags/${_.kebabCase(tag.fieldValue)}/`, component: tagTemplate, context: { tag: tag.fieldValue, }, }) }) }
今回のタグに関して記述した箇所は、
title=gatsby-node.jsconst _ = require("lodash") const tagTemplate = path.resolve(`./src/templates/tags.js`) tags: allMarkdownRemark(limit: 1000) { group(field: frontmatter___tags) { fieldValue } } const tags = result.data.tags.group tags.forEach(tag => { createPage({ path: `/tags/${_.kebabCase(tag.fieldValue)}/`, component: tagTemplate, context: { tag: tag.fieldValue, }, }) })
です。
まだまだ理解が浅いので、公式のハウツーガイドを読み込まなきゃなぁ。次にタグに関して表示するためのテンプレートページの作成。自分は src/templates に tags.js を作成。
title=tags.jsimport React from "react" import { Link, graphql } from "gatsby" import Bio from "../components/bio" import Layout from "../components/layout" import SEO from "../components/seo" const Tags = ({ location, pageContext, data }) => { const post = data.markdownRemark const siteTitle = data.site.siteMetadata?.title || `Title` return ( <Layout location={location} title={siteTitle}> <SEO title={pageContext.tag} /> <h1> {pageContext.tag} ({ data.allMarkdownRemark.totalCount}件) </h1> <ol style={{ listStyle: `none` }}> {data.allMarkdownRemark.edges.map(({ node }) => { return ( <li key={ node.fields.slug }> <article className="post-list-item" ></article> <header> <h2> <Link to={node.fields.slug} itemProp="url"> <span itemProp="headline">{node.frontmatter.title}</span> </Link> </h2> <small>{post.frontmatter.date}</small> </header> <section> <p dangerouslySetInnerHTML={{ __html: node.frontmatter.description || post.excerpt, }} itemProp="description" /> </section> </li> ) })} </ol> <hr /> <footer> <Bio /> </footer> </Layout> ) } export default Tags export const pageQuery = graphql` query($tag: String) { allMarkdownRemark( limit:1000 sort: { fields: [frontmatter___date], order: DESC } filter: { frontmatter: { tags: { in: [$tag] } } } ){ totalCount edges { node { fields { slug } frontmatter { title tags date description } } } } markdownRemark { id excerpt(pruneLength: 160) html frontmatter { title date(formatString: "MMMM DD, YYYY") description tags } } site { siteMetadata { title } } } `
今後変わっていく可能性が高いけど、今の所このサイトの作りとしてはこんな感じです。
トップページのテンプレートを参考にしてみました。
ですが global であてている css が効かなくて h1 の色が黒い…
おいおい読み込んでみますが、誰か教えて下さい〜!このテンプレートを表示させるために、各記事にタグを表示させます。自分はスターターをいじっているので blog-post.js というテンプレートで各投稿記事を表示させています。なのでそこに
import _ from "lodash"
<div className="tag-name-wrapper">
{tags.map(tag => {
return <Link className="blog-tag-name" to={`/tags/${_.kebabCase(tag)}/`}>{tag}</Link>
})}
</div>
div で囲っているのは色つけてるだけなんでお気になさらず。
lodash と kebabCase を理解していないので、これもそのうち勉強しなきゃ。
これで各投稿にタグが表示されて、そのタグのリンクをクリックすると gatsby-node に書かれた createPage によって tag.js で書いた「タグの記事一覧」が表示されます。
最初はカテゴリーを作成して、色々な投稿をした際に整理しやすくしようとしたんだけど、公式でもタグのことについての記事だったのでひとまずこれでいいかなと。
今後必要になったら同じ要領でやればいいかな。 少し graphQL について理解が進んだので良しとします。 ほいじゃ!