Web Design 2 : Content Organization & Link Content using go template

导言

link hugo theme content using go template

内容组织

管理一个组织的人员和对应所属的基本信息(入学年份,工作去向)、成果(论文 和 项目)和新闻事件(获奖,组会汇报)。

采用数据库管理的思想,把后者拆分出元数据,并且以人名的驼峰字母拼音作为主键索引。

Hugo variables

Find usefull variables

作者与论文

  1. 文章作者 跳转到对应people page
  2. people page下列出所属论文

论文按照会议/CCF分级筛选

参考图片

src1 and src2

数据库操作要求

Go template 需要做到以下几种操作:

变量的声明与使用

由于with会缩小.的变量域范围。我们需要提前保存我们要使用的变量(变量的作用范围仅在声明它的块内).

1
2
3
4
5
6
7
{{ $employment := .Params.employment }}

{{ with .Params.year_graduation }}
{{ if ne . "" }}
校友 <p>上一级职位:{{ $employment }}</p>
{{ end }}
{{ end }}

类型转换

1
{{ $numericYear := printf "%d" ($year) }}

读取任意位置文件的metadata 和 markdown 内容

读我自己写的content/path/home.yml里的元数据

如果你想读取特定内容文件(例如 content/path/home.yml)中的元数据,你可以使用类似的方法。假设你的 home.yml 文件如下:

1
2
3
4
5
---
title: "Home Page"
description: "Welcome to my home page"
author: "Your Name"
---

在你的 Hugo 模板中,你可以使用以下方式读取这个文件中的元数据:[^2] 并使用[^1]

1
2
3
4
5
6
{{ with .GetPage "home.yml" }} 
// .Params.Title also pass
{{ .Params.title }}
{{ .Params.description }}
{{ .Params.author }}
{{ end }}

这里使用了 with 来确保只有在找到相应页面的情况下才会输出元数据。请注意,这里假设 home.yml 文件的路径是 content/path/home.md,如果实际路径不同,你需要相应地调整路径参数。

某一文件夹下查找是否存在文件名是ABC的文件

在 Hugo 模板中,你可以使用 .Site.GetPage 函数来检查某个特定路径下是否存在指定的文件。以下是一个例子,检查在 content/myfolder/ 文件夹下是否存在名为 ABC.md 的文件:

1
2
3
4
5
6
7
8
9
{{ with .Site.GetPage "section" "myfolder" }}
{{ with .GetPage "ABC.md" }}
<!-- 文件存在的处理逻辑 -->
<p>文件存在:{{ .Title }}</p>
{{ else }}
<!-- 文件不存在的处理逻辑 -->
<p>文件不存在</p>
{{ end }}
{{ end }}

在这个例子中:

  • .Site.GetPage "section" "myfolder" 用于获取 myfolder 这个部分(section)的页面。
  • .GetPage "ABC.md" 用于获取在 myfolder 部分下的 ABC.md 文件。

你可以根据需要调整路径和文件名。如果文件存在,你可以在 “文件存在的处理逻辑” 部分执行相应的操作,否则可以在 “文件不存在的处理逻辑” 部分处理。

遍历 与 筛选

  • 包含key value
  • key的数值大于k

遍历单一metadata的列表

1
2
3
4
5
6
7
8
9
10
people_line:
# slider item loop
- name : "An Hong"
image : "images/clients/anhong.png"
url : "http://cs.ustc.edu.cn/2020/0426/c23235a460072/page.htm"
designation : "Prof."
content : "Chip multiprocessor architecture, parallel computer system architecture, parallel programming environment and tools, large data parallel storage and processing, high performance computing"
- name : "Shi Jun"
image : "images/clients/client1.jpg"
# xxx

对应html

1
2
3
4
5
6
7
{{ range .Params.people_line }}
{{ .name }}
{{ .image | absURL }}
{{ .url | absURL }}
{{ .designation | markdownify }}
{{ .content | markdownify }}
{{ end }}

遍历子文件夹md,并根据metadata 筛选

1
2
3
4
5
6
7
8
{{ range .Data.Pages }}
<!-- 在每个页面内部,再次使用range循环遍历该页面的所有类别。 -->
{{ if eq (.Param "display_toc") "A" }}
{{ .TableOfContents }}
{{ else }}
<!-- 如果 display_toc 参数不等于 "A",执行这里的内容 -->
{{ end }}
{{ end }}

chatgpt’s answer

在Hugo的Go模板中,你可以使用where函数结合条件来遍历子文件夹中的Markdown文件,并根据元数据(metadata)进行筛选。以下是一个示例,假设你想要遍历content/posts文件夹下的Markdown文件,然后根据文件的categories元数据进行筛选:

1
2
3
4
5
6
7
8
9
10
11
{{ $pages := where .Site.RegularPages "Section" "posts" }}

{{ range $pages }}
{{ with .Params.categories }}
{{ if in . "your_category" }}
<!-- 在这里处理符合条件的文章 -->
<h2>{{ .Title }}</h2>
<p>{{ .Content }}</p>
{{ end }}
{{ end }}
{{ end }}

在上面的示例中:

  1. where .Site.RegularPages "Section" "posts" 用于获取content/posts文件夹下的所有Markdown文件。
  2. {{ with .Params.categories }} 用于检查文章是否有categories元数据。
  3. {{ if in . "your_category" }} 用于检查文章的categories中是否包含你感兴趣的特定类别(在这里用”your_category”作为示例,你需要替换为实际的类别名称)。
  4. 如果文章符合条件,就在<!-- 在这里处理符合条件的文章 -->注释下进行处理,你可以输出文章的标题、内容等。

