はじめに
前回に引き続き、開発環境にマークダウン形式の記事を保存し、Gatsbyで取得する方法を確認する。
今回は取得したファイルの中身(マークダウン形式)を取得して、解析して最終的にHTMLに変換して表示する方法を確認する。
ここまで参考にしてきたGatsby公式チュートリアルと、gatsby-starter-blogスターターキットとでは、利用するマークダウンの変換方法が異なる。
参考にした方法 | ファイル形式 | 変換プラグイン |
---|---|---|
公式チュートリアル | .mdx |
gatsby-plugin-mdx |
gatsby-starter-blogスターター | .md |
gatsby-transformer-remark |
本記事ではmdx
形式を利用できるGatsby公式チュートリアルのやり方で実施する。
本記事のゴール
- 開発環境に保存したマークダウン形式の記事の中身を取得する。
- 開発環境からデータレイヤーに情報を送信する。
- データレイヤ内で、ノードの形式を「ファイルノード」から「MDXノード」に変換する。
- データレイヤーにGraphQLでアクセスし、情報を取得する。
- 取得したマークダウン記事をブログに表示する。
赤枠が本記事の実施範囲である。青枠が前回の実施範囲となる。
前回の記事
前提
- gatsby-starter-blogスターターキットを利用したgatsbyブログを立ち上げ済
- Vagrantを開発環境として利用
- Gatsby Cloudで公開済(今回は利用しないので、なくても可)
- 前回の記事で実施した通り、
gatsby-source-filesystem
の設定が完了し、/content/blog
フォルダ内のファイルがデータレイヤーに読み込まれる状態になっている
参考にしたサイト
MDXファイルとは
基本的にマークダウン形式のファイルだが、JSXの形式も書いて良いよ!という形式。
通常のマークダウンでは、マークダウンまたはHTMLしか書けないが、
console.log(""); // インデントするとJSとして動かないらしいので注意
や
<MyComponent title="あああ"></MyComponent>
のようなものを書くことができる。
詳細は以下サイトを参照。
ファイルノード・MDXノードとは
データレイヤーに取り込まれたデータの1つ1つは「ノード」と呼ばれる.。
- ノードの種類は、ソースプラグインごとに異なる。
- ノードの種類によって持つフィールドは異なる。
sorce-filesystem
プラグインを利用した場合、「ファイルノード」が作成される。
ファイルノードには、例えばファイル名を表すname
や、更新日時を表すmodifiedTime
等のフィールドがあり、以下のようにクエリで取得することができる。ただし、マークダウンで書かれたファイルの中身を上手く取得できるようなフィールドは無い。
query { allFile { nodes { id name } } }
そこで、「MDXノード」に変換する必要がある。
MDXノードは、body
(本文)や、frontmatter
に記載した内容、slug
(ファイル名)等を取得することができる。
query MyQuery { allMdx { nodes { frontmatter { title } slug body } } }
ファイルノードをMDXノードに変換する
MDXファイルの中身をつくる
MDXファイルに記事の内容を書く。
冒頭にはfrontmatter
を記載することができる。
frontmatterの下にはマークダウン+JSX(今回は単なるマークダウン)で記事を記載する。
frontmatterとは
frontmatterとは、英単語で言うと「本の奥付」。
まず Front Matter とはなんぞや、というと、元々は Jekyll という静的サイトジェネレータが広めたらしい、文書のメタデータを YAML で書く手法。 Markdown ファイルに限らず、そのファイルの冒頭で、以下のようにハイフン3つで囲んだ行の中が YAML 形式になっていて、その部分をメタデータ的に活用できるというモノ。
Remark プラグインを使って Markdown から Front Matter を抽出する - Neo's World
ということ。
マークダウンファイルの冒頭に以下のように記載する。
/content/blog/mdx-content.mdx
--- title: "mdxで記事を書いてみる" date: "2022-02-26" ---
記事を取得した際、node.frontmatter.title
やnode.frontmatter.date
として値を取得できる。
また、上記のdate
のように"xxxx-xx-xx"
という形式のデータを入れておくと、GraphiQLで要求電文を作成するとき、formatString
という様々な日付形式に変換できるフィルターをサジェストしてくれるので便利。
プラグインの利用設定
インストール
gatsby-plugin-mdx
をインストールする。
$ npm install gatsby-plugin-mdx @mdx-js/mdx@v1 @mdx-js/react@v1
コンフィグファイル設定
gatsby-config.js
のplugin
配列の中に、以下のように記載を追加する。
plugins: [ `gatsby-plugin-image`, { resolve: `gatsby-source-filesystem`, options: { path: `${__dirname}/content/blog`, name: `blog`, }, }, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images`, }, }, // 省略 `gatsby-plugin-mdx`, // 追加 ],
MDXノードの値を取得する
blog-tutorial
コンポーネントで、MDXノードの値を取得する。
取得した値は、props.data
に格納されるため、コンポーネント上で表示する。
src/pages/blog-tutorial.js
import { graphql } from "gatsby"; import { MDXRenderer } from "gatsby-plugin-mdx"; import * as React from "react"; import MyLayout from "../components/myLayout"; const BlogTutorial = (props) => { const { data } = props; console.log(data); return ( <MyLayout pageTitle="ブログ一覧"> {data.allMdx.nodes.map((node) => ( <article> <h2>{node.frontmatter.title}</h2> <p>Posted: {node.frontmatter.date}</p> <MDXRenderer> {node.body} </MDXRenderer> </article> ))} </MyLayout> ); }; export const query = graphql` query { allMdx(sort: { fields: frontmatter___date }) { nodes { frontmatter { title date(formatString: "YYYY年MM月DD日") } id body parent { ... on File { modifiedTime } } } } } `;
各フィールドの説明
allMdx
で取得できるフィールドを説明する。
フィールド | 説明 |
---|---|
frontmatter.title |
MDXファイルのfrontmatterにtitle タグをつけて記載した内容を取得。 |
frontmatter.date |
MDXファイルのfrontmatterにtitle タグをつけて記載した内容を取得。(formatString: "") オプションをつけると日付形式を指定できる。リファレンス:Moment.js | Docs |
id |
各ノードを一意に識別するための文字列ID。<li> 要素を使うときのキーにも利用できる。 |
body |
ファイルの中身からfrontmatterを除いたもの。 |
parent |
MDXに変換する前のノードを示す。ここでは、「対応するファイルノード」を示す。 |
MDXを読み込む
ファイルから取得したbody
はそのままでは読み込めない。
<MDXRenderer>
コンポーネントとセットで利用する必要がある。
上記ソースコードの通り、
import { MDXRenderer } from "gatsby-plugin-mdx";
でインポートして、
<MDXRenderer> {node.body} </MDXRenderer>
で囲む。
結果表示
localhost:8000/blog-tutorial
ページに、MDX記事の内容を表示できた。
【参考】他に必要なプラグイン
公式チュートリアルで紹介されていた、記事作成に必要なプラグインは以下。
gatsby-remark-images
:マークダウン形式![alt](image url)
で画像を指定できる。gatsby-remark-prismjs
:シンタックスハイライトを利用できる。- 'gatsby-remark-autolink-headers':Reactのチュートリアルサイトのように、見出しの頭にリンクを追加できる。
他にも
gatsby-remark-prismjs-add-title
(コードブロックの頭にファイル名を表示する)等も利用できそう。
おわりに
マークダウンで作成した記事のデータを取り込み、GraphQLで取得してコンポーネントで表示することができた。
まだ、記事ごとのページは作成できていないので、次回以降確認する。