前言

网站可以分为动态网站和静态网站,动态网站通过服务器查询数据库,动态渲染页面返回给用户,内容可以是变化的,对不同的用户返回不同的内容。此博客采用静态网站的方式搭建,hugogo编写的静态网站生成器,将md文档和网站结构(模板)打包生成一个完整的静态网站(HTML、CSS、JS),Cloudflare PagesCloudflare提供的一个前端网站托管平台,将hugo生成的静态文件部署到Cloudflare Pages上,网站就可以被访问了。

安装hugo

参考官方文档

新建站点

1
2
3
hugo new site MyBlog

git init

文件结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
myblog/                  # 项目根目录
├── archetypes/          # 内容模板目录
│   └─ default.md        # 默认模板
├── assets/              # 需要处理的资源文件(如CSS、JS等)
│   └── css/
│       └── extended/    # 自定义样式目录
├── content/             # 内容文件目录
│   ├── posts/         # 文章目录
│   │   ├── _index.md  # 文章列表页配置
│   ├── search.md      # 搜索页面
│   └── archives.md    # 归档页面
├── data/              # 数据文件目录(YAML、JSON、TOML)
├── layouts/           # 布局模板目录
│   ├── _default/     # 默认模板
│   └── partials/     # 部分模板
├── static/           # 静态文件目录(直接复制到public)
├── themes/           # 主题目录
│   └── PaperMod/    # PaperMod主题
├── public/          # 生成的静态网站(不需要版本控制)
├── resources/       # 处理后的资源文件(不需要版本控制)
└── hugo.yml         # 站点配置

选择主题

1
git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

配置文件

编辑hugo.yml

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
baseURL: 'https://www.lvyourz.com'
title: 'lvyourz'
pagination:
  disableAliases: false
  pagerSize: 6
theme: PaperMod
languageCode: 'zh-cn'

hasCJKLanguage: true
enableInlineShortcodes: true  #短代码
enableEmoji: true
enableRobotsTXT: true #自动生成robots.txt文件,利于 SEO。
buildDrafts: false
buildFuture: false
buildExpired: false
pygmentsUseClasses: true  #代码高亮用 class 控制,不是直接内联 style。利于统一主题样式。

minify:
    disableXML: true
    # minifyOutput: true

permalinks: #文章生成后的URL结构
  post: "/:title/"
  # post: "/:year/:month/:day/:title/"

defaultContentLanguage: zh
defaultContentLanguageInSubdir: false

menu:
  main:
    - identifier: search
      name: 🔍搜索
      url: search
      weight: 1
    - identifier: home
      name: 🏠主页
      url: /
      weight: 2
    - identifier: posts
      name: 📚文章
      url: /posts
      weight: 3
    - identifier: archives
      name: ⏱归档
      url: /archives
      weight: 20
    # - identifier: categories
    #   name: 🧩分类
    #   url: categories
    #   weight: 30
    # - identifier: tags
    #   name: 🔖标签
    #   url: /tags
    #   weight: 40

outputs:
    home:
        - HTML
        - RSS
        - JSON

params:
    env: production
    author: Hong Zhang
    defaultTheme: auto
    disableThemeToggle: false
    DateFormat: "2006-01-02"
    ShowShareButtons: true
    ShowReadingTime: true
    # disableSpecialistPost: true
    displayFullLangName: true
    ShowPostNavLinks: true  #单篇文章下方显示前一篇 / 后一篇链接。
    ShowBreadCrumbs: true
    ShowCodeCopyButtons: false
    hideFooter: false # 隐藏页脚
    ShowWordCounts: true
    VisitCount: true
    ShowLastMod: true #显示文章更新时间
    ShowToc: false # 显示目录
    TocOpen: false # 自动展开目录
    comments: true

    #网站标签图标
    assets: 
        favicon: "img/favicon.ico"
        favicon16x16: "img/favicon-96x96.png"
        favicon32x32: "img/favicon-96x96.png"
        apple_touch_icon: "img/web-app-manifest-192x192.png"
        safari_pinned_tab: "img/web-app-manifest-192x192.png"

    # cover:
    #     hidden: true # hide everywhere but not in structured data 
    #     hiddenInList: true # hide on list pages and home
    #     hiddenInSingle: true # hide on single page

    # 站内搜索,基于 Fuse.js
    fuseOpts:
        isCaseSensitive: false  # 大小写敏感
        shouldSort: true  # 是否按匹配度对结果排序。设为 true 可以让最相关的内容排在最前。
        location: 0 # 匹配关键字的预期位置。0 表示更偏好匹配在内容开头的位置。这个对排序有微弱影响。
        distance: 1000  # 模糊匹配中关键词与预期位置的最大距离。数值越大,匹配越宽松。1000 意味着基本无视距离。
        threshold: 0.4  # 匹配的“模糊度”阈值,范围 0~1。0 最严格(完全匹配),1 最宽松(只要沾点边就匹配)。设为 1 表示基本不会过滤任何关键词。
        minMatchCharLength: 0 # 最小匹配字符数。0 表示用户输入任意长度(包括 1 个字符)都能触发搜索。
        keys: ["title", "permalink", "summary","content"] # 指定搜索字段。常见的字段有:title(标题)、permalink(链接)、summary(摘要)、content(正文内容)等。

    # 评论
    twikoo:
      version: 1.4.11
    
    # 主页 - 信息模式(默认)
    homeInfoParams:
        Title: ""
        Content: ""

