资讯详情

资讯详情

Hugo Pager 的 TotalNumberOfElements 方法:获取分页集合的全部元素总数

Hugo Pager 的 TotalNumberOfElements 方法获取分页集合的全部元素总数【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoTotalNumberOfElements是 Hugo 分页器Pager提供的一个统计型方法返回整个分页集合的元素总数——即被分页的页面或页面组的总数量与当前处于哪一页无关。本文基于当前仓库的官方方法文档与源码实现完整讲解该方法的使用方式、与NumberOfElements的本质区别、底层实现原理以及可验证的测试行为帮助你写出信息准确的列表页统计与分页导航。方法签名与返回值在 Pager 方法文档 的体系下TotalNumberOfElements的官方定义如下项目内容方法名TotalNumberOfElements返回类型int签名PAGER.TotalNumberOfElements说明返回分页器集合中的元素总数Returns the number of pages in the pager collection官方定义位于 TotalNumberOfElements.md。从源码结构看该方法实际定义在Paginator类型上而Pager结构体通过嵌入*Paginator字段见 resources/page/pagination.go实现了方法提升因此在模板中无论持有分页器对象还是单个页面的 Pager 对象都可以直接调用func (p *Paginator) TotalNumberOfElements() int { return p.total }来源resources/page/pagination.goTotalNumberOfElements 与 NumberOfElements 的区别这是最容易混淆的一对方法。虽然名字只差一个词语义却完全不同方法作用范围含义TotalNumberOfElements整个分页器所有分页页面上的元素总数等价于被分页集合的完整大小如所有 posts 文章总数NumberOfElements当前页当前这一页上的元素数量最后一页可能小于每页大小pagerSize两个方法的实现都位于 resources/page/pagination.go// NumberOfElements gets the number of elements on this page. func (p *Pager) NumberOfElements() int { return p.element().Len() } // TotalNumberOfElements returns the number of elements on all pages in this paginator. func (p *Paginator) TotalNumberOfElements() int { return p.total }来源resources/page/pagination.go、resources/page/pagination.go举例共有 21 篇文章、每页 5 篇时分页器会产生 5 页。此时第 1 页的NumberOfElements为 5TotalNumberOfElements为 21第 5 页最后一页的NumberOfElements为 1TotalNumberOfElements仍为 21。NumberOfElements的官方文档见 NumberOfElements.md。模板中的完整用法基础示例官方文档原例以下是官方文档给出的标准用法先用where筛选出全部 posts 页面再通过.Paginate生成分页器最后在with作用域内输出元素总数{{ $pages : where site.RegularPages Type posts }} {{ $paginator : .Paginate $pages }} {{ range $paginator.Pages }} h2a href{{ .RelPermalink }}{{ .LinkTitle }}/a/h2 {{ end }} {{ with $paginator }} {{ .TotalNumberOfElements }} {{ end }}这里{{ .Paginate $pages }}返回*Pager对象由于Pager嵌入了*Paginator{{ .TotalNumberOfElements }}通过字段提升访问到Paginator的方法。用{{ with $paginator }}包裹后作用域内的.即指向分页器对象。在列表页展示共 N 篇统计TotalNumberOfElements最常见的实战场景是在博客列表页显示文章总数{{ $pages : where site.RegularPages Type posts }} {{ $paginator : .Paginate $pages 10 }} ul {{ range $paginator.Pages }} lia href{{ .RelPermalink }}{{ .LinkTitle }}/a/li {{ end }} /ul p共 {{ $paginator.TotalNumberOfElements }} 篇文章分为 {{ $paginator.TotalPages }} 页。/p {{ with $paginator }} nav {{ with .Prev }}a href{{ .URL }}上一页/a{{ end }} span第 {{ .PageNumber }} / {{ .TotalPages }} 页/span {{ with .Next }}a href{{ .URL }}下一页/a{{ end }} /nav {{ end }}注意{{ .Paginate $pages 10 }}中的10是可选参数用于覆盖全局默认的每页大小其合法性由ResolvePagerSize校验必须是正整数。在分页导航中判断最后一页的剩余数量结合PageNumber、TotalPages与TotalNumberOfElements可以计算当前页是否包含不满一页的尾巴{{ with $paginator }} {{ $start : add (mul (sub .PageNumber 1) .PagerSize) 1 }} {{ $end : add $start (sub .NumberOfElements 1) }} p正在显示第 {{ $start }}–{{ $end }} 篇共 {{ .TotalNumberOfElements }} 篇/p {{ end }}这里$end之所以用NumberOfElements而非直接加PagerSize正是为了正确处理最后一页元素不足的情况。pagerSize 配置如何影响该方法的返回值TotalNumberOfElements返回的是集合的总大小因此不受每页大小影响但pagerSize决定分页器被切成多少页、以及每页的NumberOfElements分布理解它有助于解释你看到的数字。全局配置在站点配置文件如hugo.toml中通过[pagination]段落配置[pagination] pagerSize 10 # 每个分页页面的默认元素数量默认值为 10 path page # 分页 URL 的路径元素如 /page/2/ disableAliases false # 是否禁用第一个分页页面的别名生成对应的配置结构体定义于 config/commonConfig.go// Pagination configures the pagination behavior. type Pagination struct { // Default number of elements per pager in pagination. PagerSize int // The path element used during pagination. Path string // Whether to disable generation of alias for the first pagination page. DisableAliases bool }pagerSize的默认值 10 定义在 config/allconfig/alldecoders.go。按语言覆盖配置分页配置支持语言级覆盖。仓库中的集成测试 allconfig_integration_test.go 验证了这一点英语站点设置pagerSize 20德语站点设置path page-de未显式设置的德语站点pagerSize回落到默认值 10[languages.en] weight 1 [languages.en.pagination] pagerSize 20 [languages.de] weight 2 [languages.de.pagination] path page-de通过方法参数临时覆盖在模板中调用.Paginate/.Paginator时可以传入第二个参数临时指定每页大小其解析逻辑见 ResolvePagerSize未传参数时读取全局配置传入多个参数或非正整数时返回错误。源码实现total 是如何被计算出来的要理解TotalNumberOfElements为什么总是等于被分页集合的完整大小需要追踪Paginator中total字段的填充链路全部位于 resources/page/pagination.go入口Paginate判断传入的序列是PagesGroup还是Pages分别走不同的构造路径resources/page/pagination.gofunc Paginate(td TargetPathDescriptor, seq any, pagerSize int) (*Paginator, error) { ... groups, ok, err : ToPagesGroup(seq) if ok { paginator, _ newPaginatorFromPageGroups(groups, pagerSize, urlFactory) } else { pages, err : ToPages(seq) ... paginator, _ newPaginatorFromPages(pages, pagerSize, urlFactory) } return paginator, nil }构造分页器newPaginatorFromPages用len(pages)作为totalnewPaginatorFromPageGroups用pageGroups.Len()作为totalresources/page/pagination.gofunc newPaginatorFromPages(pages Pages, size int, urlFactory paginationURLFactory) (*Paginator, error) { split : splitPages(pages, size) return newPaginator(split, len(pages), size, urlFactory) } func newPaginatorFromPageGroups(pageGroups PagesGroup, size int, urlFactory paginationURLFactory) (*Paginator, error) { split : splitPageGroups(pageGroups, size) return newPaginator(split, pageGroups.Len(), size, urlFactory) }newPaginator落盘把total存入Paginator结构体同时按切分结果生成编号从 1 开始的Pager列表resources/page/pagination.go。即使集合为空也会生成一个编号为 1 的Pager此时total 0。切分逻辑splitPages按pagerSize把页面切成一串paginatedElementresources/page/pagination.go最后一组不足pagerSize时保留剩余元素——这正是最后一页NumberOfElements小于PagerSize的原因。由此可见total在分页器创建时就被固定为输入集合的大小之后不随翻页变化因此无论在哪个分页页面调用TotalNumberOfElements结果都一致。测试验证行为有据可查仓库中的单元测试与集成测试对上述行为做了严格断言。单元测试21 个元素、每页 5 个resources/page/pagination_test.go 中的doTestPages验证了 21 个元素按每页 5 个切分后产生 5 页并同时断言TotalNumberOfElements、TotalPages、各页NumberOfElements的取值c.Assert(len(paginatorPages), qt.Equals, 5) c.Assert(paginator.TotalNumberOfElements(), qt.Equals, 21) c.Assert(paginator.PagerSize(), qt.Equals, 5) c.Assert(paginator.TotalPages(), qt.Equals, 5) ... c.Assert(first.NumberOfElements(), qt.Equals, 5) // 第一页5 个 ... c.Assert(last.NumberOfElements(), qt.Equals, 1) // 最后一页1 个注意第一页NumberOfElements为 5、最后一页为 1而TotalNumberOfElements恒为 21——这正是当前页元素数与全部元素数的直观对照。单元测试空集合的边界行为同一文件中的doTestPagerNoPagesresources/page/pagination_test.go验证了空集合的边界此时TotalNumberOfElements为 0、TotalPages为 0、PagerSize仍为配置值且仍存在一个编号为 1 的Pagerc.Assert(paginator.TotalNumberOfElements(), qt.Equals, 0) c.Assert(paginator.PagerSize(), qt.Equals, 5) c.Assert(paginator.TotalPages(), qt.Equals, 0) ... c.Assert(pageOne.PageNumber(), qt.Equals, 1)集成测试真实站点构建中输出总数hugolib/paginator_test.go 的TestPaginateOutputFormat构建了一个包含 22 个页面的真实站点在layouts/index.json中直接输出总数并断言public/index.json中结果为22JSON: {{ .Paginator.TotalNumberOfElements }}: {{ range .Paginator.Pages }}|{{ .RelPermalink }}{{ end }}:DONEb.AssertFileContent(public/index.json, JSON: 22 |/p1/index.json|/p2/index.json| )此外同一测试文件中的TestPaginatorhugolib/paginator_test.go还验证了[pagination]配置pagerSize 3、path thepage在真实构建中对分页 URL如/foo/thepage/2/、TotalPages、Next/Prev链接的实际影响。常见疑问与使用注意TotalNumberOfElements与len .Pages有什么区别.Pages返回的是当前页上的页面集合见 resources/page/pagination.golen .Pages等于当前页的NumberOfElements而TotalNumberOfElements是整个分页集合的大小。若想表达总共多少篇文章请使用后者。空集合时会怎样返回 0同时TotalPages为 0但仍存在一个可安全遍历的Pager编号 1模板逻辑不会因空集合崩溃。方法能否在单页模板中使用分页仅在列表类页面首页、section、taxonomy 等受支持。在单页模板中调用.Paginator会得到错误pagination not supported for this page此行为由集成测试TestPaginatorNodePagesOnly锁定hugolib/paginator_test.go。返回类型是 int可直接用于算术运算如乘法、比较也可以安全地通过printf %d输出不会产生 HTML 转义问题。小结TotalNumberOfElements是 Hugo 分页体系中一个简单但高频使用的统计方法它返回被分页集合的完整元素数量与当前页无关且对空集合有明确的 0 值边界。结合本文梳理的pagerSize配置、源码构造链路与测试断言你可以在列表页中准确呈现共 N 篇、分为 M 页的统计信息并正确区分它和当前页元素数NumberOfElements的语义差异。相关实现与文档可继续在 resources/page/pagination.go、hugolib/paginator_test.go 与 Pager 方法文档目录 中深入阅读。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →