背景

好记性不如烂笔头,先前好多技术攻关后没有将过程记录下来,回想起来特别可惜。栽一棵树最好的时间是十年前,其次是现在。现在就把博客搭建起来,为以后的一些攻关技术和思考备忘一下,给回忆增加些内容。

技术框架

Windows + Hugo + Github Pages + Vercel

准备环境

  • Windows 10+ 以上版本
  • Hugo extended windows/amd64 版本,扩展版本解决了很多系统问题
  • Git bash 执行 hugo命令、下载主题、上传源码到Github
  • 本地已安装好 golang 环境
  • 已创建好本地和 Github 的密钥连接

开始搭建Hugo博客

1. 了解 Hugo

查看官方文档 Hugo Official Docs中文文档 获取帮助手册

Hugo学习笔记

有哪些好看的Hugo主题?

hugo中文帮助文档

started

2. 下载配置 Hugo

Hugo Releases 直接下载安装适合的版本。我创建博客时是2022年9月7日,最新版本是 v0.102.3。下载后解压到安装路径,比如我的安装路径是:C:\Users\Ludard\Programs\hugo。然后将此路径加入到系统环境变量。

decompressed

path

打开命令行,输入命令:hugo version,如果显示版本信息表示已正确配置。

如果输入命令后显示:'hugo' 不是内部或外部命令,也不是可运行的程序或批处理文件。 应该是没有加入到系统环境变量或者需要重启计算机。

test_hugo

注意:我第一次创建网站后删除网站目录,然后再启动调试时报错:Error: Error building site: TOCSS: failed to transform "sass/jane.scss"。官方的 解决方案 是使用扩展程序,也就是含有 extend 的程序,比如Windows就是 hugo_extended_0.102.3_Windows-64bit.zip。然后再启动就可以了

install_error

install_err

3. 创建博客网站

打开 Git bash 命令行工具,切换到想到保存网站内容的路径,使用命令:hugo new site myBlog 创建网站。然后就在当前目录创建了一个博客目录。

如果不想切换目录,可以在创建网站时指定绝对路径:hugo new site /path/to/site

new_site

site_ls

4. 下载博客主题

我的使用的博客主题是 hugo-theme-jane ,使用下列命令下载主题:

1
2
3
cd myBlog/
git init
git clone https://github.com/xianmin/hugo-theme-jane.git --depth=1 themes/jane

hugo_theme

5. 设置博客主题

1
2
cp -r themes/jane/exampleSite/content ./    #复制一些示例文本
cp themes/jane/exampleSite/config.toml ./   #复制默认的站点设置

hugo_theme_conf

6. 创建文章

1
2
 hugo new post/test.md    #创建文章,保存在 content\post 目录下
 hugo new about.md        #创建关于页面

hugo_new_post

7. 启动 hugo 博客

使用命令 hugo server 启动博客:

start_hugo_cmd

如果要显示草稿文章要使用命令 hugo server -D

然后打开浏览器输入地址:http://localhost:1313/http://127.0.0.1:1313/ 即可看到博客内容:

start_hugo_blog

如果在启动时报错:failed to transform "sass/jane.scss"

打开目录 C:\Users\Ludard\AppData\Local\Temp\hugo_cache (Ludard为本机用户名),删除此目录即可

8. 博客定制

预览博客页面正常表示创建成功,就可以开始配置博客为自己喜欢的样式了。

修改之前先将博客内容提交到git,方便修改出错回退

1
2
3
git status
git add .
git commit -m 'init myBlog'

hugo_blog_git

0x1 博客配置

  • 默认配置文件 config.toml 位于网站的根目录,按自身需要进行定制。
  • 可以参考 https://github.com/xianmin/hugo-theme-jane/tree/master/exampleSite 设置,包含了一个示例 config.toml 配置和 full-config.toml配置,还有一些示例文章。将 config.toml 复制到自己的网站根目录,按自身需要进行修改。(修改配置后网站是实时预览的,非常方便。)

我的博客配置:

  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
167
168
169
170
171
172
173
# 正式环境 http://ludard.com
baseURL = "http://ludard.com"            # 本地调试 http://localhost:1313/
title = "卢达的技术博客 - 专注于C#|Go|DevOps|运维开发"
enableRobotsTXT = true
enableEmoji = true
theme = "jane"

hasCJKLanguage = true # has chinese/japanese/korean ? # 自动检测是否包含 中文\日文\韩文
paginate = 3          # Number of articles displayed on the homepage  # 首页每页显示的文章数
rssLimit = 20         # Limit Entry Count to Rss file # 限制 Rss 文章输出数量
disqusShortname = ""  # disqus_shortname
googleAnalytics = ""  # UA-XXXXXXXX-X
copyright = "卢达"      # default: author.name ↓        # 默认为下面配置的author.name ↓
enableGitInfo = true  # use git commit log to generate lastmod record # 可根据 Git 中的提交生成最近更新记录。
# uglyURLs = true         # more info: https://gohugo.io/content-management/urls/#ugly-urls

languageCode = "zh"
# language support # en / zh-cn / other... translations present in i18n/
defaultContentLanguage = "zh-cn" # Default language to use
[languages.en]
languageCode = "en"
[languages.zh-cn]
languageName = "中文"
weight = 2

[author] # essential                     # 必需
  name = "卢达"

[sitemap] # essential                    # 必需
  changefreq = "weekly"
  priority = 0.5
  filename = "sitemap.xml"

# 配置主菜单
[[menu.main]]
  name = "主页"
  weight = 10
  identifier = "home"
  url = "/"
[[menu.main]]
  name = "文章列表"
  weight = 20
  identifier = "archives"
  url = "/post/"
[[menu.main]]
  name = "标签"
  weight = 30
  identifier = "tags"
  url = "/tags/"
[[menu.main]]
  name = "分类"
  weight = 40
  identifier = "categories"
  url = "/categories/"


# 代码语法高亮(老版本)
# [highlighting]
#   pygmentsUseClassic = true
#   pygmentsCodeFences = true
#   PygmentsCodefencesGuessSyntax = true
#   pygmentsStyle = "autumn"
#   PygmentsOptions = "linenos=table"

# PygmentsCodeFences = true             # 等同[markup] codeFences = true
# PygmentsUseClasses = true             # 等同[markup] noClasses = false
# PygmentsCodefencesGuessSyntax = true  # 等同[markup] guessSyntax = true
# PygmentsOptions = "linenos=table"     # 等同[markup] lineNumbersInTable = true
# pygmentsStyle = "manni"

# 代码语法高亮,只应用下面的设置即可,如果应用上面就覆盖了
# 更多设置:https://gohugo.io/getting-started/configuration-markup
[markup]
  [markup.highlight]
    anchorLineNos = true
    codeFences = true         # 代码围栏功能,组织成代码块
    guessSyntax = true        # 猜测语法高亮
    hl_Lines = ''             # 高亮的行号,应用于所有代码块。在具体的代码块内设置
    hl_inline = false         # 将块代码显示为一行,开启后很难看
    lineAnchors = ''
    lineNoStart = 1           # 行号编号起始位置
    lineNos = true            # 是否显示行号,如果为false不能应用Table样式也就不显示语言
    lineNumbersInTable = true # 使用表来格式化行号和代码,而不是标签
    noClasses = false         # 使用 style 主题样式,如果为false 使用自定义主题样式
    noHl = false
    style = 'manni'           # 默认monokai 更多:https://xyproto.github.io/splash/docs/all.html
    tabWidth = 4


