2022-05-06    2024-05-20    9232 字  19 分钟

🎨 hugo-theme-virgo

为什么要把使用指南单独列出,而不是放在 README 中?

一方面,内容更新频繁(虽然没有必要),把更改放在 README 中需要每次都提交主题更新,然而有时候只是单纯的更新 README 而已。

另一方面,国内网络推送到 Github 仓库的时候经常抽风 (如下图),速度也慢。

![[assets/Pasted image 20230815144943.png]]

更新日志

- 2024-05-09 10:57 [可配置] 导航页增加迷你必应搜索(供导航页向下滚动后仍可快捷搜索)
- 2024-05-08 09:43 优化本地搜索文本内容展示,设置显示最大高度,隐藏滚动条
- 2024-04-29 21:23 [可配置] 集成并优化旧版本地搜索(页面检索)到当前版本
- 2024-04-28 16:08 导航页添加固定链接(Pin)区域,只需在导航链接前添加 '>' 即可生效
- 2024-04-23 19:07 [可配置] 导航页添加顶部搜索栏(原 Ship 页移植)
- 2024-04-22 10:52 除相关文章栏(左)、及目录栏(右),默认在新标签页中打开链接
- 2024-04-19 12:51 [可配置] 文章页新增相关(同标签)系列文章栏(页面左侧区域)
- 2024-03-20 11:38 修复旧完整版本搜索内容不完整的问题,并更新旧版本到分支 1.x
- 2023-09-27 15:12 [可配置] cool 模式下更灵活地配置背景壁纸和遮罩透明度
- 2023-09-21 17:04 [可配置] 恢复 dark 暗色模式(真的不常用),并调整部分图标
- 2023-09-07 16:24 调整 1920*1080 分辨率下样式,正确渲染不以 / 开头的图片
- 2023-08-15 12:21 合并、删除 ob 分支,为功能完整版打标签 v1.0.0
- 2023-08-14 15:46 [可配置] 新增 giscus 评论插件,并默认使用(代替 utterances)
- 2023-08-02 18:31 新增 ob 分支,精简功能,适配 Obsidian
- 2023-03-23 14:58 [可配置] 增加 utterances 评论插件
- 2023-03-22 16:08 更新主页快捷联系选项,增加知乎和简书
- 2023-03-21 17:58 更新导航页面文件结构 - `nav.md` 或 `nav/index.md`
- 2023-03-19 00:05 优化导航页面快速跳转

简介

一个简单纯净的主题,欢迎使用。🎉🎉🎉

版本 演示 配置 导航页 备注
旧完整版 https://loveminimal.github.io  config-old.toml   nav-old.md  分支:1.x
新精简版 https://aituyaa.com  config-new.toml  nav-new.md 分支:master

> 版本功能简介

旧完整版

![[assets/Pasted image 20230815105343.png]]

‘她’包含:

  • 两种模式:纯净、酷爽,
  • 内置但不限于精美的本地字体,
  • 高亮的层级目录,以及
  • 简单强大的本地文章实时搜索功能等。

新精简版

该版本为基于旧版本的精简版,包含但不限于以下更新:

  • 移除本地全局搜索功能(用的不多);
  • 页面归并改造
    • 移除独立的文章页、归档页入口
    • 归档页精简为只显示标签列表(Obsidian 只支持标签),置于首页
    • 更新导航页
  • 移除暗色模式(基本没用过)
  • 移除相邻文章切换功能(使用不多)
  • 精简了配置项
  • ……

![[assets/Snipaste_2024-02-26_16-36-42.png]]

快速开始

下载主题

首先,下载该主题。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 方案一
cd YOUR_SITE_DIR	# 本地站点目录
## === 默认拉取新精简版
git clone https://github.com/loveminimal/hugo-theme-virgo.git themes/virgo
## === 若要拉取旧完整版
## --- 鉴于有一些朋友喜欢旧的版本,为了修复问题方便,新开一个分支 1.x
## --- ✔️ 所以,你现在可以使用从该分支直接拉取旧版本的最新代码了
## --- <YOUR_LOCAL_BRANCH> 是你在本地仓库中所使用的分支名称
git checkout -b <YOUR_LOCAL_BRANCH> origin/1.x
## --- 关联本地分支到远程分支(可选)
git branch --set-upstream-to=origin/1.x <YOUR_LOCAL_BRANCH> 

