尝试使用 Contentful 将帖子列表添加到我的主页而不是 Gatsby 中的单独页面

Posted

技术标签:

【中文标题】尝试使用 Contentful 将帖子列表添加到我的主页而不是 Gatsby 中的单独页面【英文标题】:Trying to add a list of posts to my homepage instead of a separate page in Gatsby using Contentful 【发布时间】:2021-10-06 00:30:21 【问题描述】:

我希望在我的主页上放置一个帖子列表,而不是创建一个单独的动态页面。这是我的gatsby-node.js 文件

// DYNAMICALLY CREATE PAGES FOR EACH POST
module.exports.createPages = async ( graphql, actions, reporter ) => 
  const  createPage  = actions;
  const postTemplate = path.resolve('src/templates/news.js');
  const postResult = await graphql(`
    query 
      allContentfulPost 
        edges 
          node 
            slug
          
        
      
    
  `);

  // Handle errors
  if (postResult.errors) 
    reporter.panicOnBuild('Error while running GraphQL query.');
    return;
  

  // Create the pages for each markdown file
  postResult.data.allContentfulPost.edges.forEach(( node ) => 
    createPage(
      component: postTemplate,
      path: `/news/$node.slug`,
      context: 
        slug: node.slug,
      ,
    );
  );

  // PAGINATION FOR BLOG POSTS
  const postsResult = await graphql(`
    
      allContentfulPost(sort:  fields: date, order: DESC , limit: 1000) 
        edges 
          node 
            slug
          
        
      
    
  `);

  if (postsResult.errors) 
    reporter.panicOnBuild('Error while running GraphQL query.');
    return;
  

  // Create blog-list pages
  const posts = postsResult.data.allContentfulPost.edges;
  const postsPerPage = 12;
  const postNumPages = Math.ceil(posts.length / postsPerPage);
  Array.from( length: postNumPages ).forEach((_, i) => 
    createPage(
      path: i === 0 ? '/' : `/news/$i + 1`,
      component: path.resolve('./src/templates/news-list.js'),
      context: 
        limit: postsPerPage,
        skip: i * postsPerPage,
        postNumPages,
        currentPage: i + 1,
      ,
    );
  );
;

这是我的news-list.js 文件

import React from 'react';
import  Link, graphql  from 'gatsby';

import Layout from '../components/layout';
import SEO from '../components/seo';

export const query = graphql`
  query ($skip: Int!, $limit: Int!) 
    allContentfulPost(sort:  fields: date, order: DESC , limit: $limit, skip: $skip) 
      edges 
        node 
          title
          slug
          date(formatString: "MMMM Do, YYYY")
        
      
    
  
`;

const NewList = (props) => 
  // const  postNumPages  = props.pageContext;

  const posts = props.data.allContentfulPost.edges;

  return (
    <Layout>
      <SEO title='News' />

      posts.map(( node ) => 
        const title = node.title || node.slug;
        return (
          <div className='container mx-auto prose prose-lg'>
            <div className='mb-2'>
              <Link to=`/posts/$node.slug`>
                <h3 className='underline font-sans mb-1'>title</h3>
              </Link>

              <div className='flex items-center justify-between'>
                <span className='font-mono text-sm'>node.date</span>
              </div>
            </div>
          </div>
        );
      )
    </Layout>
  );
;

export default NewList;

我尝试将上述news-list.js 作为组件从我的模板文件夹导入到我的index.js 文件夹中。但是我得到了错误:

TypeError: Cannot read property 'allContentfulPost' of undefined

但如果我将 path: i === 0 ? '/news' : /news/$i + 1, 添加到我的节点文件中并转到 localhost/news 我会得到帖子列表。

但我希望它们出现在主页上.. 所以我想如果我只拥有/ 它会起作用的结果不是。

我怎样才能让LH/news 列出的帖子显示在我的主页上。

更新

最新答案后的新组件

import React from 'react';
import  useStaticQuery, graphql, Link  from 'gatsby';

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

// import News from '../components/news';
// import NewsList from '../templates/news-list';

