Gatsby.jsでnetlify cmsを使ってみる
備忘録で書きます。
参考サイト → https://developer.okta.com/blog/2020/02/18/gatsby-react-netlify
前提条件
pcにgatsbyが既に入っている
環境はwindowsでもmacでもどちらでもできました。
gatsbyでhello world
gatsbyで一番シンプルなテンプレートをインストールします。
git clone https://github.com/gatsbyjs/gatsby-starter-hello-world hello
cd hello
npm install
gatsby develop か npm start でサーバーを立ち上げます。(同じですが、私は npm start )
npm start
localhost 8000にてhello worldが出てきます!!
gatsby-plugin-netlify-cmsをインストールする
今回は最新バージョンではなく、上の参考URLの記事と同じバージョンを使用します。
npm i netlify-cms-app@2.11.20 gatsby-plugin-netlify-cms@4.1.40
エディタを開いて、一番うえの階層にあるgatsby-config.jsにインストールしたプラグインを下のように書き込む
module.exports = {
plugins: [
`gatsby-plugin-netlify-cms`,
],
}
static/adminのようにstaticフォルダにadminフォルダを作成して、その中にconfig.ymlを作成する、名前は間違えないようにする
backend:
name: test-repo
media_folder: static/assets
public_folder: /assets
collections:
- name: post
label: Post
folder: post
create: true
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
fields:
- {label: "Template Key", name: "templateKey", widget: "hidden", default: "post"}
- { name: date, label: Date, widget: datetime }
- { name: title, label: Title }
- { name: body, label: Body, widget: markdown }
とりあえず、保存して、再度 npm start します。
そして、localhost:8000/adminのように後ろに /adminをつけると管理画面が表示されます。
このとき、新しい記事をつくってもリロードすると消えます😂🤣😅😪😥
ですので、この後、githubに記事が残るように設定します。
githubにpushする
git clone したときに一番うえの階層に.gitという見えないフォルダが作成されているので、消してからinit → pushしていきます
rm -rf .git
git init
git add . && git commit -m "first commit"
git remote add origin ~
git push -u origin master
netlifyにデプロイする
netlifyにログインして、New site from Git をクリックする
- Githubを選択する
- 先ほどpushしたレポジトリを選択する
- buildコマンドをgatsby buildに変更する
- Deploy siteをクリックする(早いww)
- デプロイ完了まで5~10分かかります
config.ymlを少し編集する
- デプロイ完了後にstatic/admin/config.ymlのbackendをtest-repoから、githubに変更します。
- repo: のところは自分のgithubアカウント名/先ほどpushしたレポジトリ名です。
backend:
name: github
repo: n-ohama/hello
編集後は必ずgit でプッシュします。プッシュすることで本番のデプロイ先のコードも自動で変わります(push後、反映されるまで5分くらいかかる)
git add . && git commit -m "テストレポからgithubに変更した" && git push
netlifyのサイトで実際に反映されたか確かめることもできます。
building → published に切り替わったら、反映完了です。
CMSの管理画面をgithubの0Authで実装する
- リンクから0Authを設定しますGitHub Developer settings
- New 0Auth Appをクリックする(下図)
- Application Name → hello (何でもいいのですが、レポジトリと同じ名前のhello)
- HomePageUrl → netlifyでデプロイした時のURL
- Description は無視していいです
- Authorization callback URL → https://api.netlify.com/auth/done を貼り付ける
- clientIDをコピーして、generate new client secret をクリックして、出てきたsecretの横のクリップマークを押すことでコピー
- netlifyの中のデプロイしたサイトの上のタブにてsite settingをクリック
- 左のサイドバーにてaccess controlをクリックして、下にある0Authの中のinstall providerをクリックする
- 先ほどコピーしたIDとSecretを張り付ければ完了です
サイトから管理画面を操作する
https://<myデプロイサイトURL>/adminのように後ろにadminをつけると自動で0Authしてくれます。
これで新しくPostを作ると、githubのそのリポジトリに保存されます。(記事を作成後に先ほどのようにビルドが始まります。publishedに変わるとgithubのリポジトリの一番上の階層のpostフォルダに保存される仕組みです。)
記事作成後はgit pullを必ずしましょう。
git pull することで、コンフリクトするのを防ぎます。
さらに、先ほど作ったファイルがmd形式で保存されているのを確認できます。
記事のリスト画面を作成する。
src/components/BlogRoll.jsx ファイルを作成する。
import React from 'react'
import PropTypes from 'prop-types'
import { Link, graphql, StaticQuery } from 'gatsby'
class BlogRoll extends React.Component {
render() {
const { data } = this.props;
const { edges: posts } = data.allMarkdownRemark;
return (
<div className="post-list">
{posts &&
posts.map(({ node: post }) => (
<article key={post.id}>
<header>
<div className="title">{post.frontmatter.title}</div>
<span className="subtitle">
• {post.frontmatter.date}
</span>
</header>
<p>
<div className="excerpt">{post.excerpt}</div>
<Link className="button" to={post.fields.slug}>
Keep Reading →
</Link>
</p>
</article>
))}
</div>
)
}
}
BlogRoll.propTypes = {
data: PropTypes.shape({
allMarkdownRemark: PropTypes.shape({
edges: PropTypes.array,
}),
}),
};
export default () => (
<StaticQuery
query={graphql`
query BlogRollQuery {
allMarkdownRemark(
filter: {frontmatter: {templateKey: {eq: "post"}}}
sort: { order: DESC, fields: [frontmatter___date] }
) {
edges {
node {
fields {
slug
}
excerpt(pruneLength: 50, truncate: true)
id
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
}
}
}
}
}
`}
render={(data, count) => <BlogRoll data={data} count={count} />}
/>
)
src/pages/post.jsxを作成する。
import React from 'react'
import BlogRoll from '../components/BlogRoll'
export default class BlogIndexPage extends React.Component {
render() {
return (
<>
<h1>Latest Posts</h1>
<section>
<BlogRoll />
</section>
</>
)
}
}
src/pages/index.jsxを編集する。(私はindex.jsをindex.jsxに変更しました)
import React from "react"
import { Link } from 'gatsby'
export default () => {
return (
<>
Hello world!
<p><Link to="/post">View Post</Link></p>
</>)
}
src/templates/post.jsxを作成します。(templatesフォルダは作りました。)
import React from "react"
import { graphql } from "gatsby"
export default function Template({ data }) {
const { markdownRemark } = data
const { frontmatter, html } = markdownRemark
return (
<div className="post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
)
}
export const pageQuery = graphql`
query($id: String!) {
markdownRemark(id: { eq: $id }) {
html
id
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
}
}
}
`
一番うえの階層にgatsby-node.jsを作成します。(これはjsxにしなかったです)
const path = require(`path`);
const { createFilePath } = require('gatsby-source-filesystem')
exports.createPages = async ({actions, graphql, reporter}) => {
const {createPage} = actions;
const blogPostTemplate = path.resolve(`src/templates/post.jsx`);
const result = await graphql(`
{
allMarkdownRemark(
filter: {frontmatter: {templateKey: {eq: "post"}}}
sort: { order: DESC, fields: [frontmatter___date] }
limit: 1000
) {
edges {
node {
id
fields {
slug
}
}
}
}
}
`);
// Handle errors
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`);
return
}
result.data.allMarkdownRemark.edges.forEach(({node}) => {
const id = node.id
createPage({
path: node.fields.slug,
component: blogPostTemplate,
context: {id},
})
})
};
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const value = createFilePath({ node, getNode })
createNodeField({
name: `slug`,
node,
value,
})
}
}
module.exports = {
plugins: [
`gatsby-plugin-netlify-cms`,
`gatsby-transformer-remark`,
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/post`,
name: `markdown-pages`,
},
},
],
}
完成図
git push で変更をデプロイする
以上のコードでエラーが出ていなければ、変更をgit pushしてあげることで、再度ビルドが始まります。5分くらい待てば、デプロイ先も自動で変更されます。このようにして、加えたいCSSなどを加えて、オリジナルサイトを作っていきましょう。
git add . && git commit -m "バックエンド完了" && git push
最後に
この記事を見て、wordpressだけではなく、たくさんのcmsサービスがWEB業界に増えていくことを望んでいます。この記事ではymlファイルに書いているように、templateKeyでpostと判断させているので、同様に固定ページなどもCMS化しながら応用することも可能です。次回はその記事を書いていこうかなと思います。
Discussion