Hugo模板中如何使用where函数查询.Site.Data站点数据
Hugo模板.Site.Data条件查询实现方法
问题场景
需要在Hugo模板中对.Site.Data存储的数据做条件筛选,示例JSON数据结构如下(假设文件存放在data/blog/posts.json):
{ "my-blog-post": { "Version": 21, "Revision": 0, "Code": "my-blog-post", "Name": "My Blog Post", "Parent": "the-parent-post" }, "another-post": { "Version": 21, "Revision": 0, "Code": "another-post", "Name": "Another Post", "Parent": "the-parent-post" } }
需求为在文章详情页,筛选出所有Parent字段等于当前文章标识的子文章列表。之前尝试的where写法无法生效:
{{$child_posts := where (where .Site.Data "Section" "blog") "Parent" "the-parent-post" }}
遍历站点页面的实现方案不符合需求:
{{$posts := where $site.Pages "Section" "blog"}} {{ range sort $posts "Name" "asc" }} {{ $post := . }} {{if eq $post.parent $currentPage.Code}} ...Do something... {{end}} {{end}}
失效原因
之前的where写法不生效有两个核心问题:
.Site.Data是全站所有数据文件的根映射节点,直接对根节点调用where不会自动读取目标JSON文件的内容- 存储的JSON是键值对象结构,不是
where函数原生支持的数组/切片类型,无法直接做字段匹配筛选
正确实现方法
- 先定位到具体的数据集:根据数据文件存放路径,找到对应的数据节点,比如存放在
data/blog/posts.json的数据,对应访问路径为.Site.Data.blog.posts - 将键值对象转换为值切片:用内置函数将对象的所有属性值提取为切片,才能供
where筛选 - 执行条件匹配后排序遍历即可
可直接复用的代码
如果使用Hugo 0.83.0及以上版本,可直接用collections.Values提取对象值:
{{/* 提取数据对象所有值生成切片 */}} {{ $allPosts := .Site.Data.blog.posts | collections.Values }} {{/* 筛选Parent字段匹配当前文章Code的子文章 */}} {{ $childPosts := where $allPosts "Parent" .Params.Code }} {{/* 排序后遍历渲染 */}} {{ range sort $childPosts "Name" "asc" }} <div class="child-post"> <h3>{{ .Name }}</h3> </div> {{ end }}
如果是低版本Hugo不支持collections.Values,可手动遍历拼接切片:
{{ $allPosts := slice }} {{ range $_, $post := .Site.Data.blog.posts }} {{ $allPosts = $allPosts | append $post }} {{ end }} {{ $childPosts := where $allPosts "Parent" .Params.Code }}
注意:Hugo读取JSON数据时字段名大小写敏感,模板里写的筛选字段必须和JSON里的字段名大小写完全一致,比如JSON里是大写开头的
Parent,模板里就不能写小写的.parent,否则会匹配失败。
内容的提问来源于stack exchange,提问作者moddayjob
相关产品推荐
相关产品推荐