[params]
  since = "2022"          # Site creation time          # 站点建立时间
  homeFullContent = false # if false, show post summaries on home page. Otherwise show full content.
  rssFullContent = false  # if false, Rss feed instead of the summary

  # site info (optional)                                  # 站点信息(可选,不需要的可以直接注释掉)
  logoTitle = "卢达的博客"                                 # default: the title value    # 默认值: 上面设置的title值
  keywords = ["ludard", "C#", ".NET", "go", "golang"]
  description = "卢达的技术博客,专注于 C#/Go/DevOps/运维开发。"

  # 每篇文章下面显示作者信息
  showAuthorInfo = true

  # 日期显示样式, see https://gohugo.io/functions/format/
  dateFormatToUse = "2006-01-02"

  # 是否显示字数统计与阅读时间 样式:「约 1812 字  预计阅读 4 分钟」
  # moreMeta = true

  # 显示中英文语言切换菜单
  # showMenuLanguageChooser = true

  # 添加备案信息
  # customFooter = "京ICP备10000000号-1"

  # 网站左上角显示 Fork me on Github 条带
  # forkMeOnGithub = "https://github.com/xianmin/hugo-theme-jane"

  # 文章全局默认配置,也可以在每篇文章的 front matter 中针对单篇内容关闭或开启某些功能,archetypes/default.md 是模板文件。
  toc = true                                                                                                                                                                       # 是否开启目录
  photoswipe = true                                                                                                                                                                # 是否启用PhotoSwipe(图片可点击)  # see https://github.com/dimsemenov/PhotoSwipe
  bootcdn = false                                                                                                                                                                  # 是否使用bootcdn(@Deprecated: 请使用[params.publicCDN]配置)
  mathjax = true                                                                                                                                                                   # 是否使用mathjax(数学公式)  see https://www.mathjax.org/
  katex = false                                                                                                                                                                    # 是否使用KaTeX (排版格式) see https://github.com/KaTeX/KaTeX
  contentCopyright = '<a rel="license noopener" href="https://creativecommons.org/licenses/by-nc-nd/4.0/deed.zh"   target="_blank">署名-非商业性使用-禁止演绎 4.0 国际许可协议(CC BY-NC-ND 4.0)</a>'

  # 自定义样式和效果,样式文件要放在相对路径 /static/css 和 /static/js 目录下
  customCSS = ["revise-style.css", "manni-code-syntax.css"] # 如果启用 ['custom.css'], 加载 '/static/css/custom.css' 文件
  customJS = [] # if ['custom.js'], load '/static/js/custom.js' file

  changyanAppid = ""       # Changyan app id             # 畅言
  changyanAppkey = ""      # Changyan app key
  tencent_analytics = ""   # Tencent Analytics
  baidu_push = false       # baidu push                  # 百度
  baidu_analytics = ""     # Baidu Analytics
  baidu_verification = ""  # Baidu Verification
  google_verification = "" # Google_Verification         # 谷歌

  [params.publicCDN] # 启用公共CDN,需自行定义
    enable = false
    jquery = '<script src="https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"   integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>'
slideout = '<script src="https://cdn.jsdelivr.net/npm/slideout@1.0.1/dist/slideout.min.js" integrity="sha256-t+zJ/g8/KXIJMjSVQdnibt4dlaDxc9zXr/  9oNPeWqdg=" crossorigin="anonymous"></script>'
    gitmentJS = '<script src="https://cdn.jsdelivr.net/npm/gitment@0.0.3/dist/gitment.browser.min.js" crossorigin="anonymous"></script>'
    gitmentCSS = '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitment@0.0.3/style/default.min.css" crossorigin="anonymous">'
    photoswipe = '<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.js"   integrity="sha256-AC9ChpELidrhGHX23ZU53vmRdz3FhKaN9E28+BbcWBw=" crossorigin="anonymous"></script>'
    photoswipeUI = '<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js" integrity="sha256-UKkzOn/  w1mBxRmLLGrSeyB4e1xbrp4xylgAWb3M42pU=" crossorigin="anonymous"></script>'
    photoswipeCSS = '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.css"   integrity="sha256-SBLU4vv6CA6lHsZ1XyTdhyjJxCjPif/TRkjnsyGAGnE=" crossorigin="anonymous">'
    photoswipeSKIN = '<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.css"   integrity="sha256-c0uckgykQ9v5k+IqViZOZKc47Jn7KQil4/MP3ySA3F8=" crossorigin="anonymous">'

  [params.social] # 社交链接
    a-email = "mailto:ludard@outlook.com"
    g-github = "https://github.com/ludard"

  [params.reward] # 文章打赏
    enable = false
    wechat = "/path/to/your/wechat-qr-code.png" # 微信二维码
    alipay = "/path/to/your/alipay-qr-code.png" # 支付宝二维码

  [params.counter.busuanzi] # a Chinese visitor counter  # 不蒜子计数器
    enable = true

  [params.counter.leancloud] # Chinese leancloud visitor counter  # leancloud 计数器
    enable = false
    appId = ""
    appKey = ""

  [params.commentCount.disqus] # show counts of comments for Disqus
    enable = false

  # 指定 git 仓库地址,可以生成指向最近更新的 git commit 的链接,需要将 enableGitInfo 设置成 true.
  [params.gitInfo]
    gitRepo = "https://github.com/ludard/hugo-blog-code"
    showCommitMessage = true
    