请根据你的实际需求调整条件和处理逻辑。这只是一个示例,你可以根据自己的具体情况进行修改。在Hugo的Go模板中,你可以使用各种条件和函数来灵活地筛选和处理内容。

metadata的使用

存在并非空 的metadata

1
2
3
4
5
6
7
8
9
// 存在
{{ with .Params.year_graduation }}
// 判断非空
{{ if ne . "" }}
<p>职位:{{ . }}</p>
{{ end }}
{{ else }}
<p>没有提供职位信息</p>
{{ end }}

必须要有with

1
2
3
4
5
6
// Debug: Params.year_graduation = '%!s(<nil>)' 
{{ printf "Debug: Params.year_graduation = '%s'" .Params.year_graduation }}
{{ if ne .Params.year_graduation "" }}
校友2
<p>职位:{{ .Params.year_graduation }}</p>
{{ end }}

go template 判断 <nil> ne ""

遍历、合并、去重各post的categories

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!-- 包含了一个特殊的data-toggle属性,用于指定这是一个按钮切换组。 -->
<div class="btn-group btn-group-toggle portfolio-navigation" data-toggle="buttons">
<label class="btn btn-sm btn-primary active hvr-sweep-to-right">
<input type="radio" name="shuffle-filter" value="all" checked="checked" />All
</label>
<!-- 定义了一个变量$categories,这是一个切片(slice)类型的变量,用于存储文章的所有类别。 -->
{{ $categories := slice }}
<!-- 遍历了所有网站页面(文章)。 -->
{{ range .Data.Pages }}
<!-- 在每个页面内部,再次使用range循环遍历该页面的所有类别。 -->
{{ range .Params.categories }}
<!-- 将每个类别追加到之前定义的$categories切片中。 -->
{{ $categories = $categories | append . }}
{{ end }}
{{ end }}
<!-- 使用range循环遍历去重后的类别切片。 -->
{{ range ( $categories | uniq ) }}
<!-- 对于每个类别,生成一个按钮标签 -->
<label class="btn btn-sm btn-primary hvr-sweep-to-right">
<input type="radio" name="shuffle-filter" value="{{ . | urlize }}" />{{ . | humanize }}
</label>
{{ end }}
</div>

数值metadata的计算和处理

日期2023-12 变成 Dec

在Hugo的Go模板中,你可以使用dateFormat函数将日期格式化为你所需的格式,并使用条件语句或类似的逻辑来映射月份的数字到英文月份缩写。下面是一个示例:

1
2
3
{{ $monthMapping := dict  "01" "JAN" "02" "FEB" "03" "MAR" "04" "APR" "05" "MAY" "06" "JUN" "07" "JUL" "08" "AUG" "09" "SEP" "10" "OCT" "11" "NOV" "12" "DEC" }}

<p>{{ index $monthMapping (printf "%02d" .Date.Month) }}</p>

请注意,.Date.Month返回的是一个整数。

入学年份2021 变成 研究生几年级

同理映射 阿拉伯数字 变成 中文数字。

1
2
3
4
5
{{ $numMapping := dict  "01" "一" "02" "二" "03" "三" "04" "四" "05" "五" "06" "六" "07" "七" "08" "八" "09" "九" "10" "十" "11" "十一" "12" "十二" }}
{{ $currentYear := now.Year }}

{{ $yearDifference := sub $currentYear .Params.year_enrollment_PhD }}
{{ index $numMapping (printf "%02d" $yearDifference) }}

默认功能:排序`date

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 遍历所有页面,按照发布日期进行降序排序。.Pages表示网站的所有页面,.ByPublishDate表示按照发布日期排序,.Reverse表示降序排列。 -->
{{ range .Pages.ByPublishDate.Reverse }}
<p>
<!-- RelPermalink是相对于网站根目录的页面链接。 -->
<h3><a class="title" href="{{ .RelPermalink }}">{{ .Title }}</a></h3>
{{ partial "metadata.html" . }}
<a class="summary" href="{{ .RelPermalink }}">
<!-- Hugo automatically takes the first 70 words of your content as its summary and stores it into the .Summary variable -->
<p>{{ .Summary }}</p>
</a>
</p>
{{ end }}

是非判断

1
2
3
4
5
6
7
8
9
10
11
12
{{ if .Param "display_toc" }}
{{ .TableOfContents }}
{{ else }}
<!-- 如果 display_toc 参数不存在或为 false,执行这里的内容 -->
{{ end }}

// other
{{ if eq (.Param "display_toc") "A" }}
{{ .TableOfContents }}
{{ else }}
<!-- 如果 display_toc 参数不等于 "A",执行这里的内容 -->
{{ end }}

config in config.yml

range site.Params is the global site configuration.

range 使用

1
2
3
{{ range site.Params.plugins.css }}
<link rel="stylesheet" href="{{ .link | absURL }}">
{{ end }}

according toml

1
2
3
4
5
6
[[params.plugins.css]]
link = "plugins/bootstrap/bootstrap.min.css"
[[params.plugins.css]]
link = "https://fonts.googleapis.com/css?family=Rubik:300,400,500,700,900&display=swap"
[[params.plugins.css]]
link = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css"

单次使用变量要大写

1
{{ .Site.Params.Toporg.name }}

according toml

1
2
[params.toporg]
name = "USTC"

homepage

  1. manual designed content in config.yml
  2. 对应位置的__index.md

参考文献

[^1]: hugo params
[^2]: hugo getPage

Web Design 2 : Content Organization & Link Content using go template

http://icarus.shaojiemike.top/2023/11/30/OutOfWork/3-homepage/deployment/webDesign2LinkContent/

Author

Shaojie Tan

Posted on

2023-11-30

Updated on

2025-01-30

Licensed under