GatsbyJS月別archiveページ作成
目次
このブログとは別件で個人ブログをwordpress v4.9.8とGatsbyJS v2で作成してます。
headless cmsというやつです。
gatsby.jsは静的サイトジェネレーターなのですがgatsby-source-wordpressプラグインを使うことで、wordpressから簡単に記事を引っ張ってこれます。
月別archiveページがほしくて、ちょっとだけ面倒なのですが自作したのでその紹介です。
ゴールはhttps://example.com/2018/09/
のようなURLで2018年9月の記事一覧ページを表示することです。
どちらで実装するか
- wordpressでAPIを拡張する方法
- gatsbyで全記事取得後、ゴニョゴニョする方法
gatsby側はなるべくシンプルにしたいと思い、wordpressのAPIを拡張することにしました。
API拡張失敗
結果から言うと、API拡張まではよかったのですが、gatsby側で取得ができなかったです。
拡張した時の実装方法に問題があったみたいですが、何故かはわかっていません!
/wp-json/wp/v2/archives
を叩くと、以下のようなJSONが返ってくるように作成しました。
[
{
"id": 1,
"slug": "2018/09",
"year": "2018",
"month": "09",
"count": 2
},
{
"id": 2,
"slug": "2018/08",
"year": "2018",
"month": "08",
"count": 3
}
...
]
この場合GraphQLで allWordpressWpArchives
フィールドが追加されるはずなのですが、一向にできません。
ブラウザからだとJSONが返ってくるのに…
どのように実装していたかというと、
wp_get_archives
でhtmlを取得したあと、preg_match
で必要な部分だけ抜き出してJSONにしてました。
それを試しにget_posts
に変更したところallWordpressWpArchives
で取得でき、wp_get_archives
を呼び出してしまうと駄目なことが分かりました。
phpでゴニョゴニョするなら、JSのほうが慣れているのでAPI拡張はやめることにしました。
wp_get_archives
でこんな風になれば楽だったのですが、諦めました。
JSでゴニョゴニョ
おおまかな流れはこんな感じです。
- 全件取得
- 日付だけ取り出す
- 重複削除 (Setがめちゃくちゃ便利!!)
- 日付の配列を回して
createPage()
コードはこんなです。
// gatsby-node.js
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
// 1. 全件取得
graphql(`
{
allWordpressPost {
edges {
node {
date(formatString: "YYYY/MM", locale: "ja")
}
}
}
}
`).then(result => {
if (result.errors) {
console.log(result.errors)
reject(result.errors)
}
// 2. 日付だけ取り出す
const dates = result.data.allWordpressPost.edges.map(({ node }) => node.date)
// 3. 重複削除
const uniqueDates = Array.from(new Set(dates))
// 4. 日付の配列を回してcreatePage()
uniqueDates.forEach(date => {
const r = date.match(/(\d{4})\/(\d{2})/u)
const slug = r[0]
const year = r[1]
const month = r[2]
createPage({
path: `/${slug}/`,
component: path.resolve(__dirname, 'src/templates/archive.js'),
context: {
title: `${year}年${month}月`,
date: `/${year}-${month}/`,
},
})
})
resolve()
})
})
}
// archive.jsのquery
query PostsByDate($date: String) {
allWordpressPost(filter: {date: {regex: $date}}) {
edges {
node {
slug
id
title
date(formatString: "YYYY.MM.DD h:mm", locale: "ja")
categories {
name
}
tags {
name
}
}
}
}
}
こんな感じで月別アーカイブページを作成することができました。
感想
- API拡張失敗するとどうやってデバックすればいいか分からないため、めちゃくちゃハマった
allWordpressWpArchives
で取得できたときは、よくわからんがすげーと思ったhttp://localhost:8000/___graphql
楽しい- 作るだけならwordpressだけのほうが楽