GatsbyJS 博客中的分页

Posted

技术标签:

【中文标题】GatsbyJS 博客中的分页【英文标题】:Pagination in GatsbyJS blog 【发布时间】:2020-09-01 12:16:45 【问题描述】:

我在我的第一个 GatsbyJS 项目中创建了一个博客,我对 React 和 Gatsby 很陌生

博客本身运行良好,我正在通过降价文件提取内容,但我很难让分页部分正常工作。

我有 4 个页面 blogTemplate(每个博客文章的模板)、posts.js(循环浏览并在单个登录页面上显示每个博客文章)、blog.js(将所有博客文章拉入一个来自帖子页面的数组并将它们显示在卡片中)和我的 gatsby-node.js 页面(正在处理博客的 graphql)

下面是我正在使用的所有文件的列表,底部是我尝试实现的一些插件

blogTemplate.js

import React from "react";
import  graphql, Link  from "gatsby";
import  Container, Row, Col, Image  from "react-bootstrap";

import Layout from "../components/layout";

export default function Template( data ) 
    const post = data.markdownRemark;
    const  markdownRemark  = data // data.markdownRemark holds your post data
    const  frontmatter, html  = markdownRemark
    const  title, author, date, thumbnail  = post.frontmatter;
    return (
      <Layout>
      <Container  className="px-0" >
      <Row>
        <Col>
          <Container className="mt-5 mb-5">
            <h1>title</h1>
    <p>Posted by author on date thumbnail thumbnail</p>
    <Image src=thumbnail alt=thumbnail fluid />
            <div dangerouslySetInnerHTML= __html: post.html  />
            <Link to="/blog">Back to blogs</Link>
          </Container>
        </Col>
      </Row>
    </Container> 


        </Layout>
    )
  ;

  export const postQuery = graphql`
  query BlogPost($path: String!) 
    markdownRemark(frontmatter:  path:  eq: $path ) 
      html
      frontmatter 
        author
        date
        title
        path
        description
        thumbnail
      
      html
    
  
`;

Posts.js

import React from "react"
import  Link  from "gatsby"
import  Card  from 'react-bootstrap';


const PostLink = ( post ) => (
  <Card className="cardpadding">
      <Card.Img variant="top" src=post.frontmatter.thumbnail alt=post.frontmatter.title />
      <Card.Body className="dark-text">
        <p>post.frontmatter.date</p>
          <Card.Title>post.frontmatter.title</Card.Title>
          <Card.Text className="blue-text">
          <Link to=post.frontmatter.path className="post-link">
            post.frontmatter.title
          </Link>
          </Card.Text>
      </Card.Body>
  </Card>
)
export default PostLink

blog.js

import React from "react"
import  graphql  from "gatsby"
import Post from "../components/post";
import Layout from "../components/layout"
import  Container  from "react-bootstrap";

const BlogPage = (
  data: 
    allMarkdownRemark:  edges ,
  ,
) => 

const Posts = edges
.filter(edge => !!edge.node.frontmatter.date) // You can filter your posts based on some criteria
.map(edge => <Post key=edge.node.id post=edge.node />)
console.log('Posts', Posts)

return (
  <Layout>
    <Container className="mt-5">
    <div className="grids">
      Posts
    </div>
    </Container>
  </Layout>
)


export default BlogPage
export const AllBlogsQuery = graphql`
  query AllBlogPosts 
    allMarkdownRemark(
      sort:  order: DESC, fields: [frontmatter___date] 
      ) 
      edges 
        node 
          id
          frontmatter 
            date(formatString: "MMMM DD, YYYY")
            title
            description
            author
            path
            thumbnail
          
        
      
    
  
`

gatsby-node.js

const path = require("path");

exports.createPages = ( actions, graphql ) => 
  const  createPage  = actions;
  const postTemplate = path.resolve("src/templates/blogTemplate.js");

  return graphql(`
  
    allMarkdownRemark(
      sort:  order: DESC, fields: [frontmatter___date] 
      limit: 1000
    ) 
      edges 
        node 
          id
          frontmatter 
            path
          
        
      
    
  
`).then(res => 
    if (res.errors) 
      return  Promise.reject(res.errors)
    
    res.data.allMarkdownRemark.edges.forEach(( node ) => 
      createPage(
        path: node.frontmatter.path,
        component: postTemplate,
        context: , // additional data can be passed via context
      )
    )
  )
