Hugo模板动态调用data目录YML数据失败的技术问询
动态调用Hugo Data目录YAML数据的解决方案
问题场景
需要通过card_gallery.html模板实现不同页面展示对应卡片内容:
- 卡片数据存储在
data目录下的YAML文件中 - 页面的Front Matter里定义
card_data参数,指定要引用的数据路径 - 硬编码
{{ with site.Data.page_content }}时模板正常渲染,但将路径以字符串存入card_data后,使用{{ with .Params.card_data }}会报错:无法在string类型中解析title字段 - 尝试
transform.Unmarshal未正确获取数据
相关代码
原card_gallery.html模板
{{ define "main" }} {{ partial "header" }} {{ with .Params.card_data }} <section class="wrap-w"> <div class="inner align-center"> <h2>{{ .title }}</h2> <p><em>{{ .content }}</em></p> </div> <div class="gallery"> {{ range .cards }} {{ partial "card" . }} {{ end }} </div> </section> {{ end }} {{ end }}
data/page_content.yml数据文件
title: "Look at this content!" content: highlights cards: - title: "Chasing Windmills" content: "Somewhere in Texas - 2024" image: "/images/gallery/thumbs/windmills_thumb.jpg" - title: "Chasing Windmills" content: "Somewhere in Texas - 2024" image: "/images/gallery/thumbs/windmills_thumb.jpg" - title: "Chasing Windmills" content: "Somewhere in Texas - 2024" image: "/images/gallery/thumbs/windmills-looking-back_thumb.jpg"
尝试transform.Unmarshal后的错误代码
{{ define "main" }} {{ partial "header" }} {{ $data := dict }} {{ $path := (index .Params "card_data") | string }} <p> {{ $path | string }}</p> {{ with .Resources.Get $path }} {{ with . | transform.Unmarshal }} {{ $data = . }} <p>{{ $data }}</p> {{ end }} {{ end }} <p> {{ $data }}</p> {{ with $data }} <section class="wrap-w"> <div class="inner align-center"> <h2>{{ .title }}</h2> <p>{{ .content }}</p> </div> <div class="gallery"> {{ range .cards }} {{ partial "card" . }} {{ end }} </div> </section> {{ end }} {{ end }}
调试输出
site.Data.page_contentmap[] map[]
解决方案
核心原理
Hugo会自动加载data目录下的所有YAML/JSON/TOML文件到site.Data对象中,无需手动读取解析。动态调用的关键是用index函数,通过字符串参数定位到site.Data中的对应数据结构。
基础版本(单层数据路径)
如果card_data参数是单层名称(比如page_content),直接用index函数获取:
{{ define "main" }} {{ partial "header" }} {{/* 从site.Data中动态获取指定数据 */}} {{ $cardData := index site.Data .Params.card_data }} {{ with $cardData }} <section class="wrap-w"> <div class="inner align-center"> <h2>{{ .title }}</h2> <p><em>{{ .content }}</em></p> </div> <div class="gallery"> {{ range .cards }} {{ partial "card" . }} {{ end }} </div> </section> {{ end }} {{ end }}
进阶版本(支持嵌套数据路径)
如果数据文件是嵌套在data子目录中(比如data/gallery/page_content.yml,card_data设为gallery.page_content),需要拆分路径字符串后逐层索引:
{{ define "main" }} {{ partial "header" }} {{/* 处理嵌套数据路径,拆分字符串为层级数组 */}} {{ $pathParts := split .Params.card_data "." }} {{ $cardData := site.Data }} {{/* 逐层遍历路径,定位到目标数据 */}} {{ range $pathParts }} {{ $cardData = index $cardData . }} {{ end }} {{ with $cardData }} <section class="wrap-w"> <div class="inner align-center"> <h2>{{ .title }}</h2> <p><em>{{ .content }}</em></p> </div> <div class="gallery"> {{ range .cards }} {{ partial "card" . }} {{ end }} </div> </section> {{ end }} {{ end }}
错误原因说明
- 直接使用
{{ with .Params.card_data }}时,.Params.card_data是字符串类型,尝试读取.title字段自然会报错 .Resources.Get用于获取当前页面关联的资源文件(如页面目录下的附件),无法访问data目录下的全局数据,所以之前的transform.Unmarshal方案方向错误
内容的提问来源于stack exchange,提问作者NinjaOtt3r
相关产品推荐
相关产品推荐

