LoginSignup
2
1

More than 3 years have passed since last update.

gatsby入門 チュートリアルをこなす 7. プログラムでデータからページを作成する

Last updated at Posted at 2020-09-05

gatsbyの作業履歴

gatsby入門 チュートリアルをこなす 0.開発環境をセットアップする
gatsby入門 チュートリアルをこなす 1. ギャツビービルディングブロックについて知る(1)
gatsby入門 チュートリアルをこなす 1. ギャツビービルディングブロックについて知る(2)
gatsby入門 チュートリアルをこなす 2. ギャツビーのスタイリングの概要
gatsby入門 チュートリアルをこなす 3. ネストされたレイアウトコンポーネントの作成
gatsby入門 チュートリアルをこなす 4. ギャツビーのデータ
gatsby入門 チュートリアルをこなす 5. ソースプラグインとクエリされたデータのレンダリング
gatsby入門 チュートリアルをこなす 6. 変圧器プラグイン※Transformer pluginsのgoogle翻訳
今回:gatsby入門 チュートリアルをこなす 7. プログラムでデータからページを作成する
gatsby入門 チュートリアルをこなす 8. 公開するサイトの準備
gatsby入門 ブログ作ってサーバーにアップしてみる

チュートリアル

今回実施するgatsbyのチュートリアルはこちら
https://www.gatsbyjs.com/tutorial/part-seven/
チュートリアルの冒頭にこう書かれています。

Reactコンポーネントをsrc / pagesに配置することで、引き続きページを作成できます。ただし、プログラムからデータからページを作成する方法を学習します。

※google翻訳です。
早速やっていきましょう。
ソースは前回作ったやつを使用します。

Programmatically create pages from data

Creating slugs for pages

マークダウンページを作成するには、onCreateNodeとcreatePagesの2つのGatsby APIを使用します。
gatsby-node.jsを作成し、以下を記述します。

gatsby-node.js
exports.onCreateNode = ({ node }) => {
  console.log(`Node created of type "${node.internal.type}"`)
}

チュートリアルはこのように記載されています。

このonCreateNode関数は、新しいノードが作成(または更新)されるたびにGatsbyによって呼び出されます。

なるほど。
gatsby開発サーバを再起動します。
起動はgatsby developでできます。
2020-09-06_02h21_53.jpg
なんかログがいっぱい出てその中にマークダウンの文字が。
gatsby-node.jsを修正します。

gatsby-node.js
exports.onCreateNode = ({ node }) => {
  ここから
  if (node.internal.type === `MarkdownRemark`) {
    console.log(node.internal.type)
  }
  ここまで修正
}

マークダウンだけログだしするのね。
再起動
2020-09-06_02h26_55.jpg
出てる出てる
マークダウンファイルのファイル名からURLのパスを作っていきましょう。
。。gatsbyだとパスをslugっていうのか。
gatsby-node.jsを修正

gatsby-node.js
exports.onCreateNode = ({ node, getNode }) => {ここ修正
  if (node.internal.type === `MarkdownRemark`) {
    const fileNode = getNode(node.parent)ここ修正
    console.log(`\n`, fileNode.relativePath)ここ修正
  }
}

再起動
2020-09-06_02h32_44.jpg
これか!
ここからgatsby-source-filesystem pluginを使用
gatsby-node.jsを修正

gatsby-node.js
const { createFilePath } = require(`gatsby-source-filesystem`)ここ追記

exports.onCreateNode = ({ node, getNode }) => {
  if (node.internal.type === `MarkdownRemark`) {
    console.log(createFilePath({ node, getNode, basePath: `pages` }))ここ修正
  }
}

再起動
2020-09-06_02h36_42.jpg
出来てる!
ここからcreateNodeFieldを使用してslug(パス)を作ります。
gatsby-node.jsを修正

gatsby-node.js
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, getNode, actions }) => {ここ修正
  const { createNodeField } = actionsここ修正
  if (node.internal.type === `MarkdownRemark`) {
    ここから
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
    ここまで追記
  }
}

再起動
GraphiQLで以下を実行

query MyQuery {
  allMarkdownRemark {
    edges {
      node {
        fields {
          slug
        }
      }
    }
  }
}

