Gatsbyjsのチュートリアルがとてもわかりやすくて勉強になったので、
自分で内容を忘れないためにWordPressのデフォルトのテンプレートに近いものを作ってみました
また、私はGatsbyjsやWordPress初心者です、よろしくお願いいたします
作ったのはGitHub Pagesで見れます↓
私が作成したコードは以下です
0. gatsbyの雛形を作成
npx -p gatsby-cli gatsby new myblog https://github.com/gatsbyjs/gatsby-starter-hello-world
cd myblog
yarn develop
http://localhost:8000/
で表示される
1. 全体のスタイルを設定
body {
font-family: Verdana, sans-serif;
margin: 0 auto;
width: 900px;
}
a {
text-decoration: none;
}
gatsby-browser.js
で読み込む
import "./src/styles/global.css"
※gatsby-browser.js
などの設定関連のファイルは、変更するたびにCtrl+Cで開発サーバーを終了し、再度yarn develop
で起動し直さないと反映されないようでした
2. ヘッダー、フッター、サイドバーを作成して共通化
src/index.js
の内容を以下のように変更、(※拡張子もjsx
に変更しました)
import React from "react"
import Layout from "../components/Layout"
export default () => (
<Layout page={"top"}>
<div>Hello world!</div>
</Layout>
)
共通化したのがわかりやすいように、もう一つページを作成する
import React from "react"
import Layout from "../components/Layout"
export default () => (
<Layout>
<h1>サンプルページ</h1>
<p>
これはサンプルページです。同じ位置に固定され、(多くのテーマでは)
サイトナビゲーションメニューに含まれる点がブログ投稿とは異なります。まずは、サイト訪問者に対して自分のことを説明する自己紹介ページを作成するのが一般的です。たとえば以下のようなものです。
</p>
<blockquote class="wp-block-quote">
<p>
はじめまして。昼間はバイク便のメッセンジャーとして働いていますが、俳優志望でもあります。これは僕のサイトです。ロサンゼルスに住み、ジャックという名前のかわいい犬を飼っています。好きなものはピニャコラーダ、そして通り雨に濡れること。
</p>
</blockquote>
</Layout>
)
ヘッダーで読み込む用にサイトのメタデータを設定しておく
module.exports = {
siteMetadata: {
title: "ホゲホゲブログ",
description: "ホゲホゲによるブログです",
},
}
全体のパーツを読み込むファイル読み込むファイル
import React from "react"
import Header from "./Header"
import Main from "./Main"
import Sidebar from "./Sidebar"
import Footer from "./Footer"
export default ({ page = "default", children }) => (
<>
<Header page={page} />
<Main sidebar={<Sidebar />}>{children}</Main>
<Footer />
</>
)
ヘッダーを表示するファイル。
GraphQLを使ってサイトのメタデータを取得します。
import React from "react"
import { useStaticQuery, Link, graphql } from "gatsby"
import styles from "../styles/header.module.css"
export default ({ page }) => {
const {
site: {
siteMetadata: { title, description },
},
} = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
description
}
}
}
`
)
return (
<header>
{page === "top" && <div className={styles.headerImg}> </div>}
<div className={styles.headerBox}>
<h1>
<Link to="/">{title}</Link>
</h1>
<p>{description}</p>
</div>
</header>
)
}
サイドバーとメインコンテンツを表示するファイル
import React from "react"
import styles from "../styles/main.module.css"
export default ({ children, sidebar }) => (
<div className={styles.flex}>
<div className={styles.mainLeft}>{children}</div>
<div className={styles.mainRight}>{sidebar}</div>
</div>
)
サイドバー表示、「最近の投稿」と「カテゴリー」の表示はあとで行います
import React from "react"
import { Link } from "gatsby"
export default () => {
return (
<>
<div>
<h3>固定ページ</h3>
<ul>
<li>
<Link to="/sample-page/">サンプルページ</Link>
</li>
</ul>
</div>
<div>
<h3>最近の投稿</h3>
<ul></ul>
</div>
<div>
<h3>カテゴリー</h3>
<ul></ul>
</div>
</>
)
}
フッターを表示するファイル
import React from "react"
import { Link } from "gatsby"
export default () => (
<>
<hr />
<Link to="https://www.gatsbyjs.org/">Powered by Gatsbyjs</Link>
</>
)
共通部分の作成までできました
3. トップページにブログ一覧表示
blog
フォルダにマークダウンで内容を書いて、それを一覧表示します。
マークダウンの内容はこのような感じです。
---
title: Hello World
date: "2017-08-21"
categories: []
---
Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。
Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。
Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。Hello World。
ローカルファイルのデータをGatsbyに渡せるプラグインと、
マークダウンを扱うプラグインをインストール
yarn add gatsby-source-filesystem gatsby-transformer-remark
プラグインを使えるように設定
module.exports = {
siteMetadata: {
title: "ホゲホゲブログ",
description: "ホゲホゲによるブログです",
},
plugins: [
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/blog`,
name: "blog",
},
},
"gatsby-transformer-remark",
],
}
gatsby-node.js
を作成して、createNodeField
でslugを設定します、これでGraphQLからslugが取得できるようになります。
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,
})
}
}
↑詳しい説明はチュートリアルの、パート6、7あたりです。
GraphQLで、日付でソートしつつ必要なデータを取得しました
import React from "react"
import { Link, graphql } from "gatsby"
import Layout from "../components/Layout"
import styles from "../styles/index.module.css"
export default ({
data: {
allMarkdownRemark: { totalCount, edges: blogs },
},
}) => (
<Layout page={"top"}>
<strong>投稿 ( {totalCount} ) </strong>
{blogs.map(
({
node: {
id,
frontmatter: { title, date },
fields: { slug },
excerpt,
},
}) => (
<div key={id} className={styles.box}>
<div className={styles.date}>{date}</div>
<h2 className={styles.title}>
<Link to={slug}>{title}</Link>
</h2>
<p>{excerpt}</p>
</div>
)
)}
</Layout>
)
export const query = graphql`
query {
allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
totalCount
edges {
node {
id
frontmatter {
title
date(formatString: "YYYY年MM月DD日")
}
fields {
slug
}
excerpt
}
}
}
}
`
これによりトップページにブログの一覧表示はできましたが、まだ詳細表示するページを作成していないためアクセスしても404と表示されます。
4. ブログ詳細ページ作成
ブログページを表示するためのテンプレートを作成しておきます
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
export default ({
data: {
markdownRemark: {
html,
frontmatter: { title, categories },
},
},
}) => {
return (
<Layout>
<h1>{title}</h1>
<>
<strong>カテゴリー : </strong>
{categories.length ? categories.join(", ") : "なし"}
</>
<div dangerouslySetInnerHTML={{ __html: html }} />
</Layout>
)
}
export const query = graphql`
query($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
html
frontmatter {
title
categories
}
}
}
`
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.jsx"),
context: {
// GraphQLのクエリの $slug 変数に設定する値
slug: node.fields.slug,
},
})
})
}
ブログのページを確認できました
5. カテゴリーごとの一覧ページ作成
参考:https://www.gatsbyjs.org/docs/adding-tags-and-categories-to-blog-posts/
先ほどと同じようにテンプレートを作成します
import React from "react"
import { Link, graphql } from "gatsby"
import Layout from "../components/layout"
export default ({
data: {
allMarkdownRemark: { totalCount, edges: blogs },
},
}) => {
return (
<Layout>
{blogs.map(
({
node: {
id,
html,
frontmatter: { title },
fields: { slug },
},
}) => (
<div key={id}>
<h2>
<Link to={slug}>{title}</Link>
</h2>
<div dangerouslySetInnerHTML={{ __html: html }} />
<hr />
</div>
)
)}
</Layout>
)
}
export const pageQuery = graphql`
query($category: String!) {
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
filter: { frontmatter: { categories: { in: [$category] } } }
) {
totalCount
edges {
node {
id
html
frontmatter {
title
}
fields {
slug
}
}
}
}
}
`
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
}
}
}
}
+ categoriesAllMarkdownRemark: allMarkdownRemark {
+ group(field: frontmatter___categories) {
+ category: fieldValue
+ }
+ }
}
`)
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve("./src/templates/blog-post.jsx"),
context: {
// GraphQLのクエリの $slug 変数に設定する値
slug: node.fields.slug,
},
})
})
+ result.data.categoriesAllMarkdownRemark.group.forEach(({ category }) => {
+ createPage({
+ path: `/category/${category}/`,
+ component: path.resolve("./src/templates/categories.jsx"),
+ context: {
+ // GraphQLのクエリの $category 変数に設定する値
+ category,
+ },
+ })
+ })
}
まだページ内からのリンクはないのですが、http://localhost:8000/category/ブログ/
とurlを直打ちすると、カテゴリーに対応する投稿のみを表示することができました
6. サイドバーの情報を取得して表示
Sidebar.jsx
をGraphQLからデータを取ってくるように変更
import React from "react"
import { useStaticQuery, Link, graphql } from "gatsby"
export default () => {
const {
recentlyAllMarkdownRemark: { edges: recentlyBlogs },
categoriesAllMarkdownRemark: { group: categories },
} = useStaticQuery(
graphql`
query {
recentlyAllMarkdownRemark: allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
limit: 5
) {
edges {
node {
id
frontmatter {
title
}
fields {
slug
}
}
}
}
categoriesAllMarkdownRemark: allMarkdownRemark {
group(field: frontmatter___categories) {
category: fieldValue
totalCount
}
}
}
`
)
return (
<>
<div>
<h3>固定ページ</h3>
<ul>
<li>
<Link to="/sample-page/">サンプルページ</Link>
</li>
</ul>
</div>
<div>
<h3>最近の投稿</h3>
<ul>
{recentlyBlogs.map(
({
node: {
id,
frontmatter: { title },
fields: { slug },
},
}) => (
<li key={id}>
<Link to={slug}>{title}</Link>
</li>
)
)}
</ul>
</div>
<div>
<h3>カテゴリー</h3>
<ul>
{categories.map(({ category, totalCount }) => (
<li key={category}>
<Link to={`category/${category}`}>{category}</Link> ( {totalCount}{" "}
)
</li>
))}
</ul>
</div>
</>
)
}
サイドバーも表示することができました
7. サイトメタデータ
チュートリアルのパート8参考
https://www.gatsbyjs.org/tutorial/part-eight/
サイトのmeta
タグやtitle
、description
を設定します
react-helmet
を使うのでインストール
yarn add gatsby-plugin-react-helmet react-helmet
module.exports = {
siteMetadata: {
title: "ホゲホゲブログ",
description: "ホゲホゲによるブログです",
},
plugins: [
{
resolve: "gatsby-source-filesystem",
options: {
path: `${__dirname}/blog`,
name: "blog",
},
},
"gatsby-transformer-remark",
+ "gatsby-plugin-react-helmet",
],
}
import React from "react"
+ import Helmet from "react-helmet"
import { useStaticQuery, Link, graphql } from "gatsby"
import styles from "../styles/header.module.css"
export default ({ page }) => {
const {
site: {
siteMetadata: { title, description },
},
} = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
description
}
}
}
`
)
return (
+ <>
+ <Helmet
+ htmlAttributes={{ lang: "ja" }}
+ title={title}
+ meta={[
+ {
+ name: "description",
+ content: description,
+ },
+ ]}
+ />
<header>
{page === "top" && <div className={styles.headerImg}> </div>}
<div className={styles.headerBox}>
<h1>
<Link to="/">{title}</Link>
</h1>
<p>{description}</p>
</div>
</header>
+ </>
)
}
タイトルタグや、metaタグが設定できました。
最後まで読んでいただいてありがとうございました。m(_ _)m