0x2 文章设置

  • 默认文章文件位于 ./content/post 目录。

  • 直接运行 hugo 命令,将会自动将网站内容生成到 public/ 目录。

  • 单篇文章配置,Hugo 允许你使用 yaml, toml 或者 json 语法在你每一篇文章的开头进行设置,称为 元数据

    1. 设置模板位于 themes\jane\archetypes 有两个文件模板:default.mdpost.mddefault.md 是除 post外的所有文章的默认模板,如 aboutpost.mdpost目录内所有文章的模板
    2. 要应用这些默认设置需要使用命令 hugo new post/test.md 创建文章,手动创建 Markdown的文章是没有的。
    3. 最好禁用 themes\jane\archetypes\post.md 版权设置,禁用后使用全局配置。 # contentCopyright: true ,如果取消注释自动启用。

常用配置:

  • weight: 1 置顶文章

  • 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
    
    ---
    title: "{{ replace .TranslationBaseName "-" " " | title }}"  # 文章标题,如果有空格用 - 代替
    date: {{ .Date }}             # 创建日期
    lastmod: {{ .Date }}          # 最后修改日期
    draft: true                   # 文章中否是草稿,如果是发布后不显示
    keywords: ["技术"]             # 文章关键字
    description: ""               # 文章描述,方便搜索引擎搜索
    tags: []                      # 文章的标签 
    categories: ["技术"]           # 文章分类,在导航菜单分类里可以看到
    author: "卢达"                 # 文章作者
    slug: blog-url-path           # 文章的名称,默认是 `title` 的值。我一般title使用中文,slug使用英文
    url: post/tech/blog-url-path  # 显示在浏览器URL地址栏的地址
    
    # Uncomment to pin article to front page
    # weight: 1                   # 置顶文章
    # You can also close(false) or open(true) something for this content.
    # P.S. comment can only be closed
    comment: true                 # 是否显示评论区
    toc: true                     # 显示文章目录
    autoCollapseToc: true         # 自动展开目录
    # You can also define another contentCopyright. e.g. contentCopyright: "This is another copyright."
    # contentCopyright: true
    reward: false                 # 是否开启打赏
    mathjax: true                 # 是否支持数字公式
    
    # Uncomment to add to the homepage's dropdown menu; weight = order of article
    # menu:
    #   main:
    #     parent: "docs"
    #     weight: 1
    ---
    
    <!--more-->
    Markdown 文章正文
    

0x3 自定义页面样式

如果不满意主题的样式,可以按 F12 调整,然后将样式保存在根目录的 \static\css 目录下,然后修改博客配置添加自定义样式文件名称。

比如我自定义了2个文件,revise-style.cssmanni-code-syntax.css。修改 config.toml 配置,添加这2个样式文件:

1
2
3
4
customCSS = [
  "revise-style.css",
  "manni-code-syntax.css",
]

revise-style.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
/*代码块样式*/
.post .post-content code, .post .post-content pre{
    /* padding: 2px 4px; */
    font-size: 0.75em;
}

.post .post-content .highlight code::after{
    color: #93a1a1;
}

/*标签样式*/
.post .post-footer .post-tags a {
    color: #c05b4d;
    word-break: break-all;
    margin-right: 10px;
    padding: 1px 10px;
    border: 1px solid;
    border-radius: 20px;
    border-color: #9e9e9e;
}

.post .post-footer .post-tags a::before {
    content: '';
}

