在Hugo中有条件地渲染多个部分。

huangapple go评论94阅读模式
英文:

Conditionally render more than one section in Hugo

问题

我想在网站首页中渲染除静态文件夹之外的所有文件夹中的所有Markdown文件。使用Hugo的union方法可以实现这一目的,但随着文件夹数量的增加,我发现自己不得不在各个地方重复使用union(已经注释掉的带有union的代码是有效的)。因此,我认为使用slice会是一个更好的主意。但是,当我尝试使用slice时,出现了以下错误:

无法渲染页面:渲染“home”失败:“(目录路径)\layouts\index.html:12:19”:在类型为字符串的字段中无法评估字段Pages

目录结构:

在Hugo中有条件地渲染多个部分。

index.html的代码:

{{ define "main" }}
<ul class="homepage-topic-sections-container">
    {{$sectionNames := slice "posts" "problems" "tutorials"}}
    {{range $index, $sectionName := $sectionNames}}
    {{ range where .Pages "Section" $sectionName }}
    {{/*
    {{ range union (union
    (where .Pages "Section" "posts")
    (where .Pages "Section" "problems"))
    (where .Pages "Section" "tutorials")
    }}
    */}}
    <li>
        <section class="homepage-topic-section">
            <h1 class="topic-heading"><a href="{{.Permalink}}">{{.Title}} </a></h1>
            <div>
                {{ range .Pages }}
                <h3><a href="{{.Permalink}}">{{.Title}} &middot; {{.Date.Format "January 2, 2006"}}</a></h3>
                {{ end }}
            </div>
        </section>
    </li>
    {{end}}
    {{end}}

</ul>
{{ end }}
英文:

I want to render all the markdown files inside every folder except the static one in my home page of the website, one way of doing that is by using union in hugo, but as number of folders increase, I see myself repeating unions all over the place (code with union is commented, which is working by the way), so I thought using a slice would be a better idea, but when I try to use slice, I get the following error -

failed to render pages: render of "home" failed: "(Directory Path)\layouts\index.html:12:19": execute of template failed at <.Pages>: can’t evaluate field Pages in type string

directory structure

在Hugo中有条件地渲染多个部分。

code for index.html

{{ define &quot;main&quot; }}
&lt;ul class=&quot;homepage-topic-sections-container&quot;&gt;
    {{$sectionNames := slice &quot;posts&quot; &quot;problems&quot; &quot;tutorials&quot;}}
    {{range $index, $sectionName := $sectionNames}}
    {{ range where .Pages &quot;Section&quot; $sectionName }}
    {{/*
    {{ range union (union
    (where .Pages &quot;Section&quot; &quot;posts&quot;)
    (where .Pages &quot;Section&quot; &quot;problems&quot;))
    (where .Pages &quot;Section&quot; &quot;tutorials&quot;)
    }}
    */}}
    &lt;li&gt;
        &lt;section class=&quot;homepage-topic-section&quot;&gt;
            &lt;h1 class=&quot;topic-heading&quot;&gt;&lt;a href=&quot;{{.Permalink}}&quot;&gt;{{.Title}} &lt;/a&gt;&lt;/h1&gt;
            &lt;div&gt;
                {{ range .Pages }}
                &lt;h3&gt;&lt;a href=&quot;{{.Permalink}}&quot;&gt;{{.Title}} &amp;middot; {{.Date.Format &quot;January 2, 2006&quot;}}&lt;/a&gt;&lt;/h3&gt;
                {{ end }}
            &lt;/div&gt;
        &lt;/section&gt;
    &lt;/li&gt;
    {{end}}
    {{end}}

&lt;/ul&gt;
{{ end }}

答案1

得分: 1

https://gohugo.io/templates/introduction/#the-dot:

> ### 上下文(也称为“点”)
> 关于Go模板最容易被忽视的概念是,{{ . }}始终指的是当前上下文
>
> - 在模板的顶层,它将是可用的数据集。
> - 然而,在迭代内部,它将具有循环中当前项的值;即,{{ . }}将不再指代整个页面可用的数据。

在下面的代码中,.Pages中的点具有第一个range操作中当前项的值。该值的类型为字符串,它没有Pages字段。这就是为什么会出现execute of template failed at &lt;.Pages&gt;: can’t evaluate field Pages in type string的错误。

{{ define &quot;main&quot; }}
&lt;ul class=&quot;homepage-topic-sections-container&quot;&gt;
    {{$sectionNames := slice &quot;posts&quot; &quot;problems&quot; &quot;tutorials&quot;}}
    {{range $index, $sectionName := $sectionNames}}
    {{ range where .Pages &quot;Section&quot; $sectionName }}
                   ^^^^^^

一种可能的修复方法是使用$.来访问全局上下文:.Pages ==> $.Pages

也许一个更好的解决方案是列出要排除的部分。这样,当添加更多文件夹时,您就不需要修改代码:

{{ define &quot;main&quot; }}
&lt;ul class=&quot;homepage-topic-sections-container&quot;&gt;
    {{ range where .Pages &quot;Section&quot; &quot;!=&quot; &quot;static&quot; }}
    &lt;li&gt;
英文:

https://gohugo.io/templates/introduction/#the-dot:

> ### Context (aka “the dot”)
> The most easily overlooked concept to understand about Go Templates is that {{ . }} always refers to the current context.
>
> - In the top level of your template, this will be the data set made available to it.
> - Inside an iteration, however, it will have the value of the current item in the loop; i.e., {{ . }} will no longer refer to the data available to the entire page.

In the code below, the dot in .Pages has the value of the current item in the first range action. The type of that value is string, and it does not have the field Pages. That's why it failed with execute of template failed at &lt;.Pages&gt;: can’t evaluate field Pages in type string.

{{ define &quot;main&quot; }}
&lt;ul class=&quot;homepage-topic-sections-container&quot;&gt;
    {{$sectionNames := slice &quot;posts&quot; &quot;problems&quot; &quot;tutorials&quot;}}
    {{range $index, $sectionName := $sectionNames}}
    {{ range where .Pages &quot;Section&quot; $sectionName }}
                   ^^^^^^

One possible fix is to use $. to access the global context: .Pages ==> $.Pages.

Maybe a better solution is to list the exclude sections instead. Then you don't need to modify the code when more folders are added:

{{ define &quot;main&quot; }}
&lt;ul class=&quot;homepage-topic-sections-container&quot;&gt;
    {{ range where .Pages &quot;Section&quot; &quot;!=&quot; &quot;static&quot; }}
    &lt;li&gt;

huangapple
  • 本文由 发表于 2023年4月2日 18:27:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75911449.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定