# 分类体系,Hugo 会自动生成这些页面:/tags/,/categories/,/series/
taxonomies:
    category: categories
    tag: tags
    series: series

markup:
    goldmark:
        renderer:
            unsafe: true # HUGO 默认转义 Markdown 文件中的 HTML 代码,如需开启的话
    highlight:
        # anchorLineNos: true
        codeFences: true
        guessSyntax: true
        lineNos: true
        # noClasses: false
        # style: monokai
        style: darcula

        # codeFences:代码围栏功能,这个功能一般都要设为 true 的,不然很难看,就是干巴巴的-代码文字,没有颜色。
        # guessSyntax:猜测语法,这个功能建议设置为 true, 如果你没有设置要显示的语言则会自动匹配。
        # hl_Lines:高亮的行号,一般这个不设置,因为每个代码块我们可能希望让高亮的地方不一样。
        # lineNoStart:行号从编号几开始,一般从 1 开始。
        # lineNos:是否显示行号,我比较喜欢显示,所以我设置的为 true.
        # lineNumbersInTable:使用表来格式化行号和代码,而不是 标签。这个属性一般设置为 true.
        # noClasses:使用 class 标签,而不是内嵌的内联样式

#控制“嵌入内容”时是否加载外部脚本
privacy:
    vimeo:
        disabled: false
        simple: true

    x:
        disabled: false
        enableDNT: true
        simple: true

    instagram:
        disabled: false
        simple: true

    youtube:
        disabled: false
        privacyEnhanced: true
        
#是否禁止平台加载额外的样式(CSS)
services:
    instagram:
        disableInlineCSS: true
    x:
        disableInlineCSS: true

默认模板

Hugoarchetypes提供了一个默认的文章使用模板default.md,新建文章的Front Matter字段的模板posts.md

atchetypes/posts.md

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
---

title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
lastmod: {{ .Date }}
author: ["HZhang"]

categories: [""]

tags: [""]
 
keywords: [""]

description: "" # 文章描述,与搜索优化相关
summary: "" # 文章简单描述,会展示在主页
weight: # 输入1可以顶置文章,用来给文章展示排序,不填就默认按时间排序
slug: "" # 自定义网址最后一段 URL。比如 slug 写 my-article,那页面 URL 会是 /post/my-article/。
draft: false # 是否为草稿
comments: true
showToc: false # 显示目录
TocOpen: false # 自动展开目录
autonumbering: true # 目录自动编号
hidemeta: false # 是否隐藏文章的元信息,如发布日期、作者等
disableShare: true # 底部不显示分享栏
searchHidden: false # 该页面可以被搜索到
showbreadcrumbs: true #顶部显示当前路径
mermaid: true #流程图
cover:
    image: ""
    caption: ""
    alt: ""
    relative: true

---

搜索页面

参考官方文档

在搜索框下面添加标签区块

themes/PaperMod/layouts/_default/terms.html => layouts/_default/search.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{{ define "main" }}


<header class="page-header">
    <h1>{{- (printf "%s&nbsp;" .Title ) | htmlUnescape -}}
        <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none"
            stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
            <circle cx="11" cy="11" r="8"></circle>
            <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
        </svg>
    </h1>
    {{- if .Description }}
    <div class="post-description">
        {{ .Description }}
    </div>
    {{- end }}
    {{- if not (.Param "hideMeta") }}
    <div class="post-meta">
        {{- partial "translation_list.html" . -}}
    </div>
    {{- end }}
