尝试使用 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 网站页面的顶部