2020-09-06_02h45_04.jpg
キタコレ!

Creating pages

ページ作りだ!
gatsby-node.jsを修正

gatsby-node.js
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

ここから
exports.createPages = async ({ graphql, actions }) => {
  // **Note:** The graphql function call returns a Promise
  // see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise for more info
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)
  console.log(JSON.stringify(result, null, 4))
}
ここまで追記

この時点でどうなるのかさっぱりわからんが続けよう。
src/templatesディレクトリを作成
src/templates/blog-post.jsを作成し以下を記述

blog-post.js
import React from "react"
import Layout from "../components/layout"

export default function BlogPost() {
  return (
    <Layout>
      <div>Hello blog post</div>
    </Layout>
  )
}

gatsby-node.jsを修正

gatsby-node.js
const path = require(`path`)ここ追記
const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actionsここ追記
  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)
  ここから
  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        // Data passed to context is available
        // in page queries as GraphQL variables.
        slug: node.fields.slug,
      },
    })
  })
  ここまで追記
}

再起動
以下でアクセス
http://localhost:8000/sdf
※sdfは何でもいい
2020-09-06_03h00_20.jpg
あ、パスが出来てる
アクセス
2020-09-06_03h01_14.jpg
マークダウンファイルはまだ出てこない。
なるほど、ちょっとわかったぞ。
gatsby-node.jsのonCreateNodeでマークダウンのファイル名を取得してslug(パス)を作成。
createPagesでそのslugを取得し、繰り返し処理の中でパスとsrc/templates/blog-post.jsを同期させるのね!
つづき!
src/templates/blog-post.jsの修正

src/templates/blog-post.js
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"

export default function BlogPost({ data }) {
  const post = data.markdownRemark
  return (
    <Layout>
      <div>
        <h1>{post.frontmatter.title}</h1>
        <div dangerouslySetInnerHTML={{ __html: post.html }} />
      </div>
    </Layout>
  )
}

export const query = graphql`
  query($slug: String!) {
    markdownRemark(fields: { slug: { eq: $slug } }) {
      html
      frontmatter {
        title
      }
    }
  }
`

うんうん。graphqlでマークダウンのhtml情報を取得してsrc/templates/blog-post.jsに書き込む感じか。
2020-09-06_03h15_57.jpg
出来た!
そしてsrc/pages/index.jsを修正

src/pages/index.js
import React from "react"
import { css } from "@emotion/core"
import { Link, graphql } from "gatsby"ここ修正
import { rhythm } from "../utils/typography"
import Layout from "../components/layout"

export default function Home({ data }) {
  return (
    <Layout>
      <div>
        <h1
          css={css`
            display: inline-block;
            border-bottom: 1px solid;
          `}
        >
          Amazing Pandas Eating Things
        </h1>
        <h4>{data.allMarkdownRemark.totalCount} Posts</h4>
        {data.allMarkdownRemark.edges.map(({ node }) => (
          <div key={node.id}>
            ここから
            <Link
              to={node.fields.slug}
              css={css`
                text-decoration: none;
                color: inherit;
              `}
            >
            ここまで修正
              <h3
                css={css`
                  margin-bottom: ${rhythm(1 / 4)};
                `}
              >
                {node.frontmatter.title}{" "}
                <span
                  css={css`
                    color: #555;
                  `}
                >
                   {node.frontmatter.date}
                </span>
              </h3>
              <p>{node.excerpt}</p>
            </Link>←ここ修          </div>
        ))}
      </div>
    </Layout>
  )
}

export const query = graphql`
  query {
    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
      totalCount
      edges {
        node {
          id
          frontmatter {
            title
            date(formatString: "DD MMMM, YYYY")
          }
          ↓ここから
          fields {
            slug
          }
          ↑ここまで修正
          excerpt
        }
      }
    }
  }
`

再起動
index.jsからpostにアクセスできるようになった!
チュートリアルはここまでかな。

これ、src/pages内にmdファイルあるのが気になるから移動できないかしら?
src/mdディレクトリ作成し、mdファイルを移動
2020-09-06_03h26_25.jpg
再起動
2020-09-06_03h27_21.jpg
うん、問題ないね!
今回はここまで。

ありがとうございました。

2
1
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
2
1