</header>

<div id="searchbox" style="margin-bottom: 2rem;">
    <input id="searchInput" autofocus placeholder="{{ .Params.placeholder | default (printf "%s ↵" .Title) }}"
        aria-label="search" type="search" autocomplete="off" maxlength="64">
    <ul id="searchResults" aria-label="search results"></ul>
</div>

<section class="tags-section">
    <h1>🔖标签</h1>
    <ul class="terms-tags">
        {{- range $name, $taxonomy := $.Site.Taxonomies.tags }}
        {{- $count := len $taxonomy.Pages }}
        {{- with $.Site.GetPage (printf "/tags/%s" $name) }}
        <li>
            {{ $largestFontSize := 1.5 }}
            {{ $smallestFontSize := 1 }}
            {{ $fontSpread := sub $largestFontSize $smallestFontSize }}
            {{ $max := add (len (index $.Site.Taxonomies.tags.ByCount 0).Pages) 1 }}
            {{ $min := len (index $.Site.Taxonomies.tags.ByCount.Reverse 0).Pages }}
            {{ $spread := sub $max $min }}
            {{ $fontStep := div $fontSpread $spread }}
            {{ $weigth := div (sub (math.Log $count) (math.Log $min)) (sub (math.Log $max) (math.Log $min)) }}
            {{ $currentFontSize := (add $smallestFontSize (mul (sub $largestFontSize $smallestFontSize) $weigth)) }}
            <a href="{{ .Permalink }}" style="font-size: {{ $currentFontSize }}rem; font-weight: {{ mul $currentFontSize 300 }};">
                {{ .Name }} <sup><strong><sup>{{ $count }}</sup></strong></sup>
            </a>
            <!-- <a href="{{ .Permalink }}" style="font-size: {{ $currentFontSize }}rem; color: rgba({{ sub 150 (mul $count 10) }}, {{ sub 150 (mul $count 10) }}, {{ sub 150 (mul $count 10) }}, 1);">
                {{ .Name }} <sup><strong><sup>{{ $count }}</sup></strong></sup>
            </a> -->
        </li>
        {{- end }}
        {{- end }}
    </ul>
</section>
{{end}}
{{/* end main */ -}}

归档页面

参考官方文档

标签页面

标签云样式

themes/PaperMod/layouts/_default/terms.html => layouts/_default/terms.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{{- define "main" }}

{{- if .Title }}
<header class="page-header">
    {{- if eq .Title "Categories" }}
    <h1>{{ "分类" }}</h1>
    {{- end }}
    {{- if eq .Title "Tags" }}
    <h1>{{ "标签" }}</h1>
    {{- end }}
    {{- if .Description }}
    <div class="post-description">
        {{ .Description }}
    </div>
    {{- end }}
</header>
{{- end }}

<ul class="terms-tags">
    {{- $type := .Type }}
    {{- $tagsByCount := $.Site.Taxonomies.tags.ByCount }}
    {{- if gt (len $tagsByCount) 0 }}
        {{- $max := add (len (index $tagsByCount 0).Pages) 1 }}
        {{- $lastIndex := sub (len $tagsByCount) 1 }}
        {{- $min := len (index $tagsByCount $lastIndex).Pages }}
        {{- $largestFontSize := 1.5 }}
        {{- $smallestFontSize := 1 }}
        {{- $fontSpread := sub $largestFontSize $smallestFontSize }}
        {{- $spread := sub $max $min }}
        {{- $fontStep := div $fontSpread $spread }}

        {{- range $key, $value := .Data.Terms.Alphabetical }}
            {{- $name := .Name }}
            {{- $count := .Count }}
            {{- with $.Site.GetPage (printf "/%s/%s" $type $name) }}
            <li>
                {{- $weight := div (sub (math.Log $count) (math.Log $min)) (sub (math.Log $max) (math.Log $min)) }}
                {{- $currentFontSize := add $smallestFontSize (mul (sub $largestFontSize $smallestFontSize) $weight) }}
                <a href="{{ .Permalink }}" style="font-size: {{ $currentFontSize }}rem; font-weight: {{ mul $currentFontSize 300 }};">
                    {{ .Name }} <sup><strong><sup>{{ $count }}</sup></strong></sup>
                </a>
            </li>
            {{- end }}
        {{- end }}
    {{- end }}
</ul>

{{- end }}

assets/css/extended/tags.css

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
.terms-tags {
    text-align: center;
}

