尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Hugo 页面集合分组方法 GroupByParamDate:按自定义日期参数分组页面

Hugo 页面集合分组方法 GroupByParamDate:按自定义日期参数分组页面 Hugo 页面集合分组方法 GroupByParamDate按自定义日期参数分组页面【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoPAGES.GroupByParamDate是 Hugo 中用于将页面集合按照页面 Front Matter 中自定义日期参数进行分组的方法分组结果默认按日期降序排列且分组键会根据当前站点的语言与地区进行本地化格式化。它特别适合自定义事件日期活动日程纪念日等不以页面内置date、publishdate为准而是以业务自定义日期字段为分组依据的场景。读完本文你将掌握该方法完整的签名与返回值、布局字符串layout string语法、升降序控制、组内页面再排序技巧以及其底层实现与测试行为。方法签名与返回值签名PAGES.GroupByParamDate PARAM LAYOUT [SORT]返回类型page.PagesGroup说明按照给定的页面参数PARAM中的日期值以指定的时间布局LAYOUT将页面集合分组分组默认按降序descending排列。其中PARAMFront Matter 中自定义参数的名称支持点号嵌套路径例如custom_object.dateLAYOUT与time.Format相同的布局字符串用于决定分组键的展示粒度如只到年、到年月、到年月日SORT可选分组排序方向asc表示升序desc表示降序见 group-sort-order.md。返回的PagesGroup是一个PageGroup列表每个PageGroup包含两个字段Key分组键any类型和Pages该组内的页面集合。相关类型定义与注释位于 resources/page/pagegroup.go// PageGroup represents a group of pages, grouped by the key. // The key is typically a year or similar. type PageGroup struct { // The key, typically a year or similar. Key any // The Pages in this group. Pages }基础用法按自定义日期参数分组假设站点中的若干页面在 Front Matter 中定义了自定义日期参数例如eventDate并希望以年 月为单位分组展示。以下模板代码取自原文档可直接放入列表页模板中使用{{ range .Pages.GroupByParamDate eventDate January 2006 }} p{{ .Key }}/p ul {{ range .Pages }} lia href{{ .RelPermalink }}{{ .LinkTitle }}/a/li {{ end }} /ul {{ end }}执行逻辑为遍历.Pages读取每页 Front Matter 中的eventDate参数按布局January 2006将日期格式化为分组键例如April 2012默认按日期降序返回分组组内页面同样按该参数日期排序降序。控制分组排序方向通过可选的第三个参数指定分组排序方向。以下示例将分组按日期升序排列{{ range .Pages.GroupByParamDate eventDate January 2006 asc }} p{{ .Key }}/p ul {{ range .Pages }} lia href{{ .RelPermalink }}{{ .LinkTitle }}/a/li {{ end }} /ul {{ end }}原文档强调组内的页面也会按参数日期排序方向与分组排序方向一致升序或降序。这一点在测试TestGroupByParamDateInReverseOrder中有明确印证见 resources/page/pagegroup_test.go调用pages.GroupByParamDate(custom_date, 2006-01, asc)后期望分组键依次为2012-01、2012-03、2012-04且组内页面同样按日期升序排列。组内页面重新排序如果希望组内页面不按日期、而是按其他属性如标题排序可在组内调用任意页面排序方法。例如按标题排序{{ range .Pages.GroupByParamDate eventDate January 2006 }} p{{ .Key }}/p ul {{ range .Pages.ByTitle }} lia href{{ .RelPermalink }}{{ .Title }}/a/li {{ end }} /ul {{ end }}其他常用的组内排序方法还包括ByDate、ByPublishDate、ByExpiryDate、ByLastmod、ByWeight、ByLength等相关文档见 methods/pages 目录。Layout string 布局字符串GroupByParamDate的LAYOUT参数与time.Format函数的布局字符串格式完全一致均基于 Go 的参考时间reference timeMon Jan 2 15:04:05 MST 2006常用布局组件如下完整表格见 time-layout-string.md含义合法组件年份2006 06月份Jan January 01 1星期Mon Monday月内日期2 _2 02年内日期__2 002小时15 3 03分钟4 04秒5 05上午/下午标记PM时区偏移-0700 -07:00 -07 -070000 -07:00:00需要注意的几点来自公共片段文档PST、CET这类字符串是时区缩写而非时区-07:00、01:00这类字符串是时区偏移而非时区。真正的时区是地理区域例如缩写PST/PDT对应的时区是America/Los_Angeles若希望时区偏移在 UTC 时输出Z而非偏移量可将布局中的符号替换为Z如Z0700 Z07:00 Z07等。分组结果键.Key会根据当前渲染站点的语言与地区进行本地化localized for language and region因此同一布局字符串在不同语言站点下会输出本地化的月份、星期名称。参数值类型与底层实现原理GroupByParamDate的底层实现位于 resources/page/pagegroup.go。核心流程分为两阶段第一阶段读取参数并排序sortersorter : func(pages Pages) Pages { var r Pages for _, p : range pages { param : resource.GetParam(p, key) var t time.Time if param ! nil { var ok bool if t, ok param.(time.Time); !ok { // Probably a string. Try to convert it to time.Time. t cast.ToTime(param) } } dates[p] t r append(r, p) } pdate : func(p1, p2 Page) bool { return dates[p1].Unix() dates[p2].Unix() } pageBy(pdate).Sort(r) return r }从源码可以看出参数值首先尝试直接断言为time.Time类型若失败则通过cast.ToTime尝试将字符串转换为time.Time对应历史 issue #3983 的修复测试见 TestGroupByParamDateWithStringParams每个页面的日期值会被缓存到datesmap 中随后按Unix()时间戳进行排序。第二阶段按布局字符串分组groupByDateFieldfunc (p Pages) groupByDateField(format string, sorter func(p Pages) Pages, getDate func(p Page) time.Time, order ...string) (PagesGroup, error) { sp : sorter(p) if !(len(order) 0 (strings.ToLower(order[0]) asc || ...)) { sp sp.Reverse() } ... currentSite : firstPage.Site().Current() formatter : langs.GetTimeFormatter(currentSite.Language()) formatted : formatter.Format(date, format) ... }要点如下排序方向判断只有显式传入asc或源码中同样支持的rev、reverse变体时才保持升序否则一律降序本地化实现分组格式化使用langs.GetTimeFormatter(currentSite.Language())即当前渲染站点的语言格式化器——这印证了文档中分组键针对语言与地区本地化的说明页面集合可能混有多种语言因此这里取第一个页面所属 Site 的当前语言作为格式化语言见源码注释 Pages may be a mix of multiple languages...。空集合行为当页面集合为空时方法直接返回nil, nil不会报错。测试 TestGroupByParamDateWithEmptyPages 验证了这一行为。嵌套参数支持PARAM支持点号嵌套路径例如custom_object.date、custom_object.string_date分别对应测试 TestGroupByParamDateNested 与 TestGroupByParamDateNestedWithStringParams。与相关分组方法的对比GroupByParamDate属于 Hugo 页面分组方法家族中的一员理解它与近亲方法的差异有助于正确选型方法分组依据默认排序说明GroupByParamDate自定义参数中的日期降序本文主题自定义日期参数GroupByDate页面内置日期默认date字段降序见 GroupByDate.mdGroupByPublishDatepublishdate降序见 GroupByPublishDate.mdGroupByExpiryDateexpirydate降序见 GroupByExpiryDate.mdGroupByLastmodlastmod降序见 GroupByLastmod.mdGroupByParam自定义参数非日期升序见 GroupByParam.md从源码结构看GroupByDate、GroupByPublishDate、GroupByExpiryDate、GroupByLastmod与GroupByParamDate都复用了同一个groupByDateField辅助函数区别仅在于取哪个日期字段和如何排序见 resources/page/pagegroup.go。GroupByParamDate与GroupByParam的差异在于前者将参数值按时间解析并格式化为分组键后者则直接以参数原始值作为分组键。常见使用场景与注意事项典型场景活动/会议站点的日程归档页按自定义的eventDate分组展示即将举办/历史活动或者对带有自定义发布日期参数如releaseDate的产品文档进行按月归档。注意事项确保 Front Matter 中的参数值可被解析为日期time.Time或可转换的字符串如2012-04-06否则该页面的日期值将是零值时间可能被归入异常分组若页面未定义该参数源码中param nil时该页面会得到一个零值时间并参与排序见 sorter 实现需要结合自身数据评估影响LAYOUT字符串决定了分组粒度与键的显示格式例如2006只按年分组、January 2006按年月分组、2006-01-02按天分组组内默认按参数日期排序如需其他顺序请显式调用组内排序方法。结语GroupByParamDate为 Hugo 模板提供了按自定义日期参数分组页面集合的声明式能力一行模板即可完成参数读取、时间解析、格式化分组、本地化与排序的全部工作。其底层实现resources/page/pagegroup.go清晰地展示了时间参数的类型兼容time.Time与字符串、语言本地化格式化以及统一的groupByDateField分组管线配合 resources/page/pagegroup_test.go 中覆盖降序、升序、嵌套参数、字符串参数与空集合的完整测试用例开发者可以在自己的 Hugo 站点中放心、准确地使用该方法构建按日期归档的内容展示。延伸阅读方法文档原文GroupByParamDate.md分组排序说明asc/descgroup-sort-order.md布局字符串参考time-layout-string.md同类分组方法GroupByDate.md、GroupByParam.md底层实现resources/page/pagegroup.go测试用例resources/page/pagegroup_test.go【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表