manni-code-syntax.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
/* Background */ .bg { background-color: #f8f8f8; }
/* PreWrapper */ .chroma { background-color: #f8f8f8; }
/* Other */ .chroma .x {  }
/* Error */ .chroma .err { color: #aa0000; background-color: #ffaaaa }
/* CodeLine */ .chroma .cl {  }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #ffffcc }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #006699; font-weight: bold }
/* KeywordConstant */ .chroma .kc { color: #006699; font-weight: bold }
/* KeywordDeclaration */ .chroma .kd { color: #006699; font-weight: bold }
/* KeywordNamespace */ .chroma .kn { color: #006699; font-weight: bold }
/* KeywordPseudo */ .chroma .kp { color: #006699 }
/* KeywordReserved */ .chroma .kr { color: #006699; font-weight: bold }
/* KeywordType */ .chroma .kt { color: #007788; font-weight: bold }
/* Name */ .chroma .n {  }
/* NameAttribute */ .chroma .na { color: #330099 }
/* NameBuiltin */ .chroma .nb { color: #336666 }
/* NameBuiltinPseudo */ .chroma .bp {  }
/* NameClass */ .chroma .nc { color: #00aa88; font-weight: bold }
/* NameConstant */ .chroma .no { color: #336600 }
/* NameDecorator */ .chroma .nd { color: #9999ff }
/* NameEntity */ .chroma .ni { color: #999999; font-weight: bold }
/* NameException */ .chroma .ne { color: #cc0000; font-weight: bold }
/* NameFunction */ .chroma .nf { color: #cc00ff }
/* NameFunctionMagic */ .chroma .fm {  }
/* NameLabel */ .chroma .nl { color: #9999ff }
/* NameNamespace */ .chroma .nn { color: #00ccff; font-weight: bold }
/* NameOther */ .chroma .nx {  }
/* NameProperty */ .chroma .py {  }
/* NameTag */ .chroma .nt { color: #330099; font-weight: bold }
/* NameVariable */ .chroma .nv { color: #003333 }
/* NameVariableClass */ .chroma .vc {  }
/* NameVariableGlobal */ .chroma .vg {  }
/* NameVariableInstance */ .chroma .vi {  }
/* NameVariableMagic */ .chroma .vm {  }
/* Literal */ .chroma .l {  }
/* LiteralDate */ .chroma .ld {  }
/* LiteralString */ .chroma .s { color: #A05A48 }
/* LiteralStringAffix */ .chroma .sa { color: #A05A48 }
/* LiteralStringBacktick */ .chroma .sb { color: #A05A48 }
/* LiteralStringChar */ .chroma .sc { color: #A05A48 }
/* LiteralStringDelimiter */ .chroma .dl { color: #A05A48 }
/* LiteralStringDoc */ .chroma .sd { color: #A05A48; font-style: italic }
/* LiteralStringDouble */ .chroma .s2 { color: #A05A48 }
/* LiteralStringEscape */ .chroma .se { color: #A05A48; font-weight: bold }
/* LiteralStringHeredoc */ .chroma .sh { color: #A05A48 }
/* LiteralStringInterpol */ .chroma .si { color: #aa0000 }
/* LiteralStringOther */ .chroma .sx { color: #A05A48 }
/* LiteralStringRegex */ .chroma .sr { color: #33aaaa }
/* LiteralStringSingle */ .chroma .s1 { color: #A05A48 }
/* LiteralStringSymbol */ .chroma .ss { color: #ffcc33 }
/* LiteralNumber */ .chroma .m { color: #ff6600 }
/* LiteralNumberBin */ .chroma .mb { color: #ff6600 }
/* LiteralNumberFloat */ .chroma .mf { color: #ff6600 }
/* LiteralNumberHex */ .chroma .mh { color: #ff6600 }
/* LiteralNumberInteger */ .chroma .mi { color: #ff6600 }
/* LiteralNumberIntegerLong */ .chroma .il { color: #ff6600 }
/* LiteralNumberOct */ .chroma .mo { color: #ff6600 }
/* Operator */ .chroma .o { color: #555555 }
/* OperatorWord */ .chroma .ow { color: #000000; font-weight: bold }
/* Punctuation */ .chroma .p {  }
/* Comment */ .chroma .c { color: #A0A1A7; font-style: italic }
/* CommentHashbang */ .chroma .ch { color: #A0A1A7; font-style: italic }
/* CommentMultiline */ .chroma .cm { color: #A0A1A7; font-style: italic }
/* CommentSingle */ .chroma .c1 { color: #A0A1A7; font-style: italic }
/* CommentSpecial */ .chroma .cs { color: #A0A1A7; font-weight: bold; font-style: italic }
/* CommentPreproc */ .chroma .cp { color: #009999 }
/* CommentPreprocFile */ .chroma .cpf { color: #009999 }
/* Generic */ .chroma .g {  }
/* GenericDeleted */ .chroma .gd { background-color: #ffcccc }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericError */ .chroma .gr { color: #ff0000 }
/* GenericHeading */ .chroma .gh { color: #003300; font-weight: bold }
/* GenericInserted */ .chroma .gi { background-color: #ccffcc }
/* GenericOutput */ .chroma .go { color: #aaaaaa }
/* GenericPrompt */ .chroma .gp { color: #000099; font-weight: bold }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { color: #003300; font-weight: bold }
/* GenericTraceback */ .chroma .gt { color: #99cc66 }
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
/* TextWhitespace */ .chroma .w { color: #bbbbbb }

0x4 自定义代码块主题颜色

自定义代码块主题颜色步骤:

  1. 将博客 config.toml 配置的 noClasses 设置为 false

    1
    2
    3
    
    [markup]
      [markup.highlight]
        noClasses = false         # 使用 style 主题样式,如果为false 使用自定义主题样式
    
  2. 使用命令 hugo gen chromastyles --style=manni > manni-code-syntax.css 在当前目录生成 manni-code-syntax.css 文件,再剪切到 \static\css 目录下,然后修改文件的样式或颜色。

    注意:manni 是默认支持的主题模板。默认支持的所有主题:Chroma Style Gallery

    manni-code-syntax.css 是自定义的主题样式文件名称,修改样式里的颜色 color 部分即可,其它的内容最好不要改。

    在修改颜色时最好使用替换,将同一种颜色全部替换为自定义的颜色,这样主题颜色更统一一些。

  3. 代码块支持的所有可以高亮的语言 List of Chroma Highlighting Languages ,如果一种语言有多种叫法只需要确定一种即可,比如代码块是 C# 语言,使用 csharpc# 标记都可以

    1
    2
    3
    
    ```csharp
    // ... code
    ```
    
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    Bash
    bash, sh, ksh, zsh, shell
    
    C#
    csharp, c#
    
    CoffeeScript
    coffee-script, coffeescript, coffee
    
    CoffeeScript
    coffee-script, coffeescript, coffee
    
    Go
    go, golang
    Go HTML Template
    go-html-template
    Go HTML Template
    go-html-template
    Go Text Template
    go-text-template
    GraphQL
    graphql, graphqls, gql
    
    ...
    
  4. 在代码块内也可以高亮某一块区域,

    1
    2
    3
    
    ```go {linenos=table,hl_lines=[8,"15-17"],linenostart=199}
    // ... code
    ```
    

    效果图:

    code_highlighting

​ 更多语法:syntax-highlighting

0x5 自定义文章结构

定义文章保存物理结构:

文章保存物理结构主要是保存在本地的组织结构。所有博客文章默认都保存在 content\post 目录下,如果所有文章都直接放这个目录下时间长了非常难找。所以我是按年份在 post 下新建一级目录,如 20222023,然后在年份目录下再按月份新建目录,如 010212,文章放放在对应的年月目录下。为了方便在本地查看和搜索,所有文章名称格式都是 文章顺序编号.文章中文标题.md。比如:001.Hugo博客搭建_1_搭建本地运行环境.md

如果要查找只需要查看文章创建日期然后到对应的目录下就可以找到了。

定义文章显示逻辑结构:

文章显示逻辑结构主要是浏览器打开博客文章时显示在 URL 地址的结构。通过每篇文章的元数据标签 slugurl可以自定义文章URL的组织结构。

  • slug 最终URL路径里的文章名称,最好使用英文防止转义乱码(将中文标题翻译为英文即可)。方便URL显示,中文又长又容易乱码,不方便记忆。
  • url 自定义文章的URL地址,我定义的结构是 文章类型 + 分类 + slug,比较简短好记。文章类型有 postbook等,分类主要有 techcsharpgolangthinkinglive

比如 001.Hugo博客搭建_1_搭建本地运行环境.md 的文章设置:

  • title: "「Hugo 博客搭建」1.搭建本地运行环境"

  • slug: create-blog-step-by-step-1

  • url: post/tech/create-blog-step-by-step-1

博客首页和浏览器标签页的标题就是 「Hugo 博客搭建」1.搭建本地运行环境

打开博客后的文章URL就是 https://ludard.com/post/tech/create-blog-step-by-step-1

使用这种 分组 + 分类 + 标题 的URL更简洁更容易记忆和理解一些。

它还有一个好处,使用更短的地址 https://ludard.com/post 可以显示所有文章。

更多内容组织可查看官方文档 Content Organization

结构图:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
content
├─ about.md
├─ post
│  ├─ 2022
│  │  └─ 09
│  │     ├─ 001.Hugo博客搭建_1_搭建本地运行环境.md
│  │     ├─ 002.Hugo博客搭建_2_Github Action配置.md
│  │     └─ 003.Hugo博客搭建_3_博客加速和自定义域名.md
│  └─ syntax-highlighting.md
└─ README.md

0x6 自定义图片结构

文章的图片默认保存在 static\image目录下,和文章一样,时间长了也不容易整理。所以我也是按年月创建目录。

文章引用图片时有2种方式:

  • 网络图床,引用时直接使用图片的网络地址,比如:https://ludard.com/image/ludard_logo.png
  • 本地图片,我使用本地图片

在生成博客时,Hugo 会将 static 下的所有内容都复制到 public 目录下,所以图片保存好之后文章的引用路径就是:

![图片缺省或无法加载时的说明](/image/2022/09/创建日_编号_图片名称.png)

比如:![hugo_started](/image/2022/09/13_01_hugo_started.png)

可以把 public 当成根目录 /,图片在Markdown编辑器里无法预览是正常的,网站编译上线后会正常显示的。

图片目录结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
static
├─ css
│  ├─ manni-code-syntax.css
│  └─ revise-style.css
└─ image
   ├─ 2022
   │  └─ 09
   │     ├─ 13_01_started.png
   │     ├─ 13_02_decompressed.png
   │     └─ 13_03_path.png
   └─ about_banner.png

0x7 置顶文章

在文章元数据里设置:weight: 1 即可将文章设置为置顶文章。

pin

pin

0x8 只显示文章摘要信息

如果文章太长,在首页显示时默认显示非常长,可以在想要截断的地方加上 <!--more--> 标记做截断,这样首页就只显示标记以上的内容+阅读全文。

only_view_summary

only_view_summary

0x9 博客多语言支持

如果网站要支持多国语言,需要对 languages 进行配置。

翻译位于 i18n/ 文件夹下。

使用特定的翻译:

1
2
3
4
# 使用中文
defaultContentLanguage = "zh-cn"  # 默认使用的语言
[Languages.zh-cn]
  languageCode = "zh-cn"

有关多语言设置,请查看 Multilingual Mode | Hugo

0x10 博客主题自定义开发

如果要调整的样式非常多,可以在原有的主题上进行自定义开发。

使用 npm 安装依赖:

1
2
npm install
npm install

命令会同时运行 webpack --watchhugo server 。 如果你修改了任何文件,浏览器将会自动更新。

9. 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
#更新到最新hugo版本
go get -u -v github.com/spf13/hugo

# 查看hugo版本、配置环境、帮助信息
hugo version
hugo env
hugo help

# all 列出所有文章 drafts 所有草稿 expired 过期文章 future 将来要发布的文章
hugo list all
hugo list drafts
hugo list expired
hugo list future

# 创建 about 页面,about.md 自动生成到了 content/about.md
hugo new about.md

# 创建文章,放到 post 目录,方便之后生成聚合页面
hugo new post/first.md

# Hugo调试加载指定主题+草稿文章
hugo server --theme=hyde --buildDrafts

# 预览时包含草稿文章 启动后在浏览器里打开: http://localhost:1313
# -D, --buildDrafts 草稿文章 
# -E, --buildExpired 过期文章
# -F, --buildFuture 将来要发布的文章
hugo server -D
hugo server --buildDrafts

# 修改默认端口,指定端口号预览
hugo server -p 端口
hugo server -p 1315

# 加载自定义配置文件 默认path/config.yaml|json|toml
hugo serve --config full-config.toml

# 加载指定目录的文章  -c, --contentDir
hugo serve -c "D:\github\hugo-blog-code\themes\jane\exampleSite"

# 生成网站,网站内容保存到 `public/` 目录
hugo

如果在预览网站时发现修改后的图片与static\image的图片不一样,可以删除博客缓存目录再启动调试。

缓存目录:C:\Users\Ludard\AppData\Local\Temp\hugo_cache\博客名称

Ludard 是计算机登录名,替换为自己的登录名

10. 生成网站

使用命令 hugo 生成网站,生成的内容保存在 public/ 目录

参考资源

Config配置参考

Hugo 代码高亮

Hugo的语法高亮配置

自定义hugo主题-导航菜单