I'm currently building a website for a client with Gatsby and Wordpress as a CMS. All has gone well so far but I am struggling with creating the "previous page" and "next page" links while finalizing pagination for the site's blog. I think I know what direction I'm heading in next, but I am struggling with passing items through context in my gatsby-node.js file.
Relevant parts of gatsby-node.js:
const path = require('path')
module.exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const blogPostTemplate = path.resolve('./src/templates/blog-post.js')
const blogCategoryFilter = path.resolve('./src/templates/blog-filter-category.js')
const blogArchiveFilter = path.resolve('./src/templates/blog-filter-archive.js')
const blogList = await graphql(`
query {
allWordpressPost {
edges {
node {
slug
date(formatString:"YYYY-MM")
}
}
}
}
`);
const categories = await graphql(`
query {
allWordpressCategory {
edges {
node {
slug
}
}
}
}
`);
const posts = blogList.data.allWordpressPost.edges;
categories.data.allWordpressCategory.edges.forEach((edge) => {
const slug = edge.node.slug
const blogPostsCount = posts.length
const blogPostsPerPaginatedPage = 3
const paginatedPagesCount = Math.ceil(blogPostsCount / blogPostsPerPaginatedPage)
for (let i = 0; i <= paginatedPagesCount; i++) {
createPage({
component: blogCategoryFilter,
path: i === 0 ? `/blog/category/${slug}` : `/blog/category/${slug}/${i + 1}`,
context: {
slug: slug,
limit: blogPostsPerPaginatedPage,
skip: i * blogPostsPerPaginatedPage,
paginatedPagesCount,
currentPage: i + 1,
}
})
}
})
My template file:
import React from 'react'
import { graphql, Link } from 'gatsby'
import Layout from '../components/layout'
import BlogNav from '../components/blognav'
import blogStyles from '../components/modules/blog.module.css'
export const query = graphql`
query($slug: String!, $limit: Int!, $skip: Int!) {
allWordpressPost (filter: {categories: {elemMatch: {slug: { eq: $slug }}}} limit: $limit skip: $skip) {
edges {
node {
title
slug
content
date(formatString: "MMMM DD, YYYY")
}
}
}
allWordpressCategory (filter: {slug: {eq: $slug}}) {
edges {
node {
slug
}
}
}
}
`
export default ({ data }) => {
return (
<Layout>
<div className={blogStyles.blog_container}>
<div className={blogStyles.blogContent_container}>
<ol>
{data.allWordpressPost.edges.map((edge) => {
return (
<div className={blogStyles.blogPost_container}>
<li className={blogStyles.blog_list}>
<h2><Link to={`/blog/${edge.node.slug}`} className={blogStyles.blog_title} dangerouslySetInnerHTML={{ __html: edge.node.title }}></Link></h2>
<p className={blogStyles.blog_date}>{edge.node.date}</p>
<p className={blogStyles.blog_content} dangerouslySetInnerHTML={{ __html: edge.node.content }} />
</li>
</div>
)
})}
</ol>
</div>
<BlogNav />
</div>
</Layout>
)
}
I want to incorporate some code like this:
class BlogList extends React.component {
render() {
const { currentPage, paginatedPagesCount } = this.props.pageContext
const isFirst = currentPage === 1
const isLast = currentPage === paginatedPagesCount
const prevPage = currentPage - 1 === 1 ? "/" : (currentPage - 1).toString()
const nextPage = (currentPage + 1).toString()
return (
// code to display a list of posts
{!isFirst && (
<Link to={prevPage} rel="prev">
← Previous Page
</Link>
)}
{!isLast && (
<Link to={nextPage} rel="next">
Next Page →
</Link>
)}
)
}
}
However, my component looks different and I'm not quite sure how to pull in the information I'm passing through context in this example. This line in particular trips me up:
const { currentPage, paginatedPagesCount } = this.props.pageContext
My error reads that it cannot read props of undefined. It appears I can't use "this"? I feel like I'm missing something foundational here. React makes my head spin sometimes!
Thoughts? Strategies? Thanks! Excuse any sloppy code: I'm a newbie.
Assuming BlogList
would be BlogNav
instead (because you are calling it from the template). What you could do is something like: - template file
/** Your Query **/
export default ({ data, pageContext }) => {
// here `this.props` won't work because this is not a class (unless you transform this to a react component)
// your body
<BlogNav {...pageContext} />
}
Then, in your BlogNav
you will be able to call the properties as you are doing now.
It should work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.