List 页面模板?

List页面模板用于在一个HTML页面内显示多条内容。 例外是主页, 虽然是一个list但是主页有自己的 专用模板.

Hugo中条目list 表达了最真实的需求; 那就是,内容的序列安排,特别是按照字母或者数字顺序。 Hugo对传统上是列表内容的任何输出的HTML页面应用list模板:

模板查询顺序, 请参考Template Lookup

页面列表list的想法来源于网络的分级心智模型 hierarchical mental model of the web 最好是使用图片展示:

Image demonstrating a hierarchical website sitemap.

默认list

默认的模板 Default Templates

区块的list和特定标签的list考虑它们的模板都是lists, 在它们模板查询顺序中都具有确定的默认模板 _default/list.html 或者 themes/<THEME>/layouts/_default/list.html. 另外,section liststaxonomy lists 具有它们默认的在目录_default中的list模板.

参考 Template Lookup Order 获得完整信息

在list页面中添加内容和Front matter

从版本V0.18开始,Hugo中所有内容都是Page。这意味着list页面和主页也具有相关的包含页面元数据(如front matter)和页面内容的内容文件(如_index.md)

这个新模型允许您包含通过.Params包含list特定的front matter设置,同时也意味着list模板list templates (如 layouts/_default/list.html)具有访问所有页面变量page variables的权限。

项目目录举例

下面是典型的Hugo项目的目录内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.
...
├── content
|   ├── posts
|   |   ├── _index.md
|   |   ├── post-01.md
|   |   └── post-02.md
|   └── quote
|   |   ├── quote-01.md
|   |   └── quote-02.md
...

使用上面例子,我们假设文件 content/posts/_index.md具有下面的内容:

content/posts/_index.md
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

---
title: My Go Journey
date: 2017-03-23
publishdate: 2017-03-24
---

I decided to start learning Go in March 2017.

Follow my journey through this new blog.

You can now access this _index.md’s’ content in your list template:

layouts/_default/list.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

