0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Gatsby + material-ui: Markdown を入れてみる

0
Posted at

やること

  • markdown で書けるようにする
  • プラグインはtransfer-markdown ではなく MDX を使う
    • component が使えるのでうれしい

インストールと設定

markdown-transfer でもいいんですが、MDXのほうが便利なのでそちらを入れます。後で入れ替えるも二度手間ですし。とはいえしばらくはMDX独自の機能は使いません。

npm install --save gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
title=gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        extensions: [`.md`, `.mdx`]
      }
    }
  ]
}

拡張子は .md, .mdx 両方とも MDX扱いにしときます。

title=src/pages/awesome.md
---
title: markdown is awesome
date: 2020-02-02
---

## THIS IS AWESOME MARKDOWN

- foo
- bar
  - baz

これで localhost:8000/awesome/ で表示されます。

文書は別場所に

マークアップ文書群はコンポーネント群とは別に分けたいというのと、src/pages/に置いたままだと自動でいろいろ処理されてしまうため、自分でごにょごにょとできない(具体的には allMdx.nodes に入ってこない)という都合もあるので、content/以下に置くことにします。

そのフォルダをソースとして読み出しますよ、というのを追加設定します。プラグインのインストールです。

npm install --save gatsby-source-filesystem
mkdir content
mv src/pages/awesome.md content
title=gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/content`,
      }
    ...

これで content/ 以下のファイルも読み出せるようになりました。
ただし先程のように /awesome への書き出しは自動でやってくれなくなったので、自分で実装する必要があります。

マークアップ文書郡を取り出す

再び graphQL interface で遊びます。

gatsby-plugin-mdx を入れると、allMdx と mdx というクエリが使えるようになります。

title=graphql
query MyQuery {
  allMdx {
    totalCount
    nodes {
      slug
      frontmatter {
        title
      }
      body
    }
  }
}

これでいろいろ取れます。
手順としては、

  • クエリで mdx リソースのノード群を取り出す
  • それぞれについてテンプレートファイルに当てはめページを作成する。

となります。ページ作成は、createPage() という関数が用意されてるので、それを使う形になります。
新規に gatsby-node.js を作成します:

title=gatsby-node.js
const path = require(`path`)

exports.createPages = async ( { graphql, actions}) => {
    const { createPage } = actions
    const { data } = await graphql(`
    {
        allMdx {
            nodes {
                frontmatter {
                    title
                }
                slug
                body
            }
        }
    }
    `)
    data.allMdx.nodes.map(node=> {
        console.log('create markdown page: ', node.slug)

       createPage({
           path: node.slug,
           component: path.resolve('src/templates/post-template.js'),
           context: {
               node: node,
           }
       })
    })
}

いくつかポイントがありますが、まず async/await は非同期処理のため(らしい)です。詳しくは菊名。
graphql()で mdx リソースのノードとそのタイトルやスラッグ、ボディを取ってきてdataに入れます。
そして各ノードに対応するページを createPage()します。
その時、実際どのように出力するかを決める template component を指定し、これでよろしくとばかりにそのテンプレートに node を context として渡します。

title=src/template/post-template.js
import React from "react"
import { MDXRenderer } from "gatsby-plugin-mdx"

export default function PostTempalte ( { pageContext }){
    const { node } = pageContext
    return (
        <div>
            <h2>{node.frontmatter.title}</h2>
            <MDXRenderer>
                {node.body}
            </MDXRenderer>
        </div>
    )
}

pageContext の中に node が入ってるので、その中からデータを取り出すわけですね。
node.body はいろいろ関数やらが組み込まれた形式になってるので MDXRenderer タグで囲ってあげて HTML に変換します。

これで localhost:8000/awesome で見られるようになりました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?