.terms-tags a {
    border-radius: 30px;
    background: none;
    transition: transform 0.5s;
}

.terms-tags a:hover {
    background: none;

    -webkit-transform: scale(1.2);
    -moz-transform: scale(1.2);
    -ms-transform: scale(1.2);
    -o-transform: scale(1.2);

    transform: scale(1.2);

    transition: box-shadow 0.4s ease, transform 0.4s ease;

}

.dark .terms-tags a {
    background: none;
}

.dark .terms-tags a:hover {
    background: none;

    -webkit-transform: scale(1.2);
    -moz-transform: scale(1.2);
    -ms-transform: scale(1.2);
    -o-transform: scale(1.2);

    transform: scale(1.2);

    transition: box-shadow 0.4s ease, transform 0.4s ease;
}

.terms-tags li {
    margin: 5px;
}

主页样式

使用papermod默认的Home-Info模式,删除home-info区块,直接显示文章

layouts/partials/home_info.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{{- $params := .Site.Params.homeInfoParams }}
{{- if or $params.Title $params.Content }}
<section class="home-info">
  {{- if $params.Title }}
    <h1>{{ $params.Title }}</h1>
  {{- end }}
  {{- if $params.Content }}
    <p>{{ $params.Content }}</p>
  {{- end }}
</section>
{{- end }}

文章页面

content/posts/_index.md

1
2
3
---
title: "文章"
---

content/posts/config/_index.md

1
2
3
4
5
title: "配置"
cover:
    image: ""
hidemeta: true 
weight: 1

文章页面下增加二级目录显示文章分类

layouts/posts/list.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
{{ define "main" }}
<header class="page-header">
  <h1>{{ .Title }}</h1>
  {{- if .Description }}
  <div class="content">{{ .Description }}</div>
  {{- end }}
</header>

{{- if .Content }}
<div class="post-content">
  {{ .Content }}
</div>
{{- end }}

<!-- 如果是顶层posts页面,则显示分类列表 -->
{{ if eq .RelPermalink "/posts/" }}
  <div class="categories-container">
    {{ range .Sections }}
      <div class="category-card">
        <div class="category-content">
          <h2 class="category-title">
            <a href="{{ .RelPermalink }}">{{ .Title }}</a>
          </h2>
          {{ if .Description }}
            <div class="category-description">{{ .Description }}</div>
          {{ end }}
          <div class="category-count">{{ len .Pages }} 篇文章</div>
        </div>
      </div>
    {{ end }}
  </div>
{{ else }}
  <!-- 如果是分类页面,则显示该分类下的文章列表 -->
  <div class="posts-list">
    {{ range .Pages }}
      <article class="post-entry">
        {{ if .Params.image }}
        <div class="featured-image">
          <img src="{{ .Params.image }}" alt="{{ .Title }}" loading="lazy">
        </div>
        {{ end }}
        <div class="post-content-wrapper">
          <header class="entry-header">
            <h2>{{ .Title }}</h2>
          </header>
          <div class="entry-content">
            <p>{{ .Summary }}</p>
          </div>
          <footer class="entry-footer">
            <span class="post-date">{{ .Date.Format "2006-01-02" }}</span>
          </footer>
        </div>
        <a class="entry-link" href="{{ .Permalink }}"></a>
      </article>
    {{ end }}
  </div>
{{ end }}
{{ end }}

assets/css/extended/custom.css

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* 分类容器样式 */
.categories-container {
    display: flex;
    flex-direction: column;
    gap: 20px;
    margin-top: 30px;
  }
  
  /* 分类卡片样式 */
  .category-card {
    display: flex;
    align-items: center;
    background-color: var(--entry);
    border-radius: 12px;
    padding: 20px;
    transition: all 0.3s ease;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    border: 1px solid var(--border);
  }
  
  .category-card:hover {
    transform: translateX(10px);
    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
    border-color: var(--primary);
  }
  
  
  /* 分类内容区域 */
  .category-content {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  
  /* 分类标题样式 */
  .category-title {
    margin: 0 0 10px 0;
    font-size: 1.4rem;
    color: var(--primary);
  }
  
  .category-title a {
    text-decoration: none;
    color: inherit;
    transition: color 0.2s ease;
  }
  
  .category-card:hover .category-title a {
    color: var(--secondary);
  }
  
  /* 分类描述样式 */
  .category-description {
    color: var(--secondary);
    font-size: 0.95rem;
    line-height: 1.6;
    margin-bottom: 10px;
  }
  
  /* 分类文章计数样式 */
  .category-count {
    display: inline-flex;
    align-items: center;
    background-color: var(--tertiary);
    color: var(--primary);
    padding: 4px 12px;
    border-radius: 20px;
    font-size: 0.8rem;
    font-weight: 500;
    align-self: flex-start;
  }
  
  /* 响应式调整 */
  @media (max-width: 600px) {
    .category-card {
      flex-direction: column;
      text-align: center;
      padding: 15px;
    }
  
    .category-icon {
      margin-right: 0;
      margin-bottom: 15px;
    }
  
    .category-content {
      align-items: center;
    }
  
    .category-count {
      align-self: center;
    }
  }

自定义样式

文章封面右悬&&hover效果

assets/css/extend/side-cover.css

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* 文章卡片的Grid布局 */
.post-entry {
  display: grid;
  grid-template-columns: 4fr 1fr;
  align-items: center;
  
  /* 添加卡片样式 */
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 15px;
  background-color: var(--entry);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.05);
  
  /* 添加过渡效果 */
  transition: all 0.3s ease;
}

