
Hugo Page 方法详解RegularPagesRecursive 递归获取当前 Section 及全部子孙 Section 的常规页面【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugoRegularPagesRecursive是 Hugo 中Page对象提供的一个集合访问方法用于返回当前 section 内以及所有子孙 section 内的全部常规页面kind 为page的内容页面。本文以 docs/content/en/methods/page/RegularPagesRecursive.md 为骨架结合仓库中 hugolib/page.go、resources/page/page.go 等源码实现与测试用例完整讲解它的适用页面类型、递归语义、排序规则、与RegularPages/Pages的差异以及底层查询链路。读完本文你可以在首页、列表页模板中准确构建包含全部子栏目内容的目录页、归档页等实战场景。方法签名与适用页面类型该方法的接口定义位于 resources/page/page.go 的ChildCareProvider接口中// RegularPagesRecursive returns all regular pages below the current // section. RegularPagesRecursive() Pages返回类型page.Pages即一个可迭代的页面集合可用对象Page对象可用页面类型page kindshome首页、section栏目、taxonomy分类列表页和term分类条目页。这些页面类型的模板在 context 中会收到一个页面 collection并以 default sort order默认排序呈现。需要特别注意的是文档明确指出RegularPagesRecursive方法在Site对象上不可用。若需在Site级别获取全站常规页面应使用Site.RegularPages。术语提示文中的 page kinds、collection、context、default sort order 是 Hugo 文档体系的词汇表术语分别对应页面类型体系、页面集合、模板上下文与默认排序规则。基本用法在模板中遍历页面集合在模板中通过range遍历集合即可。典型写法如下见 RegularPagesRecursive.md{{ range .RegularPagesRecursive.ByTitle }} h2a href{{ .RelPermalink }}{{ .Title }}/a/h2 {{ end }}这里对结果调用了.ByTitle按标题排序因此输出顺序是确定的。你也可以先取数量再遍历{{ $pages : .RegularPagesRecursive }} {{ len $pages }} 篇 {{ range $pages }} {{ .Title }} → {{ .RelPermalink }} {{ end }}在 Hugo 的测试中如 hugolib/pagecollections_test.go遍历时通常会同时输出.Kind与.RelPermalink用于断言结果只包含 kind 为page的条目Sect1 RegularPagesRecursive: {{ range $sect1.RegularPagesRecursive }}{{ .Kind }}:{{ .RelPermalink}}|{{ end }}|End.递归语义结合内容结构逐层验证RegularPagesRecursive的核心语义是递归它不只返回当前 section 直属的常规页面还会深入所有子孙 section 收集常规页面。文档给出了如下内容结构示例content/ ├── lessons/ │ ├── lesson-1/ │ │ ├── _index.md │ │ ├── part-1.md │ │ └── part-2.md │ ├── lesson-2/ │ │ ├── resources/ │ │ │ ├── task-list.md │ │ │ └── worksheet.md │ │ ├── _index.md │ │ ├── part-1.md │ │ └── part-2.md │ ├── _index.md │ ├── grading-policy.md │ └── lesson-plan.md ├── _index.md ├── contact.md └── legal.md其中_index.md是分支束section 自身其余.md文件是 kind 为page的常规页面。渲染首页home时RegularPagesRecursive返回全站所有常规页面首页位于站点根部其当前 section即整个站点contact.md lessons/grading-policy.md legal.md lessons/lesson-plan.md lessons/lesson-2/part-1.md lessons/lesson-1/part-1.md lessons/lesson-2/part-2.md lessons/lesson-1/part-2.md lessons/lesson-2/resources/task-list.md lessons/lesson-2/resources/worksheet.md注意contact.md、legal.md位于根级目录同样被包含_index.md不会被包含。渲染 lessons 栏目页时返回 lessons 自身及其全部子孙 sectionlesson-1、lesson-2、resources内的常规页面共 8 个lessons/grading-policy.md lessons/lesson-plan.md lessons/lesson-2/part-1.md lessons/lesson-1/part-1.md lessons/lesson-2/part-2.md lessons/lesson-1/part-2.md lessons/lesson-2/resources/task-list.md lessons/lesson-2/resources/worksheet.md渲染 lesson-1 栏目页时lesson-1 没有任何子孙 section因此等价于返回其直属常规页面lessons/lesson-1/part-1.md lessons/lesson-1/part-2.md渲染 lesson-2 栏目页时lesson-2 下还有子孙 sectionresources/因此递归结果包含两层的常规页面lessons/lesson-2/part-1.md lessons/lesson-2/part-2.md lessons/lesson-2/resources/task-list.md lessons/lesson-2/resources/worksheet.md从这四个场景可以总结出规律结果 当前 section 直属常规页面 所有子孙 section 的常规页面递归展开分支束_index.md与其它 kind 的页面一律不包含。与 RegularPages、Pages 的对比content-management 文档 中对此有明确提示section 的列表页默认只包含其直属页面不含子孙页面若要包含子孙页面应在section模板中使用RegularPagesRecursive而不是Pages。三者差异可归纳如下方法包含内容典型用途.Pages当前节点下的全部页面含 section 等分支节点展示本节内容 子栏目入口的目录.RegularPages当前 section 直属的常规页面不递归只展示本级文章列表.RegularPagesRecursive当前 section 及所有子孙 section 的常规页面递归生成全部文章归档、全文检索列表从实现上看RegularPages与RegularPagesRecursive的区别仅在于查询参数Recursive是否为true详见下文源码分析。源码级原理从 pageState 到页面树的查询链路方法实现按页面类型分派RegularPagesRecursive的实体实现位于 hugolib/page.gofunc (ps *pageState) RegularPagesRecursive() page.Pages { switch ps.Kind() { case kinds.KindSection, kinds.KindHome: return ps.s.pageMap.getPagesInSection( pageMapQueryPagesInSection{ Path: ps.Path(), Include: pagePredicates.ShouldListLocal.And(pagePredicates.KindPage).BoolFunc(), Recursive: true, }, ) default: return ps.RegularPages() } }从中可以读出两层信息section 与 home 走递归查询查询条件Include为ShouldListLocal应被列出的本地页面排除翻译占位等与KindPagekind 为page的合取Recursive置为truetaxonomy / term 回退到 RegularPages文档声明该方法对 taxonomy、term 页面同样可用但从源码结构看这两种 kind 会走default分支委托给RegularPages()即不展开子孙 section。RegularPages对KindTaxonomy走非递归的getPagesInSection对KindTerm则按术语匹配查询见 hugolib/page.go。底层查询遍历页面树并缓存实际查询发生在 hugolib/content_map_page.go 的getPagesInSection。关键点包括前缀定位用paths.AddTrailingSlash(q.Path)构造当前 section 的路径前缀树遍历通过doctree.NodeShiftTreeWalker在treePages页面树上从该前缀开始遍历当q.Recursive为真时对沿途每个命中include谓词的*pageState直接收集不跳过任何子分支非递归模式则遇到分支节点cnh.isBranchNode时调用w.SkipPrefix跳过其子树结果缓存查询结果通过getOrCreatePagesFromCache按查询 key 缓存同一查询在构建周期内重复调用不会重复遍历hugolib/content_map_page.go。这意味着每次调用RegularPagesRecursive的成本是可接受的底层是一棵按路径组织的 radix 树上的前缀遍历且结果带缓存。测试用例行为验证与重建、多语言场景仓库中针对该方法有专门测试可作为行为契约参考hugolib/pagecollections_test.goTestRegularPagesRecursive构造了两级嵌套 sectionsect1下还有sect1_s2断言site.GetPage sect1的RegularPagesRecursive返回ps1、ps2以及深层ps2_1验证递归穿透TestRegularPagesRecursiveHome验证首页场景根目录的p1.md与post/子 section 的p2.md都会被收集。hugolib/rebuild_test.go覆盖增量重建场景——删除内容文件、修改标题后len .RegularPagesRecursive会随之更新同时验证多语言/翻译场景下输出会按语言隔离如/translations/p7/与/en/translations/p7/。hugolib/hugo_sites_build_test.go在多站点/多主机构建中验证RegularPagesRecursive的遍历输出。hugolib/pagesfromdata/pagesfromgotmpl_integration_test.go验证由数据/模板生成的页面pagesfromdata特性同样会出现在RegularPagesRecursive结果中。hugolib/pages_test.go在页面方法遍历测试中登记该方法确保所有页面类型调用它不会产生副作用。实战注意事项排序不是递归的产物RegularPagesRecursive返回的是已按默认排序规则weight → date → title/link title排列的集合。若两个页面标题相同输出顺序依赖默认排序的平局处理需要确定性顺序时建议显式调用.ByTitle、.ByDate等方法或在 front matter 中设置weight。递归包含子栏目文章注意聚合页语义在 lessons 这样的父栏目列表页使用该方法时子栏目lesson-1、lesson-2的文章会一并出现适合做全量归档但不适合做仅本级目录——后者请用.RegularPages。在Site对象上不可用全站维度的递归集合没有Site.RegularPagesRecursive请改用Site.RegularPages全站所有常规页面或在首页模板中使用.RegularPagesRecursive。_index.md不参与结果分支束与普通页面在页面树中是不同节点Include谓词限定了KindPage因此_index.md永远不会出现在结果里无需额外过滤。结合其他模板函数组合使用返回的page.Pages可以继续接where、first、groupBy等函数例如{{ range first 10 (.RegularPagesRecursive.ByDate.Reverse) }}即可在父栏目页实现全部子栏目最新 10 篇。小结RegularPagesRecursive是构建树形栏目全量内容视图的核心方法它以home/section为起点沿页面树递归收集所有 kind 为page的常规页面底层由getPagesInSection的前缀遍历与缓存机制支撑并被 hugolib/pagecollections_test.go、hugolib/rebuild_test.go 等测试锁定行为。需要本节 全部子栏目文章时优先选择它需要仅本级列表时使用.RegularPages需要站点级全量列表时使用Site.RegularPages。【免费下载链接】hugoThe world’s fastest framework for building websites.项目地址: https://gitcode.com/gh_mirrors/hu/hugo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考