こんばんは!
今回はページネーション機能を使ってみたいと思います.
ページネーション機能を利用するためのプラグインは何個かあるのですが、そのなかで一番便利な (悪く言うとプラグイン任せな) awesome-pagination
を使います.
まずはプラグインをインストールします.
npm i gatsby-awesome-pagination
gatsby-node.js
に以下を追加します.
const { paginate }= require('gatsby-awesome-pagination')
const bloglistTemplate = path.resolve('./src/templates/blog-list-template.js')
paginate({
createPage,
items: res.data.allMarkdownRemark.edges,
itemsPerPage: 3,
pathPrefix: '/bloglist',
component: bloglistTemplate,
})
さらに、bloglist.js
の名前を blog-list-template.js
とし、templates
フォルダに入れます.
そして、blog-list-template.js
を以下のように編集します.
import React from 'react'
import { Link , graphql } from 'gatsby'
import Layout from '../Layouts/common'
export const data = graphql`
query ($skip: Int!, $limit: Int!) {
allMarkdownRemark (
skip: $skip ,
limit: $limit
){
edges {
node {
frontmatter {
title
date (formatString: "MMMM DD, YYYY")
}
excerpt
fields{
slug
}
}
}
}
}
`
const BlogList = (props) => {
return (
<Layout>
<h1>This is BlogList </h1>
<ol>
{props.data.allMarkdownRemark.edges.map( ({node}) => {
return (
<li key={node.fields.slug}>
<Link to={`/bloglist/${node.fields.slug}`} >
<h2>{node.frontmatter.title}</h2>
<p>{node.frontmatter.date}</p>
</Link>
</li>
)
})}
</ol>
</Layout>
)
}
export default BlogList
開発用サーバーを起動して、Bloglist
ページを見てみると、記事の数が3つになっています. これは、gatsby-node.js
にて、itemsPerPage
を 3
に設定したからです. http://localhost:8000/bloglist/2
にアクセスしてみると、続きの3つの記事が現れます.
このように、ページネーション機能を使うと、記事数が多くなった時に見やすく、記事数が少ない場合でも多く見せることができます.
ここでいったん、上のコードの意味を簡単に考えてみましょう.
ページネーションを行うには 4つの情報
が必要です.
それは、すべての記事情報 ( items
)、1ページに何個の記事を載せるか ( itemsPerPage
)、各ページにつけたいパス ( pathPrefix
)、利用するテンプレート ( component
) です.
これらの情報に加え、上の $skip , $limit
を利用して、ページネーションしています. この二つは変数で必ず正の整数が与えられます.
例えば今6つ記事があり、itemsPerPage
を 3
に指定したとき、$limit
に 3
が与えられます. これは、1ページの記事の個数を 3
に限定 ( limit
) しているわけです.
http://localhost:8000/bloglist/2
に移動したとき、$limit
に加え、$skip
には 3
が与えられます. なぜなら、6
つの記事のうち最初の 3
つを飛ばしているから ( skip
) です.
つまり、ひとつのテンプレートを 使いまわして、情報だけを変えているから、あたかも、ページが切り替わっているように見えるというわけです.
さて、http://localhost:8000/bloglist/2
に行くためのリンクを作ってみましょう.
そのまま、blog-list-template.js
にページリンクを書くと長くなるので、コンポーネントとして書いてみます.
src/components
に pageCon.js
を作成し、以下のように書きます.
import React from 'react'
import { Link } from 'gatsby'
const Page = ( {context} ) => {
const { previousPagePath , nextPagePath ,humanPageNumber , numberOfPages} = context
return (
<div className="container">
<nav className="pagination" >
<ul>
{previousPagePath && (
<p>
<Link to={previousPagePath} className="newer-posts">
Prev
</Link>
</p>
)}
<p>
<span className="page-number">
Page {humanPageNumber} of {numberOfPages}
</span>
</p>
{nextPagePath && (
<p>
<Link to={nextPagePath} className="older-posts">
Next
</Link>
</p>
)}
</ul>
</nav>
</div>
)
}
export default Page
context
とは pagination
によって渡されるオブジェクトで、自動的に以下の値を受け渡します.
- pageNumber - ページ番号 (
0
から始まります )- humanPageNumber - ページ番号 (
1
から始まります )- skip - さきほど
$skip
が使えたのはcontext
で自動的に受け渡されているからです- limit -
$skip
と同様- numberOfPages - トータルのページ数
- previousPagePath - 前のページへのパスを表します
- nextPagePath - 次のページへのパスを表します
{previousPagePath && ( ...
この &&
はもし、previousPagePath
がなければ ( = undefined
)、&&
以下は表示されないということです.
blog-list-template.js
に以下を追加します.
import Page from '../components/pageCon'
<Layout>
... (省略)
<Page context = {props.pageContext} />
</Layout>
これで、next
previous
を押してページ移動することができます !
次回は、 CSS
で少し形を整えた後、ページネーションを各記事間に設置、タグを実装してみたいと思います.
ここまで読んでくださって、ありがとうございました.