Featured image of post 个人网站的建立过程(三):Hugo主题stack的使用与优化

个人网站的建立过程(三):Hugo主题stack的使用与优化

Hugo主题stack的使用与优化

本网站使用Hugo主题stack,此处记录一下如何使用不同的Hugo主题,stack主题的特点,以及对stack主题做的优化。

缘起

最初建立个人网站时使用了Hexo框架,也尝试了几个Hexo框架的主题,包括hexo-theme-yiliahexo-theme-yilia-plushexo-theme-next。也使用过一个用户名为“leirock”的GitHub用户基于hexo-theme-next创建的一个主题https://leirock.github.io/blog/,这个主题是我目前为止最喜欢的一个主题,其GitHub仓库地址为https://github.com/leirock/blog,效果如下:

leirock制作的基于hexo-theme-next的主题

然而遗憾的是,由于在Hexo上配置多语言十分糟心,我最终决定放弃Hexo,并转向了使用Hugo框架。使用Hugo框架后并没有尝试太多主题,一直在使用目前这个hugo-theme-stack。使用时发现这个主题缺了一些自己需要的功能,就动手修改了一下。

前置条件

安装主题

  • 我们把本地服务器上的网站目录称为“网站根目录”。例如~/Documents/www/website1是本文章中所用到的网站根目录。
  • 我们把网站根目录里面themes文件夹下的主题目录称为“主题根目录”。例如~/Documents/www/website1/themes/hugo-theme-stack是本文章中所用到的主题根目录。
  1. 首先进入本地服务器网站根目录下,使用下面的命令将stack主题放在themes文件夹下:

    1
    2
    
    cd ~/Documents/www/website1
    git clone https://github.com/CaiJimmy/hugo-theme-stack/ themes/hugo-theme-stack
    
  2. 应用示例网站。stack主题内带了一个示例网站,放在主题根目录下的exampleSite文件夹内,只要我们把exampleSite文件夹内的文件复制到网站根目录下,我们就可以应用示例网站了。不过需要注意的是,这将覆盖掉网站根目录下原有的同名文件,如果你不想让你的文件被覆盖掉,请在执行下面的命令前做好备份。

    将stack主题内exampleSite文件夹目录下的文件复制到网站根目录下:

    1
    
    cp -r themes/hugo-theme-stack/exampleSite/* ./
    

    然后需要删除Hugo在网站根目录下默认生成的config.toml,防止跟从stack主题exampleSite复制到网站根目录下的config.yaml冲突。

    1
    
    rm config.toml
    
  3. 预览示例网站。在网站根目录下执行如下命令:

    1
    
    hugo server
    

    然后在本地服务器打开浏览器,输入http://localhost:1313即可预览示例网站,显示效果可参见本文的封面图片,或stack主题作者给出的示例网站https://demo.stack.jimmycai.com/

基本使用指南

Hugo网站文件结构

网站根目录下面的文件夹目录树一般如下所示:

 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
.
├── archetypes                  
│   └── default.md
├── config.yaml                 # 网站配置文件
├── content                     # 站点内的内容都在这里
│   ├── categories              # “分类”页面的首页
│   │   └── Test                # “分类”页面下的一个分类页面
│   ├── page                    # 显示在网站主页左侧边栏菜单的选项
│   │   ├── about               # 左侧边栏菜单中的“关于”页面
│   │   ├── archives            # 左侧边栏菜单中的“归档”页面
│   │   ├── links               # 左侧边栏菜单中的“链接”页面
│   │   └── search              # 左侧边栏菜单中的“搜索”页面
│   └── post                    # 用户写的帖子都放在这里,每个子文件夹对应一个帖子
│       ├── chinese-test
│       ├── emoji-support
│       ├── markdown-syntax
│       ├── math-typesetting
│       ├── placeholder-text
│       └── rich-content
├── data
├── layouts
├── LICENSE
├── README.md
├── resources
│   └── _gen
│       ├── assets
│       └── images
├── static                     # 放用户自定义字体、用户头像、网站小图标等
└── themes                     # 放各种主题
    └── hugo-theme-stack       # stack主题
        ├── archetypes
        ├── assets
        ├── config.yaml
        ├── data
        ├── debug.sh
        ├── exampleSite
        ├── go.mod
        ├── i18n
        ├── images
        ├── layouts
        ├── LICENSE
        ├── netlify.toml
        ├── README.md
        └── theme.toml

此外,上面没有显示的是网站根目录下的private文件夹和public文件夹。

  • public文件夹会在运行hugo -D部署网站时生成,是暴露给外界的文件夹,网站上页面的HTML文件都会由Hugo生成并放在public文件夹下。public文件夹内不要放置任何包含用户信息的敏感文件!
  • private文件夹可以由用户创建,这里我们用它来存放网站的SSL证书。

关于网站根目录下各文件夹,更详细的说明可参见Hugo的官方文档https://gohugo.io/getting-started/directory-structure/

配置文件夹config

Hugo支持两种配置方式:

  • 一种是直接在网站根目录的.config文件中配置
  • 另一种是在网站根目录下创建config文件夹,配置放在config文件夹内

第二种配置方式支持将不同的配置项分开放在不同的文件中,相比第一种配置方式可以让配置项的条理更加清晰,因此我们这里选择第二种配置方式。本网站的配置目录结构如下所示:

1
2
3
4
5
6
7
8
config
  └── _default
      ├── config.yaml
      ├── languages.yaml
      ├── menu.en.yaml
      ├── menu.zh-cn.yaml
      ├── params.en.yaml
      └── params.zh-cn.yaml

关于Hugo的配置,更详细的说明可参考官方文档https://gohugo.io/getting-started/configuration/

修改并优化主题

这里我对原stack主题做了两项修改:

  • 为用户的联系方式添加自定义图标,使得主页左侧边栏用户头像下可以显示豆瓣、知乎、码云等图标
  • 在主页左侧边栏底部和文章页面右侧边栏顶部添加语言转换按钮,便于网页的中英文切换

自定义图标

由于原stack主题只提供了有限的几个社交图标,包括GitHub、Twitter和RSS,却不包含中国用户常用的微博、知乎等,所以我决定更换原stack主题使用的svg图标,引入包含微博、知乎等图标的字体。

之前用Hexo框架时,在Hexo的yilia主题和yilia-plus主题中看到过不少社交图标,于是就将这两款主题里的图标引入了stack主题,下面是具体操作。

  1. 获取yilia-plus主题中的字体。前往yilia-plus主题的GitHub仓库https://github.com/JoeyBling/hexo-theme-yilia-plus,下载其中source-src/css目录下的fonts文件夹,并将该文件夹复制到网站根目录下的static文件夹中。

  2. 更改stack主题菜单的样式。找到stack主题根目录下的assets/scss/partial/menu.scss文件,这是stack主题中左侧菜单的样式文件,将文件内最后一项定义.social-menu的代码块更换为如下代码:

      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
    
    .social-menu {
        list-style: none;
        padding: 0%;
        display: flex;
        flex-direction: row;
        gap: 0px;
        a {
            border-radius:50%;
            display:-moz-inline-stack;
            display:inline-block;
            vertical-align:middle;
            *vertical-align:auto;
            zoom:1;
            *display:inline;
            margin:0 8px 15px 8px;
            transition:0.3s;
            text-align: center;
            color: #fff;
            opacity: 0.7;
            width: 28px;
            height: 28px;
            line-height: 26px;
            &:hover {
                opacity:1
            }
        }
        a.weibo {
            background: #aaaaff;
            border:1px solid #aaaaff;
            &:hover {
                border:1px solid #aaaaff;
            }
        }
        a.segmentfault {
            background: #009a61;
            border:1px solid #009a61;
            &:hover {
                border:1px solid #009a61;
            }
        }
        a.rss {
            background: #ef7522;
            border:1px solid #ef7522;
            &:hover {
                border:1px solid #cf5d0f;
            }
        }
        a.github {
            background: #afb6ca;
            border:1px solid #afb6ca;
            &:hover {
                border:1px solid #909ab6;
            }
        }
        a.gitee {
            background: #c8171e;
            border:1px solid #c8171e;
            &:hover {
                border:1px solid #c8171e;
            }
        }
        a.facebook {
            background: #3b5998;
            border:1px solid #3b5998;
            &:hover {
                border:1px solid #2d4373;
            }
        }
        a.google {
            background: #4086f4;
            border:1px solid #4086f4;
            &:hover {
                border:1px solid #4086f4;
            }
        }
        a.twitter {
            background: #55cff8;
            border:1px solid #55cff8;
            &:hover {
                border:1px solid #24c1f6;
            }
        }
        a.linkedin {
            background: #005a87;
            border:1px solid #005a87;
            &:hover {
                border:1px solid #006b98;
            }
        }
        a.acfun {
            background: #fd4c5d;
            border:1px solid #fd4c5d;
            &:hover {
                border:1px solid #fd4c5d;
            }
        }
        a.bilibili {
            background: #e15280;
            border:1px solid #e15280;
            &:hover {
                border:1px solid #e15280;
            }
        }
        a.zhihu {
            background: #0078d8;
            border:1px solid #0078d8;
            &:hover {
                border:1px solid #0078d8;
            }
        }
        a.douban {
            background: #06c611;
            border:1px solid #06c611;
            &:hover {
                border:1px solid #06c611;
            }
        }
        a.mail {
            background: #005a87;
            border:1px solid #005a87;
            &:hover {
                border:1px solid #006b98;
            }
        }
        a.jianshu {
            background: #ff5722;
            border:1px solid #ff5722;
            &:hover {
                border:1px solid #ff5722;
            }
        }
        a.weixin {
            background: #4caf50;
            border:1px solid #4caf50;
            &:hover {
                border:1px solid #4caf50;
            }
        }
        a.qq {
            background: #34baad;
            border:1px solid #34baad;
            &:hover {
                border:1px solid #34baad;
            }
        }
        a.psn {
            background: #086ef6;
            border:1px solid #086ef6;
            &:hover {
                border:1px solid #086ef6;
            }
        }
    }
    
  3. 添加字符索引。该字体的字符索引将作为stack主题中的可定制样式文件中作为用户自定义样式。前往yilia-plus主题的GitHub仓库https://github.com/JoeyBling/hexo-theme-yilia-plus,下载其中的source-src/css/fonts.scss文件,将其中的内容全部复制到stack主题根目录下的assets/scss/custom.scss文件内。

  4. 打开stack主题根目录下的layouts/partials/sidebar/left.html文件,找到{{- with .Site.Menus.social -}}这一行,将这一行和其对应的{{- end -}}这一行中间的内容替换为以下内容:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    
            <ol class="social-menu">
                {{ range . }}
                    <li>
                        <a 
                            class="{{ .Identifier }}" href="{{ .URL }}" 
                            {{ with .Name }}title="{{ . }}"{{ end }}
                            {{ if eq (default true .Params.newTab) true }}target="_blank"{{ end }}
                        >
                            <i class="icon-{{ .Params.Icon }}"></i>
                        </a>
                    </li>
                {{ end }}
            </ol>
    
  5. 如需在主页左侧边栏头像下显示社交网站图标,则只需在配置文件中加入对应的项即可。例如如果想要显示GitHub和电子邮件,则可以在config/_default/menu.en.yamlconfig/_default/menu.zh-cn.yaml配置文件中加入如下配置内容:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    social:
    - identifier: github
        name: GitHub
        url: https://github.com/jin-li/
        params:
            icon: github
    
    - identifier: mail
        name: Email
        url: "mailto:[email protected]"
        params:
            icon: mail
    

    显示效果可参考本网站主页左侧边栏。

语言转换按钮

尽管Hugo框架原生支持多语言,但stack主题却未提供语言转换的按钮,我参考了Hugo论坛上的相关讨论,并修改了stack主题的代码,添加了语言转换的按钮。

具体功能有两个:

  • 在主页左侧边栏的底部“暗色模式”按钮下面添加一个语言转换按钮,实现全站的语言转换。
    • 在当前站点语言是中文时,点击按钮则站点语言变为英文
    • 在当前站点语言是英文时,点击按钮则站点语言变为中文
  • 在文章页面的右侧边栏顶部“目录”上面添加一个语言转换按钮,实现单个页面的语言转换。
    • 在当前页面对应有双语页面时,显示转为另一种语言的语言转换按钮
    • 在当前页面对应没有双语页面时,不显示语言转换按钮

具体效果可参考本网站。下面是具体操作。

  1. 下载一个翻译按钮的SVG文件,并放到stack主题根目录的assets/icons文件夹内。

  2. 找到stack主题根目录下的assets/scss/partials/sidebar.scss文件,此文件是定义网站侧边栏的样式文件。在文件末位添加如下内容:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    .language-select{
        align-self: stretch;
        color: var(--body-text-color);
        align-items: center;
    }
    .language-select #selected{
        font-weight: 500;
        display: flex;
        margin-top: 0px;
        margin-bottom: 0px;
    }
    .language-select #to-select{
        font-weight: 100;
        display: flex;
        a {
            margin-left: 60px;
        }
        margin-top: 0px;
        margin-bottom: 0px;
    }
    
  3. 找到stack主题根目录下的assets/scss/partials/layout/article.scss文件,加入以下内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    .widget--translation {
        background-color: var(--card-background);
        border-radius: var(--card-border-radius);
        box-shadow: var(--shadow-l1);
        display: flex;
        flex-direction: column;
        color: var(--card-text-color-main);
        overflow: hidden;
    }
    
  4. 找到stack主题根目录下的layouts/partials/sidebar/left.html文件,在该文件的倒数第3行处加入以下内容:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
            {{ if .Site.IsMultiLingual }}
                {{ $siteLanguages := .Site.Languages}}
                {{ $pageLang := .Page.Lang}}
                {{ range .Page.AllTranslations }}
                    {{ $translation := .}}
                    {{ range $siteLanguages }}
                        {{ if eq $translation.Lang .Lang }}
                            {{ $selected := false }}
                            {{ if eq $pageLang .Lang}}
                            {{ else }}
                                <div class="language-select">
                                    <li id="selected">{{ partial "helper/icon" "trans" }}<a href="{{ $translation.RelPermalink }}"><span>{{ .LanguageName }}</span></a></li>
                                </div>
                            {{ end }}
                        {{ end }}
                    {{ end }}
                {{ end }}
            {{ end }}
    
  5. 打开stack主题根目录下的layouts/_default/single.html文件,找到该文件最后一个定义右侧边栏的代码块。将其替换为以下内容:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
            {{ if .Site.IsMultiLingual }}
                {{ $siteLanguages := .Site.Languages}}
                {{ $pageLang := .Page.Lang}}
                {{ range .Page.AllTranslations }}
                    {{ $translation := .}}
                    {{ range $siteLanguages }}
                        {{ if eq $translation.Lang .Lang }}
                            {{ $selected := false }}
                            {{ if eq $pageLang .Lang}}
                            {{ else }}
                                <div class="language-select">
                                    <li id="selected">{{ partial "helper/icon" "trans" }}<a href="{{ $translation.RelPermalink }}"><span>{{ .LanguageName }}</span></a></li>
                                </div>
                            {{ end }}
                        {{ end }}
                    {{ end }}
                {{ end }}
            {{ end }}
    
  6. 在网站根目录配置文件夹config/_default内添加语言配置文件languages.yaml,加入以下内容:

    1
    2
    3
    4
    5
    6
    7
    
    en:
        languageName: "English"
        languageNameShort: "en"
    
    zh-cn:
        languageName: "简体中文"
        languageNameShort: "zh"
    

最后将两种语言对应的文章在文章文件夹内分别命名为index.zh-cn.mdindex.en.md,在用Hugo部署网站时Hugo就会自动生成两种语言的网页,并自动添加语言转换的按钮。

comments powered by Disqus