开发博客时想在侧边栏添加一个文章归档功能,这方面的资料太少了
下面说说我的思路,希望对你有帮助
效果大概是这样的:
- 2021-4
- 2020-9
- 2020-8
点击链接查询相应月份发布的文章
首先需要拿到所有的日期,转成 2021-4
这样的格式并且去重
const dateList = await Article.find({}, {createdDate: 1}).sort({createdDate: -1})
const archive = []
dateList.forEach(item => {
archive.push(dayjs(item.createdDate).format('YYYY-MM'))
})
res.locals.archives = Array.from(new Set(archive))
await next()
从数据库到所有的日期后使用 dayjs
转成 2021-4
这样的格式,用set去重,由于不管用户从哪个页面进入都要加载侧边栏,于是我就把这段代码写在了调用路由前的中间件上:app.all(’/*’,xxxx),并且设置了全局变量(可以在模板引擎中拿到)。缺陷就是加载每个路由都要调用这个中间件,会影响性能,目前我还没有想到更好的解决思路。
我用的art模板引擎,具体页面这样写:
{{each archives}}
<li><a href="/category/{{$value.split('-')[0]}}/{{$value.split('-')[1]}}" class="text-muted">{{$value}}</a></li>
{{/each}}
点击 2021-4
跳转到路由 /category/2021/4
,首页、归档、分类这样类似需求的使用同一个页面上,在路由中接受两个参数
const {year, month} = req.params
if (year && month) {
articles = await Article.find({
createdDate: {
$gt: new Date(year, month - 1),
$lt: new Date(year, month)
}
}).sort({createdDate: -1})
return res.render('home/index', {
articles
})
}
如果页面接收到 year
和 month
,就根据日期筛选文章,否则就查询所有数据渲染主页面。
这里有一个小坑就是 new Date()
的月份是从 0 开始,所以要筛选条件就这样写