export const query = graphql`
  
    allContentfulPost(sort:  fields: date, order: DESC , limit: 1000) 
      edges 
        node 
          title
          slug
          date(formatString: "MMMM Do, YYYY")
        
      
    
  
`;

const Index = ( data ) => 
  const  site  = useStaticQuery(
    graphql`
      query 
        site 
          siteMetadata 
            companyname
          
        
      
    `
  );

  return (
    <Layout>
      <section className='c-mt-10'>
        <div className=''>
          <div className='font-mono md:flex md:justify-between'>
            <div className='mb-5'>
              <a href=`mailto:hello@$site.siteMetadata.companyname.co.uk`>
                hello@pfbsite.siteMetadata.companyname.co.uk
              </a>
              <br />
              <br />
              <tel>+44 020 3925 6054</tel>
            </div>

            <a
              href='https://www.google.com/maps/place/Warnford+Court,+29+Throgmorton+St,+London+EC2N+2AT/@51.5154096,-0.0890419,17z/data=!3m1!4b1!4m5!3m4!1s0x48761cacb440b98d:0x9742679143333ff!8m2!3d51.5154096!4d-0.0868479'
              target='_blank'
              rel='noreferrer'>
              <address className='text-right'>
                Warnford Court
                <br />
                29 Throgmorton Street
                <br /> London, EC2N 2AT
              </address>
            </a>
          </div>
        </div>

        <div>
          <h2>Company News</h2>
          <ul>
            data.allContentfulPost.edges.map(( node ) => (
              <li key=node.title>
                <Link to=node.slug>node.title</Link>
              </li>
            ))
          </ul>
        </div>
      </section>
    </Layout>
  );
;
export default Index;

【问题讨论】:

news-list.js 是 Gatsby 页面组件吗(即它是否存在于 pages 文件夹中)? 不,这存在于模板目录中 【参考方案1】:

我认为你混合了很多概念。

一件事是gatsby-node.js 查询,可用于基于参数(在您的情况下为slug)基于动态数据(在您的情况下来自 Contentful CMS)创建动态页面。

另一件事是page queries,一种在***组件(页面或模板,而不是组件)中检索数据的方法。

如果你想在你的主页上列出你的所有帖子,你只需要创建一个 GraphQL 查询并循环遍历结果,就像这样:

const IndexPage = ( data ) => 

   return <Layout> 
    <ul>
    data.allContentfulPost.edges.map((node)=> <li key=node.title><Link to=node.slug>title</Link></li>)
    </ul>
   </Layout>



export const query = graphql`
    
      allContentfulPost(sort:  fields: date, order: DESC , limit: 1000) 
        edges 
          node 
            title
            slug
            date(formatString: "MMMM Do, YYYY")
          
        
      
    
`;

使用页面查询时,您的数据存储在props.data 中,因此您可以将它们直接解构为data

在您的情况下,您是在页面中导入模板,这没有多大意义,因为您没有查询等。

【讨论】:

这是有道理的,我在您的更新中添加了一个新组件,但仍然收到相同的错误:( 正如我所说,页面查询仅在***组件(页面)中可用。它不能是一个孤立的组件,它必须在主页本身。如果你复制粘贴 sn-p,应该单独工作。 完美的工作......我现在可以重建它周围的索引页面 @mrpbennett 您可以在常规旧组件中使用StaticQuery,查看文档:gatsbyjs.com/docs/how-to/querying-data/use-static-query 当然可以,但对我来说,在这种情况下(从概念上)这不是静态查询的目的。它们的行为与页面查询略有不同,并且以不同的方式重新水合(它们在每次渲染中被触发)组件。但你是对的,这是另一种获取数据的方式

以上是关于尝试使用 Contentful 将帖子列表添加到我的主页而不是 Gatsby 中的单独页面的主要内容,如果未能解决你的问题,请参考以下文章

我正在尝试将某种小部件或菜单添加到我所有 Wordpress 网站页面的顶部

使用表格显示添加的用户及其数据

我如何将 wordpress 帖子添加到我的 html 网站中,该博客位于 myurl.com/blog

如何将“标签”添加到我的简单博客帖子类库和存储库?

使用 Gatsby Contentful 显示所有博客文章

如何将数据从 Firebase 检索到我的适配器