问题
Can anyone shed some insight on how I would go about paginating pages in Gatsby when filtering Wordpress posts by category?
For context, my gatsby-node file:
const path = require('path')
module.exports.createPages = async ({ graphql, actions }) => {
// import { paginate } from 'gatsby-awesome-pagination';
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 res = await graphql(`
query {
allWordpressPost {
edges {
node {
slug
date(formatString:"YYYY-MM")
}
}
}
allWordpressCategory {
edges {
node {
slug
}
}
}
}
`)
// UNPAGINATED
//Blog list - organized by category
res.data.allWordpressCategory.edges.forEach((edge) => {
createPage({
component: blogCategoryFilter,
path: `/blog/category/${edge.node.slug}`,
context: {
slug: edge.node.slug,
}
})
})
}
The blog-filter-category.js file that I use as my template:
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!) {
allWordpressPost (filter: {categories: {elemMatch: {slug: { eq: $slug }}}}) {
edges {
node {
title
slug
content
date(formatString: "MMMM DD, YYYY")
}
}
}
}
`
export default ({ data }) => {
//const post = data.allWordpressPost.edges[0].node
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 tried reading through the documentation of some relevant plugins (gatsby-paginate, gatsby-awesome-paginate, etc) and this article (https://www.gatsbycentral.com/pagination-in-gatsby) but it was all going a little over my head. It seemed to make sense for blog posts that I'm generating on to a template and simply sorting chronologically, but I get confused when I start filtering by category, archived months, etc.
Any tips? Can I paginate using the code structures above or do I have to rethink how I'm throwing this together?
Thank you!
回答1:
Let's assume we chose to use the gatsby-awesome-pagination
plugin, as mentioned in the question.
This is from the plugin's quick start instructions:
import { paginate } from 'gatsby-awesome-pagination';
exports.createPages = ({ actions, graphql }) => {
const { createPage } = actions;
// Fetch your items (blog posts, categories, etc).
const blogPosts = doSomeMagic();
// Create your paginated pages
paginate({
createPage, // The Gatsby `createPage` function
items: blogPosts, // An array of objects
itemsPerPage: 10, // How many items you want per page
pathPrefix: '/blog', // Creates pages like `/blog`, `/blog/2`, etc
component: path.resolve('...'), // Just like `createPage()`
})
}
What we're interested in in order to paginate by category is:
items
: we need an array of posts grouped by categorypathPrefix
: the category name to generate paths
We can get these by using a GraphQL query:
query MyQuery {
allWordpressPost {
group(field: categories___name) {
nodes {
title
# any other post data you need
}
fieldValue
}
}
}
This will return something like:
{
"data": {
"allWordpressPost": {
"group": [
{
"nodes": [
{
"title": "Abyssinians"
}
],
"fieldValue": "Cats"
},
{
"nodes": [
{
"title": "Teckels"
},
{
"title": "Poodles"
}
],
"fieldValue": "Dogs"
}
]
}
}
}
Now we can create paginated pages in gatsby-node.js
. An implementation could look like this:
import { paginate } from 'gatsby-awesome-pagination';
exports.createPages = ({ actions, graphql }) => {
const { createPage } = actions;
const { data } = await graphql(`
query {
allWordpressPost {
group(field: categories___name) {
nodes {
title
# any other post data you need
}
fieldValue
}
}
}
`)
// create paginated pages for each category
data.allWordpressPost.group.forEach(({ nodes: posts, fieldValue: category }) => {
paginate({
createPage,
items: posts,
itemsPerPage: 10,
pathPrefix: category, // use category name for pages
component: path.resolve('...'), // your template for post lists
})
// TODO create a page for each post
// you can do it manually or use the plugin's `createPagePerItem` API:
// https://github.com/GatsbyCentral/gatsby-awesome-pagination#createpageperitem
}
}
The key here is to take advantage of GraphQL to build the right query.
Hope it helps!
来源:https://stackoverflow.com/questions/59419055/paginating-gatsbyjs-pages-when-filtering-wordpress-posts-by-category