以前の記事でGatsby-Stater-Lumenのサイドバーにカテゴリーリストを追加した。 引き続き、今回は月別アーカイブリストを追加したい。
この前のカテゴリーリストの際は、サイドバーのコンポーネントにデータを流して、UIを追加するだけという感じだった。 今回はプラスアルファで、月別の記事一覧のページを作成する必要がある。
まず、下の画像のような月別一覧ページを作成したい。
そこで、Gatsbyのカナメとも言えるgatsby-node.js
をいじる。どんなWebサイトも何らかのページを作成しないと何も始まらないが、Gatsbyの場合「どのURLでどのページを表示させるか」をこのファイルに記述していく。Gatsbyはビルド時にこのファイルを元に各ページを発行していく。
ここでは以下のようなコードを追加して、月別の記事一覧ページを作成する。 (一部記載、全体はこちら)
_.each(dates, (date) => {
const year = moment(date).year();
const month = moment(date).month() + 1;
const paddingMonth = ('00' + month.toString()).slice(-2);
const monthPath = `/archive/${year}/${month}/`;
const pattern = `/^${year}-${paddingMonth}/`
createPage({
path: monthPath,
component: monthTemplate,
context: { year: year, month: month, regex: pattern }
});
});
createPageはGatsbyのAPIの1つであり、その名の通りページを作成するための関数だが、path component context
を渡すことで、
を指定することができる。
とりわけ、今回の場合context
は重要である。というのも、contextを通して年月のデータをmonth-template.jsx
に渡しておかなければ、表示する記事を年月でフィルタリングできないからだ。
次に、先ほどのcomponent
で指定したmonthTemplate
を作成する。Railsで言えば、ビューにあたる部分である。
class MonthTemplate extends React.Component {
render() {
const { title } = this.props.data.site.siteMetadata;
const { year, month, regex } = this.props.pathContext;
return (
<div>
<Helmet title={`${year}年${month}月 - ${title}`} />
<Sidebar {...this.props} />
<MonthTemplateDetails {...this.props} />
</div>
);
}
}
コンポーネント自体はこのようにシンプルなものとなった。
あと、こちらのmonth-template.jsx
も合わせて見てもらえば分かると思うが、記事のフィルタリングはGraphqlのクエリ内で行っている。下の$regex
で年月フィルタリングを行っている。ちなみに、$
のように任意のデータをフィルタリングに使いたい場合は、context
経由で受け渡したデータしか使えないので要注意。
allMarkdownRemark: allMarkdownRemark(
limit: 1000,
filter: { frontmatter: { date: { regex: $regex }, layout: { eq: "post" }, draft: { ne: true } } },
sort: { order: DESC, fields: [frontmatter___date] }
){ //続く
カテゴリーリストと同じなので、バッサリと割愛… 結果のみ…
今回は月別アーカイブのページを作成し、サイドバーにリストを追加した。ようやくブログっぽくなってきたので、もう少し頑張るます。次は、ブログの全文検索機能を実装する。