[React] Next.jsでブログ(会社HP)をつくるぞ!④postに付随するyaml情報を好きな形式に変更しよう

2022/12/03

Docker
React
Next.js

next.jsを使用して会社のHPを作成しています。

前回、remarkではなくzennのマークダウンファイルのパーサーを使用するように変更しました。

今回は、postに付随するyaml情報をいじってtagや関連記事を表示させるようにしていきます。

前回までの記事はこちら。

  1. [React] Next.jsでブログ(会社HP)をつくるぞ!①テンプレートを選んで、ローカルで起動しよう

  2. [React] Next.jsでブログ(会社HP)をつくるぞ!②blog-starterサンプル内の構成を理解しよう

  3. [React] Next.jsでブログ(会社HP)をつくるぞ!③markdownパーサーをzennに移行しよう

既存のyamlについて

既存のyamlには、titleexcerptcoverImagedateauthorogImageがあります。
postのサンプルの先頭を見るとこのようになっているはずです。

---
title: 'Dynamic Routing and Static Generation'
excerpt: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Praesent elementum facilisis leo vel fringilla est ullamcorper eget. At imperdiet dui accumsan sit amet nulla facilities morbi tempus.'
coverImage: '/assets/blog/dynamic-routing/cover.jpg'
date: '2020-03-16T05:35:07.322Z'
author:
  name: JJ Kasper
  picture: '/assets/blog/authors/jj.jpeg'
ogImage:
  url: '/assets/blog/dynamic-routing/cover.jpg'
---

今回修正したいのは以下の項目です。

  1. coverImageやogImageに画像を指定していますが、今回は画像を使用しないので削除します。
  2. tagというキーを追加して、その中にタグを配列で指定します。
  3. relatedPostSlugsというキーを追加して、その中に関連記事のslugを配列で指定します。
  4. releasedというキーを追加して、その中に記事を公開するかどうかをbooleanで指定します。
---
title: '[React] Next.jsでブログ(会社HP)をつくるぞ!その4'
excerpt: 'next.jsを使用して会社のHPを作成しています。今回は、postに付随するyaml情報をいじってtagや関連記事を表示させるようにしていきます。'
date: '2022/12/03'
author:
  name: Kenji
tags:
  - 'Docker'
  - 'React'
  - 'Next.js'
relatedPostSlugs:
  - 'next-create-blog-1'
  - 'next-create-blog-2'
  - 'next-create-blog-3'
released: true
---

それでは、これで対応できるようにlib/api.tsを修正していきます。

lib/api.tsの修正

今回修正する関数は、getPostBySlugです。

getAllPostsは、getPostBySlugを使用しているので、getPostBySlugを修正するとgetAllPostsも修正されます。
下記は、getPostBySlugの修正後のコードです。

lib/api.ts
const relatedPosts = (relatedPostNeeded) ? data['relatedPostSlugs']?.map((slug: string) => getPostBySlug(slug, ['title', 'slug', 'image', 'date', 'tags'], false)) : []

export function getPostBySlug(slug: string, fields: string[] = [], relatedPostNeeded: boolean = false) {
  const realSlug = slug.replace(/\.md$/, '')
  const fullPath = join(postsDirectory, `${realSlug}.md`)
  const fileContents = fs.readFileSync(fullPath, 'utf8')
  const image = `/assets/ogp/${realSlug}.webp`
  const { data, content } = matter(fileContents)
  const relatedPosts = (relatedPostNeeded) ? data['relatedPostSlugs']?.map((slug: string) => getPostBySlug(slug, ['title', 'slug', 'image', 'date', 'tags'], false)) : []

  type Items = {
    [key: string]: string
  }

  const items: Items = {}

  // Ensure only the minimal needed data is exposed
  fields.forEach((field) => {
    if (field === 'slug') {
      items[field] = realSlug
    }
    if (field === 'content') {
      items[field] = content
    }

    if (field === 'image') {
      items[field] = image
    }

    if (field === 'relatedPosts') {
      items[field] = relatedPosts
    }

    if (typeof data[field] !== 'undefined') {
      items[field] = data[field]
    }
  })

  return items
}

新たな引数として、relatedPostNeededを追加しています。
これは、関連記事を取得するかどうかを指定するためのものですが、これを追加しておかないと、関連記事の取得が無限ループになってしまいます。

また、relatedPostsの取得に関しては、relatedPostSlugsのslugを元に、getPostBySlugを再帰的に呼び出しています。

pages/posts/[slug].tsxの修正

今回上記のように画像をimageに統合したので、pages/posts/[slug].tsxを修正していきます。

pages/posts/[slug].tsx
      <Head>
        <title>
          {post.title} | 合同会社irori
        </title>
        <meta property="og:image" content={post.image} />
      </Head>

これで、OGP画像が表示されるようになりました。

タグの表示

次に、タグの表示を実装していきます。

タグの表示は以下のようにすれば大丈夫です。

pages/posts/[slug].tsx
{post.tags.map((tag) => (
  <div className="pr-2 pb-2" key={tag}>
    <Tag text={tag} />
  </div>
))}

これで、タグが表示されるようになりました。
関連記事についても同様のやり方で実装できます。

今日はこのあたりで。

Related Posts

[React] Next.jsでブログ(会社HP)をつくるぞ!①テンプレートを選んで、ローカルで起動しよう

[React] Next.jsでブログ(会社HP)をつくるぞ!①テンプレートを選んで、ローカルで起動しよう

[React] Next.jsでブログ(会社HP)をつくるぞ!②blog-starterサンプル内の構成を理解しよう

[React] Next.jsでブログ(会社HP)をつくるぞ!②blog-starterサンプル内の構成を理解しよう

[React] Next.jsでブログ(会社HP)をつくるぞ!③markdownパーサーをzennに移行しよう

[React] Next.jsでブログ(会社HP)をつくるぞ!③markdownパーサーをzennに移行しよう