Grav框架中如何按dd-mm-yyyy hh:mm格式对集合按日期排序?
解决Grav中dd-mm-yyyy格式日期的集合排序问题
你的问题根源很明确:Grav默认会把header.date的字符串值按字符顺序排序,而不是解析成日期对象处理。比如28-05-2005和15-05-2017,字符串比较时1开头的会排在2开头的前面,完全忽略年份的大小,这就导致了排序错误。
下面给你两种可行的解决方案,按推荐程度排序:
方案一:改用ISO标准日期格式(推荐)
这是最省心的方式,直接把所有页面的日期格式改成Grav原生支持的YYYY-MM-DD HH:mm格式,比如把:
date: '15-09-2015 13:00'
改成:
date: '2015-09-15 13:00'
修改后,你原来的collections配置不需要任何改动,Grav会自动识别日期类型并正确排序。
方案二:保留现有日期格式,使用自定义排序回调
如果你不想修改大量页面的日期格式,可以通过自定义排序逻辑来解析dd-mm-yyyy hh:mm格式的日期,转换成时间戳后再排序。
步骤如下:
- 在你的主题目录下(比如
user/themes/your-theme/)创建一个PHP文件,比如custom-sort.php,内容如下:
<?php use Grav\Common\Page\Page; function customDateSort(Page $a, Page $b) { // 解析dd-mm-yyyy hh:mm格式的日期为时间戳 $dateA = DateTime::createFromFormat('d-m-Y H:i', $a->header()->date); $dateB = DateTime::createFromFormat('d-m-Y H:i', $b->header()->date); // 按时间戳升序排序(如果要降序就交换$dateA和$dateB的位置) return $dateA->getTimestamp() - $dateB->getTimestamp(); }
- 在你的页面frontmatter中修改collections配置,使用
custom排序方式,并指定回调函数:
--- title: Noticias content: items: '@self.children' order: by: custom func: customDateSort pagination: true limit: 10 ---
- 确保这个PHP文件被Grav加载,你可以直接把函数代码放到主题的
theme.php的onPluginsInitialized事件里,或者在主题配置中添加加载逻辑。
这样配置后,Grav会调用你的自定义函数,把每个页面的日期解析成DateTime对象,再通过时间戳比较来实现正确的排序。
注意事项
- 如果你的页面中有日期格式不统一的情况,
DateTime::createFromFormat会返回false,可能导致排序异常,所以要确保所有页面的日期格式都是严格的dd-mm-yyyy hh:mm。 - 方案二的自定义排序会比原生排序稍微消耗一点性能,但对于普通博客的页面数量来说,完全可以忽略。
内容的提问来源于stack exchange,提问作者M.E.
相关产品推荐
相关产品推荐

