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

Posted

技术标签:

【中文标题】如何在 GatsbyJS 中对属于特定类别的帖子列表进行分页【英文标题】:How to paginate a list of posts belonging to a specific category in GatsbyJS 【发布时间】:2019-04-26 16:16:44 【问题描述】:

我用 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")
          
        
      
    
  
`

这不起作用,现在抛出错误:错误 gatsby-node.js 返回错误,TypeError: _.kebabCase is not a function

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

有人知道吗?

谢谢!

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

以上是关于如何在 GatsbyJS 中对属于特定类别的帖子列表进行分页的主要内容,如果未能解决你的问题,请参考以下文章

如何在wordpress中检查帖子是不是属于分类类别的子类别

获取带有特定类别附件的帖子?

在 Wordpress Datewise 中为特定类别创建存档

如何查询多对多

显示月存档链接中特定类别的帖子?

使用Twig和WordPress,如何确定帖子是否属于某个类别?