我想从特定博客文章转到上一篇文章和下一篇文章。
考虑一下,这个盖茨比的例子 - https://gatsby-starter-blog-demo.netlify.com/my-second-post/
它在页面底部有2个链接 -
←你好世界这是一个以前的帖子和新的开始→这是一个下一篇文章
要动态使用它,我需要访问帖子的slug但我怎么能得到它?由于使用了GraphQL,在Gatsby中很简单。
但是,在Next中,我只能使用preval hack来获取帖子。我如何获得slug以便我可以在我的特定博客中实现上一篇和下一篇文章?
甚至Next JS's own blog也没有Next Post和Previous Post链接。
查看any post on Next JS's Blog,你会发现一个返回博客按钮,但没有以前的帖子或下一个帖子按钮。
分页相当简单。您可以使用static async getInitialProps
方法从查询中获取请求的页面。
然后你可以使用button
和Router.push
来强制路由器,或者使用Link
来声明性地路由。
class PaginationTest extends React.Component {
static async getInitialProps ({query: {page = 1}}) {
const data = await fetchPage(page)
return {
page: parseInt(page, 10),
data
}
}
render () {
return (
<div>
// render data
<button
onClick={() => Router.push(`/page=${this.props.page + 1}`)}
disabled={this.props.page <= 1}
>Next Button</button>
<Link href={`/page=${this.props.page + 1}`}>
<a>Next Link</a>
</Link>
</div>
)
}
}
Here is a working codesandbox: https://codesandbox.io/s/6w3k5yzqmn
因为您正在生成静态站点,所以我假设您只关心从Next.JS的服务器端解决这个问题。为此,您基本上需要编写一个名为getNextPost(current)
的函数来获取当前帖子(只是文件名或完整对象)并扫描您的帖子目录以获取下一个目录。对于Next.JS的服务器端,您在Node中,因此您可以使用fs
包来扫描文件系统。
理想情况下,这意味着每个文件名应该有一个时间戳或类似的前缀(例如2019-02-22_13-45-53-my-second-post.html
),这样你就可以使用一个简单的排序来确定下一篇文章是什么。否则,你需要实际解析每个帖子文件,以便以这种方式提取日期信息(我相信Gatsby是如何工作的,肯定是Hugo所做的)。
无论哪种方式,我建议将所有帖子文件解析为内存缓存一次,这样您就不必每次都扫描posts目录。
首先,你必须问自己“先前的帖子”和“下一篇文章”是什么意思,以及你如何找到它们。 你能表达出来吗?回答这个问题将解决您的大多数问题,而不是Next.js相关的问题。
一旦你澄清了这个问题,“如何添加上一个和下一个帖子链接”这个问题的答案就是mrvdot和lipp提供的内容。
创建一个getNextPost
和getPreviousPost
函数。假设你有增量ID,一个简单(而不是健壮)的例子是:
const getPreviousPost = currentPostId => getPost(currentPostId - 1)
const getNextPost = currentPostId => getPost(currentPostId + 1)
然后,一旦你有了这个,你可以在你的Post组件的getInitialProps
中查询你的上一篇和下一篇文章以及你当前的帖子
class Post extends React.Component {
static async getInitialProps ({id}) {
const post = await getPost(id)
const previousPost = await getPreviousPost(id)
const nextPost = await getNextPost(id)
return {
post,
previousPost,
nextPost,
}
}
getPreviousPost = currentPostId => getPost(currentPostId - 1)
getNextPost = currentPostId => getPost(currentPostId + 1)
render ({post, previousPost, nextPost}) {
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
<Link href={previousPost.url}><a>Previous post</a></Link>
<Link href={nextPost.url}><a>Next post</a></Link>
</div>
)
}
}
或类似的东西。那有意义吗?