/* 封面图定位 */
.post-entry .entry-cover {
  grid-row: span 3;
  margin: auto;
}

/* 标题定位 */
.post-entry .entry-header {
  grid-row-start: 1;
  /* 
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
  */
}

/* 内容定位 */
.post-entry .entry-content {
  grid-row-start: 2;
}

/* 页脚定位 */
.post-entry .entry-footer {
  grid-row-start: 3;
}

/* 文章卡片的悬停效果 */
.post-entry:hover {
  transform: translateY(-5px); /* 轻微上浮效果 */
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); /* 加深阴影 */
  border-color: rgba(125, 125, 125, 0.2); /* 显示轻微边框 */
}

/* 封面图样式 */
.post-entry .entry-cover img {
  border-radius: 8px;
  transition: all 0.3s ease;
}

/* 添加标题悬停效果 */
.post-entry .entry-header h2 {
  transition: color 0.3s ease;
}

.post-entry:hover .entry-header h2 {
  color: #3498db; /* 悬停时标题变色,可根据您的主题颜色调整 */
}

/* 适配移动设备 */
@media (max-width: 768px) {
  .post-entry {
    grid-template-columns: 1fr; /* 在小屏幕上切换为单列布局 */
  }
  
  .post-entry .entry-cover {
    grid-row: 1; /* 封面图放在顶部 */
    margin-bottom: 15px;
  }
  
  .post-entry .entry-header {
    grid-row: 2;
  }
  
  .post-entry .entry-content {
    grid-row: 3;
  }
  
  .post-entry .entry-footer {
    grid-row: 4;
  }
}

查看特定文章分类下的文章,底部的上一篇和下一篇只导航到同一目录下的文章

layouts/partials/post_nav_links.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{{- $pages := where site.RegularPages "Type" "in" site.Params.mainSections }}

{{/* 如果页面有.File属性(即真实文件) */}}
{{- if .File }}
  {{/* 获取当前文章的目录路径 */}}
  {{- $currentDir := .File.Dir }}
  {{/* 过滤同一目录下的文章 */}}
  {{- $pages = where $pages "File.Dir" $currentDir }}
{{- end }}

{{- if and (gt (len $pages) 1) (in $pages . ) }}
<nav class="paginav">
  {{- with $pages.Next . }}
  <a class="prev" href="{{ .Permalink }}">
    <span class="title">« {{ default "上一篇" }}</span>
    <br>
    <span>{{- .Title -}}</span>
  </a>
  {{- end }}
  
  {{- with $pages.Prev . }}
  <a class="next" href="{{ .Permalink }}">
    <span class="title">{{ default "下一篇" }} »</span>
    <br>
    <span>{{- .Title -}}</span>
  </a>
  {{- end }}
</nav>
{{- end }}

部署

使用cloudflare pages而不是github pages的优点:

  • 可以将博客仓库设置为private
  • 自动部署,无需像github pages一样额外配置github actions
  • 自带CDN加速

自定义域名

Pages绑定自定义域名,需要先将域名交给Cloudflare托管,在Cloudflare中添加站点,会获得两个DNS服务解析器地址,在域名服务商内替换掉原有的nameservers。替换成功后,Cloudfare会增加一条DNS记录,将域名CNAME解析至pages.dev二级域名,现在配置自定义域名就成功了,可以通过自定义域名访问部署在Pages上的站点了。