You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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未正确获取数据

相关代码

{{ 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 }}

错误原因说明

  1. 直接使用{{ with .Params.card_data }}时,.Params.card_data是字符串类型,尝试读取.title字段自然会报错
  2. .Resources.Get用于获取当前页面关联的资源文件(如页面目录下的附件),无法访问data目录下的全局数据,所以之前的transform.Unmarshal方案方向错误

内容的提问来源于stack exchange,提问作者NinjaOtt3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 10:33:39