## ❌ 不再推荐从标签拉取,那样你可能会错过一些功能性的修复
## git clone --branch v1.0.0 https://github.com/loveminimal/hugo-theme-virgo.git themes/virgo
## git switch -c master

# 方案二
cd YOUR_SITE_DIR
git submodule add https://github.com/loveminimal/hugo-theme-virgo.git themes/virgo

💡 使用哪种方式呢?如果你有这个疑问,那么就选择第一种方案。

然后,更新你站点的 config.toml 内容,如下(后续可按需修改):

现在,你就可以进入网站根目录,运行 hugo server -D 开始你的折腾之旅了。

旧完整版注意事项

如同下个小章节 [[#导航页]] 中要提到的,我们需要为几个定制页面建立对应的 *.md 文件,如下:

定制页 路由 对应的 md 文件
导航页 /nav content/nav.md
归档页 /archive content/archive.md
搜索页 /search content/search.md

其中,相应 *.md 文件中,其 front-mattar 中的 title: 是必需的。实际上,你可以通过以下命令来创建它们:

hugo new content/nav.md
hugo new content/archive.md
hugo new content/search.md
...

除了导航页,其他页面都是没有内容的,创建完成之后即可。关于导航页,为了获得更好的体验,和预览中的样式,请遵循相应的内容格式,详见 [[#导航页]] 中的具体描述。

导航页

旧完整版

对于功能完整版,如果,你想使用导航页并正确渲染,那么就应该严格按照这种格式搭建你的 nav.md 文件结构,详见 nav-old.md

为什么要做格式方面的限制呢?

众所周知,Markdown 对 Table 的支持很一般,鉴于导航页的内容主要是外链和书签,使用列表管理是最方便的。另外,我们会使用 JS 进行内容项的统计,所以就需要使用者遵守格式,不然可能页面显示可能会不正常。

新精简版

该版本对于 nav.md 的格式要求就比较宽松,详见 nav-new.md

导航页放在哪儿?

放在站点根目录中的 contents/nav.md 即可。

它本质上也是一个博客文件,只不过由于其与常规页面而言有一些定制化,我们在 Front Matter 中定义了 type: nav 来标识它。

对于导航页,我们还做了哪些事情? 接着往下看。

关于搜索

移植 Ship 站外搜索

我们把之前定制的搜索页移植到了导航页面,并添加了一些动态效果。loveminimal/ship: A simple search page. 是一个独立的项目,单独部署没有任何问题。之前一直做为子模块嵌在当前主题中,但其风格有时候跟当前主题有些割裂,尤其是当你激活 cool 模式的时候。另外,顶部的快捷导航图标也需要单独维护,尤其是做出更改的时候。

现在,我们直接把它移植过来,可以直接复用 _contact.html 模板页,并允许在 config.toml 配置它。

移植站内搜索

最初我们在新当前版本中是移除了本地搜索的,因为这个功能其实真的不怎么使用,现在加上它也只是因为无聊的很~

既然做了,我们就试图把这个功能做的更好些。我们把旧版本分离式的交互逻辑精简,直接集成在了当前版本的主题中,优化了一些比较耗费性能的触发事件。它不再是一个单独的页面,而是做为一个页面组件插入在导航页的顶部区域。

事实上,导航页是我最常用的页面。

其他

提取固定常用链接

我们在 [[导航]] 中使用表格来保存导航链接。尽管我们对其做了分类,但随着链接数量的增加,更快地找到常用链接仍然变成了一个问题,于是增加一个可以固定在顶部的常用导航区域。

为了方便地在导航页编辑和更换固定的链接项,我们在主题文件中 runMisc.js 中做了一些事情,只需要在导航链接的描述文本前加上 > 符号(见下图),该链接项就会自动固定在顶部区域。

> 固定链接的添加示例

![[assets/Pasted image 20240429151056.png]]

PS:我们还做了一些“无聊但有趣的事情” 😅,使用 MD5 对链接文本加密,并提取前 6 个字符拼成一个十六进制的颜色值,做为固定链接项的“颜色球”来标识它,所以你会发现不同的链接项,颜色球都是不一样的。

标记语法增强

> 使用 JS 对 markdown 做出的一些增强性修改

不止一次吐槽过 markdown 虽然是纯文本性质的,但是其某些标记语法真的是让人不敢恭维,直观性和表现力都是一般。不过,从另一个方面来说,本来就是轻量级的标记语言,不可能承载太多。

本来想直接修改 markdown 引擎来实现,研究了一下,还要颇费一番工夫。鉴于仅满足于个人使用,用一些曲线方式使用 js 来实现反而更加简单些。

此处就记录一下针对 hugo-theme-virgo 做的一些魔改。

行内格式

Markdown 中的行内格式有以下几种:

语法 效果 转译 html 标签
**加粗** 加粗 <strong>加粗</strong>
*斜体* 斜体 <em>斜体</em>
~~删除线~~ 删除线 <del>删除线</del>
` 行内代码` 行内代码 <code>行内代码</code>
下划线 <u>下划线</u>

是的,markdown 中没有下划线的标记语法。

本来想用行内代码的标记格式做魔改,鉴于博文中出现行内的代码的概率较高,遍历起来相对更耗性能(虽然并没有多少),故决定选择 *斜体* 语法标记,其使用频率不多,且其对应的 Org Mode 中可以直接显为粗体显示。

新增语法 效果
*_下划线* _下划线
*=高亮* =高亮

| *-高亮* | -高亮 |
| *=吐槽系* | =吐槽系 |

如此,我们便增加了 _下划线=高亮 两种语法标识了。另外,在文章中,尤其是一些摘录和转载的文章中,我们需要做一些随笔,之前我们是使用 <div class="oh-essay">...</div> 这种标签插入,如上表,我们也对其做了语法标识。

如上,所示,更改了一些语法标记,因为有的 Markdown 引擎中使用 ==高亮== 来高亮文本,我们这里就用 *=高亮* 来表示,以做到在观感上统一。

另外,我们不再使用 *=吐槽系* 来表示个人在摘录或编辑中的个人想法展示,主要是由于在不支持当前语法标记的主题中,它只能以斜体展示,不容易和正文内容作区分。我们使用 >:: 吐槽系> :: 吐槽系 来表示,如此在不支持的情况下,可以解析为引用样式,便于区分。

之前我们做了一些 snippet 进行 html 标签的插入,以实现以上效果,但是这就限定在了某些编辑器中,些许背离了纯文本输入的理念,以上小小的增强,使得我们可以任何文本编辑器中进行方便的文本输入。

>:: 好吧,尽管它们只能在 `hugo-theme-virgo` 中才有效果 😅
> ::好吧,尽管它们只能在 `hugo-theme-virgo` 中才有效果 😅
> :: 好吧,尽管它们只能在 `hugo-theme-virgo` 中才有效果 😅

上述语法标记是等价的,会被解析为如下样式:

:: 好吧,尽管它们只能在 hugo-theme-virgo 中才有效果 😅

代码块折叠

在 Markdown 中,包裹代码块很方便。但有时候在博文中,我们可能引入较多的代码片段,这会导致正文内容的间断,所以,允许其进行折叠,可以在 config.toml 中,使用 hasFoldAllCodeBlocks: true 进行初始化。

既然已经可以折叠了,这里我们不妨用它再做一个更通用的折叠板(默认折叠),原理也很简单,利用 lang 判别。

如果其为 _lang 这种格式,则表示轻量级代码折叠 - 不换行;如果使用 __lang 则折叠板中内容会自动换行。

💡 在新精简版中,我们 不再支持 代码块折叠及折叠板功能。

Wiki 链接及图片语法渲染

最近使用 Obsidian ,其使用的链接及图片格式为 Wiki 语法,如下:

名称 描述
链接 ![[assets/Pasted image 20231005135434.png|60]]
链接(带描述) ![[assets/Pasted image 20231005135451.png|116]]
图片 ![[assets/Pasted image 20231005135507.png|120]]
图片(带尺寸) ![[assets/Pasted image 20231005135528.png|166]]

Hugo 默认的 Markdown 引擎是不支持渲染这种语法的,我们这里做了一下增强,现在你可以畅快地使用 Obsidian 来编辑你的博客了。

:: 图片和链接,好像 Wiki 的这种语法写起来更加简洁。其实,还是使用 <img> 标签的通用性更好些,不过许多软件的即时渲染又不支持,就很伤。

图片渲染相关

在使用 Obsidian 或 Typora 自动插入图片时,自动插入的图片路径形式为 assets/xxx.jpg 等(无法通过设置使其插入路径为 /assets/xxx.jpg 的形式),Hugo 无法正确渲染访问路径,它在解析的时候,会生成有类似如下路径: http://localhost:1313/temp-%E8%B0%83%E8%AF%95%E6%96%87%E4%BB%B6/assets/baby.png ,所以,我们对其遍历,为不以 / 开头的路径,添加 / ,以使其正确渲染。

我的怎么写博客的

在《[[一场疲惫的主题制作之旅]]》中,已经有了不少博客相关的碎碎念。这里,主要用来浅谈一下当前站点博客系统的搭建、编辑及部署相关的系列流程。

当前站点,使用 Hugo 静态博客生成系统 驱动,部署在个人服务器上。事实上,你可以把生成的站点项目部署在任何可以被访问的地方(比如 Github Page),它本质上是一个包含了若干 .html 文件及相关静态资源的文件夹。

准备篇

……

搭建篇

……

编辑篇

这里,我们以当前文章的创建及编辑过程为例。其中:

  • ✔️ 正在使用
  • ❌ 已不使用

:: 怎么说呢?这个章节写的过于太细节了……好像…… 😅

❌ 使用 VSCode 编辑

创建文章

我们可以使用以下命令来创建文章:

1
2
3
hugo new posts/how-do-i-blog/index.md	# 推荐
# 或
hugo new posts/how-do-i-blog.md			# 不推荐

这里我们使用第一条命令,该命令会自动生成如下目录层级下 .md 文件。

content
├── posts
│   ├── how-do-i-blog
│   │   ├── imgs
│   │   │   └── 1aa09c580e674b09e82c722a3689d280012f2ae6e1700e924deeef558347d91a.png
│   │   └── index.md

为什么不直接使用 how-do-i-blog.md ,而使用 how-do-i-blog/index.md ?

正如上述目录层级中所反映的,如此方便我们把当前文件所需要的资源(如图片 imgs )都放在当前文章的层级下,方便管理。

这样做还有额外的好处,我们将在后面 [[#插入图片]] 的部分进一步说明。

插入图片

在文章中插入图片是一个相对高频的操作。在第三方的博客平台中,一般来说直接复制图片并粘贴到要插入的位置就可以了,很方便。而编辑 .md 文件,插入图片就稍微麻烦一些。

我们通过 ![图片名称](地址链接) 在文章中插入图片,默认情况下,你需要经过:

1. 搜索图片
2. 另存图片到本地
3. 编辑 `![图片名称](地址链接)` 引用
……

很繁琐!

而且还不能控制图片的‘显示’尺寸,需要插入图片数量过多的时候,简直就是一种折磨了。

有没有一种更好的方式来插入图片呢?

很幸运,有!

我平时是使用 VSCode 来管理站点内容和编辑 .md 文件的,其中有一款插件很好地解决了这个问题。

![[assets/Pasted image 20230526102347.png]]

它提供了丰富的自定义设置选项,这里主要用到以下几种:

  • Markdown-image › Base: File Name Format ,设置为 ${hash} ,当然有其它各种格式可选组合;
  • Markdown-image › Base: Image Width ,设置为 400 ,默认宽度设为 400px ;
  • Markdown-image › Local: Path ,设置为 ./imgs ,生成的图片放在当前文章同级目录下的 imgs 文件夹中。

这也是上文中我们推荐使用 hugo new posts/how-do-i-blog/index.md 命令来生成文章的原因之一。

使用该插件,你只需要复制所需要图片(本地或网络图片),并通过其提供的粘贴方式(右键选择)插入到位置即可。如此,你的 .md 文件中,就会插如下内容:

<img alt="picture 3" src="imgs/30737f6467ed6269eed8911b8a915f47b9fed706b8f892efd3271d9b6a76181c.png" width="400" />  

它会被渲染成下面这张图片,是不是很方便!

![[assets/Pasted image 20230526102356.png]]

它的原理是什么?

它会读取你剪切板中刚刚复制的图片数据,在你粘贴的时候,重新生成一份拷贝,并在 .md 文件中,插入对应的图片格式,并引用。真的很方便!🎉

其他插件

cyberbiont/vscode-open-in-typora: open Markdown files from VSCode in Typora

![[assets/Pasted image 20230815170141.png]]

在 VSCode 中使用 Typora 打开当前 Markdown 文件。

❌ 使用 Typora 编辑

创建文章不是 Typora 的强项,光是手写 Front Matter 都让人受不了,就老老实实地用 [[#创建文章]] 章节中的命令创建好文章,再用 Typora 编辑就好。(这也是不支持第三方插件的坏处了,什么问题你只能等着作者去解决。相对来说,Obsidian 就不存在这个问题,它支持类似于 Snippet 的插件扩展。)

:: 现在的编辑操作就是使用 Typora 完成的。 😄

之前的 VSCode 使用的不是很爽吗?为什么切换为 Typora 了呢?

VSCode 确实很爽,到目前为止,我也经常使用它。切换到 Typora 的原因也很简单,家里的电脑性能不行,新的主机配置还在纠结中……

更多原因可以查看 [[一款 Typora 主题]] 中的描述。

PS: VSCode 真的是一款非常优秀的编辑器,插件丰富且优质,可扩展性强,可轻可重。

使用 Typora 的感觉怎么样?

很好!如 [[一款 Typora 主题]] 中所描述的那样,配合自己制作的主题(由站点样式适配),基本上实现了所见即所得的编辑。另外,Typora 本身集成了许多 Markdown 相关的快捷键,很直观也很好用,尤其是当你专注于编写内容的时候。

它还有‘专注模式’和‘打字机模式’,很舒心。

其内置的图片插入功能也不错,基本上和 [[#插入图片]] 章节中的实现是相同的,原理没有探究。怎么说呢,Typora 上的相对来说,更加符合日常的编辑逻辑,还贴心地增加了可以缩放图片的选项,最最重要的还是‘所见即所得’,你可以实时看到你的图片。

✔️ 使用 Obsidian 编辑

支持扩展的编辑器是可以不断进化的,比如 Emacs、Vi/Vim 等。

上面说了,Typora 是不容易扩展的(不支持),这就限制了使用,要么牵就,要么离开…… 尝试了几个软件之后,Obsidian 可以说是相当不错的管理软件了,稍微‘调教’之后,就相当顺手了。

Obsidian 也是所见即所得的编辑模式,有非常丰富的三方插件,如键位映射、图片缩放/清理、表格插入/编辑等功能都可以很方便的得到实现。

……

为了更方便地显示图片及适应 [[如何使用 hugo-theme-virgo 主题]] 中关于 [[#Wiki 链接及图片语法渲染]] 的兼容,重新组织了博客层级,如下:

C:\USERS\JACK\APPDATA\ROAMING\SITE\CONTENT
│  A Simple Bookmark Copying.md
│  Ajax.md
│  C.md
│  Canvas.md
│  CPU 是如何制造出来的.md
│  CPU 缓存是什么.md
│  CSS 中的动效.md
│  Emacs Lisp.md
│  Emojings.md
│  Git.md
│  GTD 管理系统.md
│  Java 那些事儿.md
│
├─assets
│      3b5d12f26d9d00dc2b021d097ff8c34.jpg
│      4.gif
│      Pasted image 20230525155800.png
│      Pasted image 20230817094853.png
│      vim.gif
│
└─snippets
        frontmatter.md
        longitudinal.md
        more.md
        timestamp.md

并且,使用 tags 标签来分类博文,而不是之前的 categories 分类。

创建文章

如上面的博客层级所示,我用 content 目录作为 Obsidian 的根目录,如此,Obsidian 相关的所有配置(如插件、主题、设置等) .obsidian 文件夹都使用 Git 统一管理。

💡 .obsidian 默认位于 Obsidian 仓库的根目录。

创建文章很简单,直接使用 Obsidian 提供的相关创建逻辑就行了。需要注意的是,如果你的博文也想用 Hugo 进行管理的话,就需要在博文头部添加相应的信息。如:

---
title: 我是怎么写博客的
aliases: []
tags:
  - Hugo
date: 2023-05-26 
time: 10:21
---

其中, titledate 是必须的,Hugo 需要使用其提供的信息进行渲染。

如果你使用 hugo new 命令去生成 .md 文件的话,那么你只需要设置 Hugo 相关的 archetypes/default.md ,如:

---
title: "{{ replace .Name "-" " " | title }}"
aliases: 
tags: [_Misc]
date: {{ .Date | time.Format "2006-01-02" }}
time: {{ .Date | time.Format "15:04" }}
---

然后,运行如 hugo new my-post-name.md 之类的命令就可以了。

当然,Obsidan 本身也是支持插入模板的,如 Templater 模板插件,你写好模板,放在相应文件夹下(如 snippets/frontmatter) ,运行插入命令即可,如:

---
title:  <% tp.file.title %>
aliases: 
tags:
  - _Misc
date:  <% tp.date.now() %>
time:  <% tp.date.now("HH:mm") %>
---
插入图片

Obsidian 的插入图片很方便,你只需要像文本一样粘贴进来就好了。图片会自动上传到设置好的目录,可以是相对于当前文件的相对位置,也可以相对于仓库根目录的绝对位置。

图片插入后,默认是 WIKI 语法的,如 ![[path/to/img]] ,可以在设置中修改为常用 Markdown 语法的。当然,如果你使用  hugo-theme-virgo 主题的话,就不用担心,它支持 WIKI 语法的图片和链接的渲染。

![[assets/Pasted image 20231026173226.png]]

这个插件,可以让你方便的调整图片尺寸,如按着 ALT 键滚动缩放。

插入表格

:: 目前新版本的 Obsidian 已经完美支持表格操作,便捷好用,终于可以完全抛弃 Typora 了!

这方面,目前没有遇到比 Typora 做的更好的了。 当然,借助下面这个插件,可以实现类似 Typora 表格插入和编辑的体验:

![[assets/Pasted image 20231026173536.png]]

另外,这个插件是没有上传到官方插件仓库的,但可以借助 Obsidian42-Bart 这个插件去引入,也很方便。

![[assets/Pasted image 20231026173648.png]]

不得不说,支持第三方扩展的软件,才会更有生命力!

渲染篇

详见 [[#标记语法增强]] 章节。

部署篇

当你想部署你的站点内容到托管平台时,你可能会经过以下步骤:

1. 执行 `hugo` 命令,生成站点内容,默认放在站点根目录的 `public` 文件夹中;
2. 复制内容包,上传到托管平台;
……

如果,只操作一次的话,不是很复杂,但如果,你的内容更新比较频繁,那就有些烦扰了。内容包的部署方式有很多,各有优缺。

脚本部署

我们这里,使用脚本部署,一次性配置之后,每次部署只需要执行一条简单的命令即可。分享出来,供大家参考使用。

我们的站点目录如下所示:

.
├── config.toml
├── content
│   ├── about
│   ├── archive.md
│   ├── _index.md
│   ├── nav
│   ├── posts
│   └── search.md
├── package.json
├── README.md
├── resources
│   └── _gen
├── scripts
│   ├── deploy.sh
│   └── update.sh

> 2023-09-05 22:41 最新 - 完全可以做为唯一的部署脚本 !它对站点内容的跟踪是完备的,当前环境下,只会在首次部署的时候进行全量更新,后续会自动基于 Git 的更新记录进行增量式更新,体验相当不错。

其中, scripts/deploy.sh 便是我们定义的部署脚本,其内容如下:

 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
#!/bin/sh
# -------------------
# 部署博客到指定的仓库
# Deploy posts to special repo.
#
# 配置 Configurations
# -------------------

# 自定义 `REPO_DEPLOYED` 为所要部署仓库
REPO_DEPLOYED="jack@aituyaa.com:/home/jack/.repo/site.git" 

# rm -rf "public/CNAME" && cp -r "CNAME" "public/" # Fix potential error - Recovery `CNAME` before deploy.

# 判断是否存在 public
if [ -d "public" ]
then
    # 判断是否已经存在与 site 同级的 .temp 文件夹
    if [ ! -d "../.temp" ]
    then
        # ^ 若不存在,直接复制 public 为 ../.temp ,进入该目录,初始化,强制推送至指定的远程仓库
        echo -e "\e[32m >>> .temp not exited. \e[0m"
        cp -r "public" "../.temp"
        echo -e "\e[32m >>>[DONE] copy public to .temp. \e[0m"

        cd "../.temp"

        git init
        git add .
        git commit -m "Posts update."
        git remote add origin $REPO_DEPLOYED
        # git remote add origin https://github.com/loveminimal/loveminimal.github.io.git
        # git push -f origin master:main
        git push -f origin master

    else 
        # ^ 若存在,则进入 ../.temp 目录,判断该仓库是否已初始化(包含 .git )
        echo -e "\e[32m >>> .temp exited. \e[0m"
        cd "../.temp"
        if [ -d ".git" ]
        then
            # ^^ 若存在 .git ,则备份 .git ,并在处理 .temp 后,恢复它
            echo -e "\e[42m >>> copying.... \e[0m"
            
            mv ".git" "../.git.bak"
            # 此处,对于 .temp 处理的目的是为了绝对保持其与 site/public 文件的一致性(无论增删)
            cd ..
            rm -rf .temp
            cp -r "site/public" ".temp"
            mv ".git.bak" ".temp/.git"
            
            cd .temp
            git add .
            git commit -m "Posts update."
            git push -f origin master
        else
            # ^^ 若不存在 .git ,初始化,强制推送至指定的远程仓库
            git init
            git add .
            git commit -m "Posts update."
            git remote add origin $REPO_DEPLOYED
            # git remote add origin https://github.com/loveminimal/loveminimal.github.io.git
            # git push -f origin master:main
            git push -f origin master
        fi

    fi
    echo -e "\e[42m >>>[DONE] Update. \e[0m"
    cd "../site"
fi

在站点根目录下,运行 source scripts/deploy.sh 就可以静待站点部署完成了。

💡 注意修改 REPO_DEPLOYED 为你自己的部署仓库!

命令简化

使用 source scripts/deploy.sh 还是有点太复杂了?有如下限制:

  • 需要进行到站点根目录才可以运行它;
  • 部署后,站点内的内容包并没得到清理。

哈,你只需要多加几条命令即可,如下:

cd ~/AppData/Roaming/site && rm -rf public && hugo && source scripts/deploy.sh && rm -rf public

如此,无论当前你在那一种路径,都会:

  1. 自动进入站点根目录(此处是 site);
  2. 删除站点下旧的 public (如果有的话);
  3. 根据当前内容生成新的 public 内容包;
  4. 执行部署脚本,发布到对应托管平台;
  5. 清理掉生成的 public 内容包。

Emm… 还是长啊,每次都要键入这么长,太麻烦了,怎么办?

那么你就需要了解一些关于 bash alias 方面的知识了,如下所示,在当前用户家目录下,创建 .bash_aliases 文件(若无),并添加如下内容:

alias ssd="cd ~/AppData/Roaming/site && rm -rf public && hugo && source scripts/deploy.sh && rm -rf public"

保存后,在用户家目录下,运行 source .bashrc 命令使 .bash_aliases 中的别名生效。

OK,现在,当你想部署站点的时候,你只需要运行键入 ssd ,回车即可完成部署。

‘用户家目录’是什么?

在 Windows 下,有两个家目录:

  • 用户家目录,如 C:\Users\jack ,一些软件的默认配置会放在该目录下;
  • 用户漫游家目录,如 C:\Users\jack\AppData\Roaming ,另一些软件的配置又会放在这个目录下。

😅 微软的东西真的有点混乱哈。

如果,你使用的是 GNU/Linux 系统,那么家目录就只有一个喽,如 /home/jack 。

❗❗❗😅 记一次踩坑……

原来的域名 walkssi.com 废弃了,启用了新的域名 aituyaa.com 。不久前老域名到期之后,腾讯云那边的 DNS 解析服务就停止了,但是公司主机上的 .temp 文件夹(上方部署脚本中生成的)已经存在,这导致一键部署的时候总是提示 ssh: connect to host walkssi.com port 22: Connection timed out …… 搞的自己在腾讯云域名解析那里弄了好久,再跑到服务器上检查 Nginx 设置…… blablabla……

答案是:更换了域名之后,如果 .temp 文件夹存在,就要先删除它,因为它是一个包含 .git 的完备追踪文件夹,其会延用旧有的域名信息。

附录

❌ 废弃的部署脚本

最初版本的 scripts/deploy.sh 脚本,其内容如下:

 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
#!/bin/sh
# -------------------
# deploy.sh
# Deploy posts to `loveminimal.github.io`
# -------------------

# 检测是否存在 .temp 文件夹,若存在,先移除 
if [ -d "../.temp" ]
then
    echo -e "\e[31m >>> .temp exited. \e[0m"
    rm -rf "../.temp"
    echo -e "\e[32m >>> ... \e[0m"
    echo -e "\e[32m >>> .temp has been removed. \e[0m"
else
    echo -e "\e[32m >>> .temp not exited. \e[0m"
fi

if [ -d "public" ]
then
	# 如果你是部署到 GitHub ,并绑定了域名,那你可能需要启用该行,以
	# 保证其正确的指向
    # rm -rf "public/CNAME" && cp -r "CNAME" "public/"

	# 拷贝内容包 public 到一个临时文件夹 .temp ,并
	# 用 git 初始化管理该它
    cp -r "public" "../.temp"
    cd "../.temp"
    pwd
    git init
    git add .
    git commit -m "Posts update."

	# 添加远程库,引得我们使用的是个人服务器的仓库地址,如果
	# 你是托管在 GitHub 上,那么连接的对应的远程库即可 - <YOUR_USERNAME>.github.io
	# 如果你是在 GitHub ‘政治正确’后创建的库,其默认分支为 main, 那你
	# 需要 master:main 而不是 master
    git remote add origin jack@ovirgo.com:/home/jack/.repo/site.git
    git push -f origin master
    # git remote add origin https://github.com/loveminimal/loveminimal.github.io.git
    # git push -f origin master:main

	# 清除临时文件夹
    cd ..
    rm -rf ".temp"

	# 返回站点目录
    cd "site"
fi

初看,上述脚本初看可能有些混乱,但其实,理论上你只需要:

  • 更改远程仓库地址;
  • 更改站点目录,即可。

> 2023-09-05 11:53 更新 - 添加增量更新脚本

随着博文数量的增加,我们使用 deploy.sh 全量更新的话,时间也会随之变长。单纯的文字还好,但站点难免会引入外部的静态资源(图片、音频等),如此‘等待’就成了一个问题。所以,就有了 update.sh ,如下:

 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
#!/bin/sh
# -------------------
# update.sh
# Deploy posts to `loveminimal.github.io`
# -------------------
if [ ! -d "../.temp" ]
then
    echo -e "\e[32m >>> .temp not exited. \e[0m"
    mkdir "../.temp"
    echo -e "\e[32m >>> ... \e[0m"
    echo -e "\e[32m >>> .temp has been created. \e[0m"
else 
    echo -e "\e[32m >>> .temp exited. \e[0m"
fi

if [ -d "public" ]
then
    # rm -rf "public/CNAME" && cp -r "CNAME" "public/" # Fix potential error - Recovery `CNAME` before deploy.

    cp -r "public/." "../.temp"
    cd "../.temp"
    pwd
    # 该仓库没有初始化,初始化该仓库,并推送
    # 仓库已初始化,仅推送增量更新
    if [ -d ".git" ]
    then
        git add .
        git commit -m "Posts update."
        git push -f origin master
    else
        git init
        git add .
        git commit -m "Posts update."
        git remote add origin jack@walkssi.com:/home/jack/.repo/site.git
        # git remote add origin https://github.com/loveminimal/loveminimal.github.io.git
        # git push -f origin master:main
        git push -f origin master
    fi
    cd ..
    # rm -rf ".temp"
    cd "site"
fi

它保留了临时文件夹的仓库跟踪,使得我们只需要提交增量更新即可,极大的缩小了仓库更新的时间。

当然,这样也会存在一个问题,就是当你删除了某些静态文件,如图片等,仓库是无法追踪到的,它只能知道你增加了什么。幸运的是,这个场景本身很少出现,你并需要关注它。当然,如果你实在介意,你可以执行以下操作中的一个就可以实现全量更新了:

  • 手动删除 .temp 文件夹;
  • 或者,你可以直接执行前面的 deploy.sh 脚本;
  • 或者,你可以使用下面这个最新的 update.sh 脚本,它会严格保持修改前后文件的一致性,性能介于 deploy.sh 和旧的 update.sh 之间,比后者稍慢一点点(配置中等主机下几乎相同),但比前者快出非常非常多。

💡 事实上,你完全可以用下面这个最新(2023-09-05 22:41)的 deploy.sh 做为唯一的部署脚本(推荐)!

结语

制作主题,对‘强迫症’来说,真的是一件挺‘辛苦’的事情,或者说是‘痛并快乐着’ ?!