;

我尝试过的

我尝试在下面的 gatsby-node 文件中添加 gatsby-paginate 插件。 但是,当我现在单击单个博客页面链接时,出现 404 错误。

盖茨比-node.js

const path = require("path");
const paginate = require('gatsby-paginate')


exports.createPages = async ( actions, graphql ) => 
  const  createPage  = actions;
  //const postTemplate = path.resolve("src/templates/blogTemplate.js");

  const ya = await graphql(`
  
    allMarkdownRemark(
      sort:  order: DESC, fields: [frontmatter___date] 
      limit: 1000
    ) 
      edges 
        node 
          id
          frontmatter 
            path
          
        
      
    
  
`);

paginate(
  createPage,
  items: ya.data.allMarkdownRemark.node,
  itemsPerPage: 2,
  pathPrefix: '/blog',
  component: path.resolve("src/templates/blogTemplate.js")
);

ya.data.allMarkdownRemark.node.map(articleData => 
      createPage(
        path: node.frontmatter.path,
        component: path.resolve("src/components/post.js"),
        context: , // additional data can be passed via context
    )
  );

【问题讨论】:

能否请您提供任何堆栈闪电战???? 您能详细说明您遇到的错误吗? (我认为这 404 是您的问题所在)。为什么是404?网址错了吗?它路由到什么,它应该是什么? (提示:Gatsby 开发 404 页面应该向您显示实际开发包中的页面列表) 【参考方案1】:

我解决了这个问题,错误出现在我的 gatsby-node.js 文件中。

将两个模板分解为单独的变量,然后将数据传递给每个模板是我想要实现的正确方法

见下面的 gatsby-node.js 文件

const path = require('path')
const  slugify  = require('./src/util/utilityFunctions')
const _ = require('lodash')

exports.onCreateNode = ( node, actions ) => 
  const  createNodeField  = actions
  if (node.internal.type === 'MarkdownRemark') 
    const slugFromTitle = slugify(node.frontmatter.title)
    createNodeField(
      node,
      name: 'slug',
      value: slugFromTitle,
    )
  


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

  // Page templates
  const templates = 
    post: path.resolve('src/templates/single-post.js'),
    postList: path.resolve('src/templates/post-list.js')
  

  const res = await graphql(`
    
      allMarkdownRemark 
        edges 
          node 
            frontmatter 
              author
              tags
            
            fields 
              slug
            
          
        
      
    
  `)

  if (res.errors) return Promise.reject(res.errors)

  // Extracting all posts from res
  const posts = res.data.allMarkdownRemark.edges

  // Create single post pages
  posts.forEach(( node ) => 
    createPage(
      path: node.fields.slug,
      component: templates.post,
      context: 
        // Passing slug for template to use to fetch the post
        slug: node.fields.slug
      ,
    )
  )

  // Create posts pagination pages
  const postsPerPage = 4
  const numberOfPages = Math.ceil(posts.length / postsPerPage)

  Array.from( length: numberOfPages ).forEach((_, index) => 
    const isFirstPage = index === 0
    const currentPage = index + 1
    // Skip first page because of index.js
    if (isFirstPage) return

    createPage(
      path: `/page/$currentPage`,
      component: templates.postList,
      context: 
        limit: postsPerPage,
        skip: index * postsPerPage,
        numberOfPages: numberOfPages,
        currentPage: currentPage,
      ,
    )
  )

【讨论】:

以上是关于GatsbyJS 博客中的分页的主要内容,如果未能解决你的问题,请参考以下文章

GatsbyJS :访问保存在降价文件(GraphQL)中的博客文章的不同部分

Django搭建个人博客平台7---自定义基于Bootstrap的分页组件

Django搭建个人博客平台7---自定义基于Bootstrap的分页组件

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

thinkphp简洁美观靠谱的分页类

一款基于jQuery的分页插件