{{ define "main" }}
<main>
    <article>
        <header>
            <h1>{{.Title}}</h1>
        </header>
        <!-- "{{.Content}}" pulls from the markdown content of the corresponding _index.md -->
        {{.Content}}
    </article>
    <ul>
    <!-- 遍历 content/posts/*.md -->
    {{ range .Pages }}
        <li>
            <a href="{{.Permalink}}">{{.Date.Format "2006-01-02"}} | {{.Title}}</a>
        </li>
    {{ end }}
    </ul>
</main>
{{ end }}

上面模板会输出如下的HTML:

example.com/posts/index.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16

<!--top of your baseof code-->
<main>
    <article>
        <header>
            <h1>My Go Journey</h1>
        </header>
        <p>I decided to start learning Go in March 2017.</p>
        <p>Follow my journey through this new blog.</p>
    </article>
    <ul>
        <li><a href="/posts/post-01/">Post 1</a></li>
        <li><a href="/posts/post-02/">Post 2</a></li>
    </ul>
</main>
<!--bottom of your baseof-->

不需要_index.md的List页面

不需要为每一个list页面(如section, taxonomy标签页, taxonomy terms标签条目等页面)或者首页创建 _index.md文件。如果Hugo在显示list模板时在相应的内容section内没有找到 _index.md, hugo会创建list页面, 但是不包含{{.Content}},仅仅包含 .Title的默认值.

使用上面相同的 layouts/_default/list.html 模板, 对上面的 quotes 区块应用这个模板会产生下面的输出. 请注意 quotes 并没有一个可以提取内容的_index.md:

example.com/quote/index.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15

<!--baseof-->
<main>
    <article>
        <header>
        <!-- Hugo assumes that .Title is the name of the section since there is no _index.md content file from which to pull a "title:" field -->
            <h1>Quotes</h1>
        </header>
    </article>
    <ul>
        <li><a href="https://example.com/quote/quotes-01/">Quote 1</a></li>
        <li><a href="https://example.com/quote/quotes-02/">Quote 2</a></li>
    </ul>
</main>
<!--baseof-->

List Templates 举例

块模板

list模板已经被修改,同spf13.com原来使用的模板稍微不同。 为了所生成页面的拼接,它使用了partial templates,而没有使用 base template. 下面的例子也使用了内容视图模板 li.html 或者 summary.html

layouts/section/posts.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15

{{ partial "header.html" . }}
{{ partial "subheader.html" . }}
<main>
  <div>
   <h1>{{ .Title }}</h1>
        <ul>
        <!-- 对每个content/posts/*.md 输出li.html内容视图 -->
            {{ range .Pages }}
                {{ .Render "li"}}
            {{ end }}
        </ul>
  </div>
</main>
{{ partial "footer.html" . }}

标签模板

layouts/_default/taxonomy.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

{{ define "main" }}
<main>
  <div>
   <h1>{{ .Title }}</h1>
   <!-- 对和特定标签相关的内容文件循环,
   输出summary.html内容视图 -->
    {{ range .Pages }}
        {{ .Render "summary"}}
    {{ end }}
  </div>
</main>
{{ end }}

对内容排序

Hugo列表list基于内容的前言设定 front matter中的元数据来生成内容. 除了缺省显示, hugo也提供了多个方法在list模板内对内容进行快速排序。

缺省的排序顺序: Weight > Date > LinkTitle > FilePath

layouts/partials/default-order.html
1
2
3
4
5
6
7
8
9

<ul>
    {{ range .Pages }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

By Weight

越小的weight值有越高的优先级。具有低weight值的内容会先出现.

layouts/partials/by-weight.html
1
2
3
4
5
6
7
8
9

<ul>
    {{ range .Pages.ByWeight }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

By Date

layouts/partials/by-date.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

<ul>
    <!-- 基于前言设定中的“date”值对内容排序 -->
    {{ range .Pages.ByDate }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

By Publish Date

layouts/partials/by-publish-date.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

<ul>
    <!-- 基于前言设定中的“publishdate”值对内容排序-->
    {{ range .Pages.ByPublishDate }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

By Expiration Date

layouts/partials/by-expiry-date.html
1
2
3
4
5
6
7
8
9

<ul>
    {{ range .Pages.ByExpiryDate }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按最后修改日期排序

layouts/partials/by-last-mod.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

<ul>
    <!-- 基于前言设定中的“lastmod”值对内容排序-->
    {{ range .Pages.ByLastmod }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按内容长度升序排列

layouts/partials/by-length.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

<ul>
    <!-- 按照内容长度升序排序(最短的内容最先出现)-->
    {{ range .Pages.ByLength }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按title排序

layouts/partials/by-title.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10

<ul>
    <!-- 按前言设定中"title"的升序排列-->
    {{ range .Pages.ByTitle }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

按链接Title排序

By Parameter 按指定参数排序

Order based on the specified front matter parameter. Content that does not have the specified front matter field will use the site’s .Site.Params default. If the parameter is not found at all in some entries, those entries will appear together at the end of the ordering.

layouts/partials/by-rating.html
1
2
3
4
5

<!-- Ranges through content according to the "rating" field set in front matter -->
{{ range (.Pages.ByParam "rating") }}
  <!-- ... -->
{{ end }}

If the targeted front matter field is nested beneath another field, you can access the field using dot notation.

layouts/partials/by-nested-param.html
1
2
3
4

{{ range (.Pages.ByParam "author.last_name") }}
  <!-- ... -->
{{ end }}

Reverse Order 反序排列

对上面任意一个排序方法可以进行反序排列. 下面以ByDate排序作为例子:

layouts/partials/by-date-reverse.html
1
2
3
4
5
6
7
8
9

<ul>
    {{ range .Pages.ByDate.Reverse }}
        <li>
            <h1><a href="{{ .Permalink }}">{{ .Title }}</a></h1>
            <time>{{ .Date.Format "Mon, Jan 2, 2006" }}</time>
        </li>
    {{ end }}
</ul>

Group Content 内容分组

Hugo提供了按照区块、类型、日期将内容分组的函数.

By Page Field 通过页面字段分组

layouts/partials/by-page-field.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<!-- 按内容section区块分组. ".Key"这里指的是section的标题-->
{{ range .Pages.GroupBy "Section" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

在上面例子中, 如果希望使用添加到"_index.md"文件中的title字段作为{{.Title}}. 可以使用函数.GetPage function获得这个值:

layouts/partials/by-page-field.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

<!-- Groups content according to content section.-->

{{ range .Pages.GroupBy "Section" }}
<!-- Checks for existence of _index.md for a section; if available, pulls from "title" in front matter -->
{{ with $.Site.GetPage "section" .Key }}
<h3>{{.Title}}</h3>
{{ else }}
<!-- If no _index.md is available, ".Key" defaults to the section title and filters to title casing -->
<h3>{{ .Key | title }}</h3>
{{ end }}
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

按日期分组 By Date

layouts/partials/by-page-date.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<!-- 基于前言设定的"date"中的月份将内容分组 -->
{{ range .Pages.GroupByDate "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

按发布日期分组 By Publish Date

layouts/partials/by-page-publish-date.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<!-- 基于前言设定的"publishDate"中的月份将内容分组 -->
{{ range .Pages.GroupByPublishDate "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .PublishDate.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

按最后修改时间分组 By Lastmod

layouts/partials/by-page-lastmod.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<!-- 基于前言设定的"lastMod"中的月份将内容分组  -->
{{ range .Pages.GroupByLastmod "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Lastmod.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

按过期时间分组 By Expiry Date

layouts/partials/by-page-expiry-date.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<!-- Groups content by month according to the "expiryDate" field in front matter -->
{{ range .Pages.GroupByExpiryDate "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .ExpiryDate.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

基于页面参数分组 By Page Parameter

layouts/partials/by-page-param.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<!-- Groups content according to the "param_key" field in front matter -->
{{ range .Pages.GroupByParam "param_key" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

基于日期格式的页面参数分组 By Page Parameter in Date Format

The following template takes grouping by date a step further and uses Go’s layout string. See the Format function for more examples of how to use Go’s layout string to format dates in Hugo.

layouts/partials/by-page-param-as-date.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13

<!-- Groups content by month according to the "param_key" field in front matter -->
{{ range .Pages.GroupByParamDate "param_key" "2006-01" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

反转key顺序 Reverse Key Order

分组内排序基于键值的字母顺序,和日期的反向顺序(最新的最先出现)。

逻辑默认如此, 但有时并不总是想要的顺序。下面是两钟改变Hugo默认分组内排序的格式,效果一样:

1. 添加Reverse方法

1
{{ range (.Pages.GroupBy "Section").Reverse }}
1
{{ range (.Pages.GroupByDate "2006-01").Reverse }}

2. 提供不同的方向

1
{{ range .Pages.GroupByDate "2006-01" "asc" }}
1
{{ range .Pages.GroupBy "Section" "desc" }}

组内排序 Order Within Groups

对于内容分组返回的{{.Key}} 和页面list的切片, 上面提到的排序方法都适用:

下面例子中的排序:

  1. 内容按照前言设定中date的月份分组
  2. 不同组按照升序排列(最早的组先出来)
  3. 相应的每个组内页面通过title按字母顺序排序
layouts/partials/by-group-by-page.html
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12

{{ range .Pages.GroupByDate "2006-01" "asc" }}
<h3>{{ .Key }}</h3>
<ul>
    {{ range .Pages.ByTitle }}
    <li>
    <a href="{{ .Permalink }}">{{ .Title }}</a>
    <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
    </li>
    {{ end }}
</ul>
{{ end }}

list过滤和条件选择 Filtering and Limiting Lists

有时候想获得可访问内容的子集列表,比如常见的在博客首页仅仅显示来自main sections的post的。

列表过滤和条件选择,可以参考 where functionfirst function 文档获得更多信息.