尧图精选

Hugo Pager.PageGroups 方法详解:对分页集合按分组渲染

🕒 发布时间:2026/9/19 5:13:25 📁 来源:尧图网络
Hugo Pager.PageGroups 方法详解对分页集合按分组渲染【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoPageGroups是 Hugo 中Pager对象提供的方法用于在分页pagination场景下获取当前分页器pager的页面分组page.PagesGroup。它专为「先分组、再分页」的渲染模式设计当你在列表页模板中先用GroupByDate、GroupBy等分组方法对页面集合分组再调用.Paginate分页时每个分页器内保存的不再是扁平页面列表而是PagesGroup分组结构。通过PageGroups你可以直接在模板中遍历分组键如年份、月份与分组内的页面构建出「按年份/月份分块的博客归档页」这类经典布局。读完本文你将掌握PageGroups的返回类型与适用条件、它与Pages方法的互斥关系、与全部分组方法GroupByDate、GroupBy、GroupByParam等的组合用法、底层分页器对分组数据的切分原理以及搭配内置分页导航模板的完整落地示例。方法签名与返回类型PageGroups方法的官方签名定义如下PAGER.PageGroups → page.PagesGroup适用对象分页器对象Pager即调用.Paginate或.Paginator后返回的对象。返回类型page.PagesGroup即一组PageGroup的列表。每个PageGroup由两部分组成——Key分组键通常是年份、月份等和Pages该分组下的页面集合。该类型定义在 resources/page/pagegroup.go 中type PageGroup struct { // The key, typically a year or similar. Key any // The Pages in this group. Pages }从源码结构看Key的类型是any可以承载字符串如日期格式化的Jan 2006、整数、前端参数值等任意分组键Pages直接内嵌了页面集合因此模板中可以沿用Pages上的一切方法如.ByTitle、.Limit等对分组内页面做进一步处理。与 Pages 方法的互斥关系Pager上有两个「二选一」的取数方法Pages与PageGroups。两者不能同时返回非空结果具体行为由底层存储的分页元素类型决定。在 resources/page/pagination.go 的实现中可以看到这段关键逻辑// Pages returns the Pages on this page. // Note: If this return a non-empty result, then PageGroups() will return empty. func (p *Pager) Pages() Pages { ... if pages, ok : p.element().(Pages); ok { return pages } return paginatorEmptyPages } // PageGroups return Page groups for this page. // Note: If this return non-empty result, then Pages() will return empty. func (p *Pager) PageGroups() PagesGroup { ... if groups, ok : p.element().(PagesGroup); ok { return groups } return paginatorEmptyPageGroups }也就是说当你把「普通页面集合」传给.Paginate如.Paginate $pages每个分页器内部元素是Pages切片此时用Pages()取数PageGroups()返回空。当你把「分组结果」传给.Paginate如.Paginate ($pages.GroupByDate Jan 2006)每个分页器内部元素是PagesGroup此时用PageGroups()取数Pages()返回空。另外当分页器没有任何元素时例如对空集合分组后再分页两个方法都会返回预定义的空值paginatorEmptyPages/paginatorEmptyPageGroups模板中的range会安全地跳过不会报错——这一点由 hugolib/paginator_test.go 中的TestPaginatorEmptyPageGroups测试用例对应 Issue 10802验证对空集合执行GroupByPublishDate后再分页len $pag.Pages为 0页面正常渲染。使用前置条件分组方法官方文档明确指出PageGroups需要与任意的分组方法配合使用。Hugo 提供的分组方法全部定义在 resources/page/pagegroup.go 中返回类型统一为PagesGroup方法分组依据签名GroupByDate页面date字段默认取前端元数据中的datePAGES.GroupByDate LAYOUT [SORT]GroupByPublishDate页面publishDate字段PAGES.GroupByPublishDate LAYOUT [SORT]GroupByExpiryDate页面expireDate字段PAGES.GroupByExpiryDate LAYOUT [SORT]GroupByLastmod页面lastmod字段PAGES.GroupByLastmod LAYOUT [SORT]GroupByParam页面指定参数key的值PAGES.GroupByParam KEY [SORT]GroupByParamDate页面参数中的日期值PAGES.GroupByParamDate KEY LAYOUT [SORT]GroupBy页面任意字段或方法的值PAGES.GroupBy KEY [SORT]所有方法都支持可选的排序参数asc、desc、rev、reverse后三者等价于降序。日期类分组的默认顺序是降序最新的在前这一点在groupByDateField的实现中体现除非显式传入asc、rev或reverse否则分组前会先对页面集合执行Reverse()。分组键的本地化对于日期类分组LAYOUT参数使用与time.Format相同的 Go 时间布局字符串如Jan 2006、2006分组键会根据当前站点的语言和地区进行本地化。从 resources/page/pagegroup.go 的源码可以看到格式化器取自当前渲染站点的语言currentSite : firstPage.Site().Current() formatter : langs.GetTimeFormatter(currentSite.Language()) formatted : formatter.Format(date, format)这意味着多语言站点中同一篇内容在不同语言列表页上会得到对应语言的分组键例如英文站点显示January 2026中文站点显示2026年1月。官方示例按月分组的博客归档页PageGroups最典型的使用场景是按时间分组的归档列表。官方文档 PageGroups 给出的完整示例{{ $pages : where site.RegularPages Type posts }} {{ $paginator : .Paginate ($pages.GroupByDate Jan 2006) }} {{ range $paginator.PageGroups }} h2{{ .Key }}/h2 {{ range .Pages }} h3a href{{ .RelPermalink }}{{ .LinkTitle }}/a/h3 {{ end }} {{ end }} {{ partial pagination.html . }}这段模板的执行流程where site.RegularPages Type posts筛选出类型为posts的常规页面构建待分组集合$pages.GroupByDate Jan 2006按「年月」分组得到PagesGroup如Mar 2026、Feb 2026…….Paginate (...)对分组结果进行分页返回分页器对象range $paginator.PageGroups遍历当前分页器的分组外层输出分组键.Key如Mar 2026内层range .Pages输出该分组下的每篇文章标题与链接partial pagination.html .调用 Hugo 内置的分页导航模板渲染上一页/下一页及页码链接。分页器对分组的切分原理把分组结果交给.Paginate后Hugo 是如何按页大小切分分组的关键实现在 resources/page/pagination.go 的splitPageGroups函数中。其策略是先把所有分组「展平」成键值对序列再按页大小切成若干段最后在每段内重建分组结构。func splitPageGroups(pageGroups PagesGroup, size int) []paginatedElement { type keyPage struct { key any page Page } var ( split []paginatedElement flattened []keyPage ) for _, g : range pageGroups { for _, p : range g.Pages { flattened append(flattened, keyPage{g.Key, p}) } } ... }这意味着分页边界可能出现在某个分组内部如果pagerSize 5而某个月份有 8 篇文章那么该月份可能被拆到相邻两个分页器上每个分页器各自持有该月份的部分页面键相同但页面不同。因此分页器上的分组键并不保证完整覆盖该分组的全部页面——这正是按PageGroups逐页渲染时需要注意的行为。展平后的重建逻辑会保持组内页面相对顺序并按页大小重新聚合每遇到新的键值就新建一个PageGroup把后续同键页面追加进去见 resources/page/pagination.go。此外分页器内部的page()方法resources/page/pagination.go也支持从PagesGroup中按全局索引取页面用于计算NumberOfElements等派生数据因此你仍然可以正常使用Pager.NumberOfElements()等方法。多语言项目中的分组键本地化实践将PageGroups与多语言配置结合时分组键会自动跟随当前渲染语言。你可以在项目配置中为每种语言分别设置分页参数官方分页配置说明 configuration/pagination 给出的多语言示例[languages.en] contentDir content/en direction ltr label English locale en-US weight 1 [languages.en.pagination] disableAliases true pagerSize 10 path page [languages.de] contentDir content/de direction ltr label Deutsch locale de-DE weight 2 [languages.de.pagination] disableAliases true pagerSize 20 path blatt配合GroupByDate时不同语言站点会使用各自的地区格式器生成分组键模板无需任何改动即可输出本地化的年份/月份标题。与内置分页导航模板的配合PageGroups只负责渲染「当前页的分组内容」分页导航上一页、下一页、页码列表通常由 Hugo 内置模板partial pagination.html提供它支持两种格式{{ partial pagination.html . }} !-- default 格式 -- {{ partial pagination.html (dict page . format terse) }} !-- terse 格式 --default格式控件与页码槽位更多terse格式占用更少空间适合水平排列的紧凑导航。如需定制可将内置模板源码复制为layouts/_partials/pagination.html后自行修改。如果要完全自研导航也可以组合使用Pager的其他方法详见 methods/pager 下的各方法文档PageNumber()当前页码、TotalPages()总页数、HasPrev()/HasNext()、Prev()/Next()、First()/Last()、URL()分页器 URL等全部在 resources/page/pagination.go 中实现。常见误区与注意事项不要同时使用Pages与PageGroups二者按分页元素的类型互斥。对分组结果分页却调用Pages()或对普通集合分页却调用PageGroups()都会得到空结果。分组后不要在range中重复分页与普通分页一样同一列表页上首次调用分页方法的结果会被缓存重复调用不会按预期重新执行这是 Hugo 分页最常见的模板错误详见 templates/pagination 的缓存说明。分组键跨页拆分如前文源码分析所述当某分组元素数超过每页容量时该组可能被拆分到多个分页器每个分页器只包含该组的子集渲染时按当前分页器所见为准。空集合安全对空页面集合分组后再分页不会报错PageGroups()返回空分组range自然跳过参考测试 hugolib/paginator_test.go。分组键类型GroupBy/GroupByParam的键可以是任意类型字符串、整数等而日期类分组的键是本地化后的字符串模板中输出.Key时请按实际类型处理。小结PageGroups是 Hugo 分页体系中连接「分组」与「分页」两个特性的桥梁。它让你能够先按日期、参数或任意字段把文章集合组织成分组再对分组结果分页最终在每个分页器内按「分组键 → 分组内页面」的两级结构渲染内容。其底层实现resources/page/pagination.go 与 resources/page/pagegroup.go清晰展示了PagesGroup的类型结构、分页切分算法与空值安全策略。掌握了PageGroups你就能轻松实现博客按月归档、按标签分类的无限分页列表等常见实战布局。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →