如何在GatsbyJS中对属于特定类别的帖子列表进行分页

时间:2018-11-24 10:01:14

标签: node.js reactjs pagination graphql gatsby

我使用Gatsby JS开发了一个博客,并设法将类别添加到每个markdown文件中,以便我可以通过查询特定类别来创建页面并列出与该类别相关的所有帖子。 现在,我正在尝试添加分页功能,以避免每个类别页面内的帖子数量无限。

我一直在这里关注官方指南:https://www.gatsbyjs.org/docs/adding-pagination/

这是我想出的代码:

gatsby-node.js

const path = require('path')
const _ = require("lodash")
const { createFilePath } = require("gatsby-source-filesystem")

exports.createPages = ({actions, graphql}) => {
const {createPage} = actions

const articleTemplate = path.resolve(`src/templates/article.js`)
const categoryTemplate = path.resolve("src/templates/category.js")

return new Promise((resolve, reject) => {
    resolve(
      graphql(
          `
            {
                allMarkdownRemark(
                    sort: { order: DESC, fields: [frontmatter___date] }
                    limit: 2000
                ) {
                    edges {
                        node {
                            html
                            id
                            frontmatter {
                                path
                                title
                                categories
                            }
                        }
                    }
                }
            }

    `).then(result => {
        if (result.errors) {
            reject(result.errors)
        }

        const articles = result.data.allMarkdownRemark.edges
        const articlesPerPage = 6
        const numPages = Math.ceil(articles.length / articlesPerPage)

        //Creating a page for each article
        articles.forEach(({ node }) => {
            createPage({
            path: node.frontmatter.path,
            component: articleTemplate,
            //context: {}, // additional data can be passed via context
            })
        })

        // Categories pages:
        let categories = []
        // Iterate through each article, putting all found categories into `categories`
        _.each(articles, edge => {
            if (_.get(edge, "node.frontmatter.categories")) {
                categories = categories.concat(edge.node.frontmatter.categories)
            }
        })


        Array.from({ length: numPages }).forEach((category, _, i) => {
            createPage({
              path: i === 0 ? `/${_.kebabCase(category)}/` : `/${_.kebabCase(category)}/${i + 1}`,
              component: categoryTemplate,
              context: {
                limit: articlesPerPage,
                skip: i * articlesPerPage,
                category,
              },
            })
        })
    })
)
})

/templates/categories.js

import React from "react"
import PropTypes from "prop-types"
import Layout from '../layouts/layout'
import ArticleCard from '../components/articles/articlecard'

// Components
import { Link, graphql } from "gatsby"

const _ = require("lodash")

const Categories = ({ pageContext, data }) => {
  const { category } = pageContext
  const { edges } = data.allMarkdownRemark

  return (
    <Layout>
        <section class="hero is-info is-medium has-text-centered">
            <div class="hero-body">
                <div class="container">
                    <h1 class="title is-top">
                        {category}
                    </h1>
                </div>
            </div>
        </section>
        <div class="section">
            <div class="container">
                <div class="columns is-multiline">
                    {edges.map(({ node }) => {
                        const { path, title, date } = node.frontmatter
                        return (
                            <div class="column is-half">
                                <div class="card">
                                    <div class="card-header">
                                        <p class="card-header-content">{date}</p>
                                    </div>
                                    <div class="card-content">
                                    <Link to={_.kebabCase(category)}><span class="tag is-success has-padding">{category}</span></Link>
                                        <Link to={path}>
                                            <h2 class="title is-4">{title}</h2>
                                        </Link>
                                    </div>
                                    <div class="card-footer">
                                        <div class="card-footer-item"><Link to={path}><div class="button is-success is-inverted is-fullwidth">Read</div></Link></div>
                                        <div class="card-footer-item"><Link to={path}><div class="button is-info is-inverted is-fullwidth">Share on Linkedin</div></Link></div>
                                    </div>        
                                </div>
                            </div>
                        )
                    })}
                </div>
            </div>
        </div>
    </Layout>
  )
}

Categories.propTypes = {
  pageContext: PropTypes.shape({
    category: PropTypes.string.isRequired,
  }),
  data: PropTypes.shape({
   allMarkdownRemark: PropTypes.shape({
      totalCount: PropTypes.number.isRequired,
      edges: PropTypes.arrayOf(
        PropTypes.shape({
          node: PropTypes.shape({
            frontmatter: PropTypes.shape({
              path: PropTypes.string.isRequired,
              title: PropTypes.string.isRequired,
            }),
          }),
        }).isRequired
      ),
    }),
  }),
}

export default Categories

export const pageQuery = graphql`
  query($skip: Int!, $limit: Int!, $category: String) {
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      filter: { frontmatter: { categories: { in: [$category] } } }
      limit: $limit
      skip: $skip
    ) {
      totalCount
      edges {
        node {
          frontmatter {
            title
            path
            date(formatString: "MMMM DD, YYYY")
          }
        }
      }
    }
  }
`

这不起作用,现在抛出错误:error gatsby-node.js返回了错误,TypeError:_.kebabCase不是函数

但是,在修改查询以添加分页之前,kebabCase的使用很顺畅,因此我认为问题实际上并不存在。

有人有任何线索吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

您两次声明变量“下划线”:
1-来自lodash库
2-来自forEach函数:

Array.from({ length: numPages }).forEach((category, _, i)

只需将第二个变量更改为另一个任意名称,如下所示:

Array.from({ length: numPages }).forEach((category, otherName, i)