既然是写博客, 那我自然从写博客的工具, Jekyll, 开始. 我会选择 Jekyll 主要是受到 GitHub 影响. GitHub Pages 对 Jekyll 的支持使得 Jekyll 在同类中相对更容易上手.
Jekyll 总览
如果不考虑 WordPress 这种由商业公司支撑的大型架构, 常见的开源博客生成器主要是
- 基于 Node.js 的 Hexo;
- 基于 Ruby 的 Jekyll;
- 基于 Go 的 Hugo;
- 基于 React 的 Gastby;
其中后两种是基于新兴语言的新兴平台. 对于不以前端为工作的人而言, 其实哪一种平台都差不多. 这 4 种语言本来也不是在生活中会接触到的东西. 由于我一直在使用 Jekyll, 这里就只介绍 Jekyll 的使用.
本质上来讲, 选择这类工具写博客本身就是一种折腾的心理.
对我而言, 这个过程中更重要的一点是去理解网站到底是如何工作的.
观察 html, css 以及 javascript 对网页显示效果的影响比写作本身更有意思.
在 Kramdown 的加持下, Jekyll 可以很方便的进行 markdown 与 html 混排.
这让网站的制作过程在拥有直接编辑 html 的自由度的同时可以利用 markdown 的简单语法.
Jekyll 让我很喜欢的一点就是它对 Liquid 的支持.
在 Liquid 的辅助下, Jekyll 的 Layout 结构可以很方便的做代码复用.
而 Kramdown 的 arttribute
功能可以在 markdown 的语法中直接修改 html 的属性.
这让我可以很容易的 hack 进 markdown 语法, 实现这个警示牌 (admonition) 功能.
标题
这个功能的实现还是比较复杂的. 我一开始是仿制了一个 Liquid 写的语法分析器, 利用代码块自定义语言的功能过滤关键词, 然后替换代码块的容器.
Lemma
直到后来我发现了 Kramdonw 支持 dl
, dt
, dd
等描述列表元素的语法.
现在这个框写起来就更简单了, 而且去掉了语法分析器后 html 和 css 就解耦合了.
我之后想添加其他的警示框就只需要在 css 中添加了.
比如这个引理框.
不同于常见的 JSON 文件, Jekyll 使用的数据格式为 YAML.
# Example
lang_name: "ZH-CN"
title: "Q-Canon"
date_format: "%F"
list:
- a
- b
dict:
name: 'Alice'
number: 12577
YAML 在使用缩进的同时支持与 JSON 文件混排. 在因为格式混乱而不适合大型项目的同时, 它在小项目中却非常的方便.
Jekyll 的使用
Jekyll 的安装
Jekyll 最简单的使用方式就是 GitHub Pages. 直接在 GitHub 建一个公开的仓库, 然后去仓库的设置里找到 Pages. 选择一个分支和想要的主题就可以了.
只要在仓库中添加一个 index.md
文件, 随便写点什么, 这个就是你的主页.
其他的文件只要建立一个 _post
文件夹, 然后给每一条博文新建一个 日期-名字.md
文件, 比如 2022-06-18-hello-world.md
, 它就会自动被加入到博客中.
唯一需要的前置知识就是 markdown 的语法了.
每次向仓库 push
新的 commit
的时候 GitHub 会自动帮你编译, 然后部署到 https://账号名.github.io/仓库名/
上.
当然, 这样部署的网页更新起来不是很方便, 没有办法在本地编辑的时候实时的看到效果.
想要有更好的体验最好是在本地安装 Jekyll, 等一篇博文写完了再 push
到 GitHub 上.
但对很多 Windows 用户而言, 这是一股很大的劝退力量.
Ruby 对 windows 的支持并不好, 因此 Jekyll 在 Windows 上的安装与配置会非常麻烦.
我们这里以 Ubuntu 为例.
安装 Jekyll 的第一步是安装 Ruby: 用系统包管理器, 比如 apt
安装 ruby
sudo apt-get install ruby-full build-essential zlib1g-dev
这段命令是 Jekyll 官方设定的, 后两个 build-essential
和 zlib1g-dev
一般 Linux 都会自带, 但是使用这个命令可以保证安装不会出问题.
安装 ruby 的同时会安装它的包管理器 gem
.
这就像 python 与 pip
的关系.
按照官方推荐, 我们需要手动设置一下 gem
的环境变量.
否则的话所有 gems 会被安装到 root
用户下.
echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc
echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
最后用 gem
安装 Jekyll 就可以了
gem install jekyll bundler
其中 bundler
是一个 gem
的依赖管理包.
bundler
会用工作文件夹下的 Gemfile
文件确定需要哪些 gems.
文件夹结构
Jekyll 默认的文件夹结构如下:
├── _config.yml
├── _data/
├── _drafts/
│ ├── begin-with-the-crazy-ideas.md
│ └── on-simplicity-in-technology.md
├── _includes/
│ ├── footer.html
│ └── header.html
├── _layouts/
│ ├── default.html
│ └── post.html
├── _posts/
│ └── 2009-04-26-barcamp.md
├── _sass/
├── _site/
├── .jekyll-cache/
└── index.html
Jekyll 中所有带下划线 _
的文件夹或者文件都是功能性的.
在编译的时候, 这些特殊的文件以及根目录下的文件会被用于 Jekyll 编译.
其他所有文件, 如果是 html 或者 markdown 则会被当作一个页面处理, 其他文件会被原封不动的复制到 _site
内.
一个好习惯是保留一个不含 html 和 markdown 的文件夹, 一般命名为 assets
.
这个文件夹里面储存了所有网站需要的 css, js 文件, 图片, 字体, logo 等内容.
这样可以清晰的让自己知道哪些文件在编译过程中是不会变的, 哪些文件有可能被修改转移位置.
我从上到下介绍一下这些文件夹分别是什么:
_config.yml
_config.yml
也可以被命名为 _config.yaml
.
这是 Jekyll 的配置文件.
但其实这个文件里面可以什么都不写.
默认配置已经完全够用.
实际上这个文件里面写的大部分内容都是为 Liquid 服务的.
具体需要定义些什么是由模板决定的, 它实际上只是在编译中定义了一些常数.
_data/
_data/
文件夹其实是 _config.yml
文件的延申.
我们可以在这个文件夹里面储存 .yml
, .yaml
, .json
, .tsv
, .csv
等数据文件.
它里面的文件同样是不会被复制进网站的, 它同样是为 Liquid 服务的.
对于基础的博客这个文件夹并不重要.
_drafts/ 与 _posts/
_drafts/
与 _posts/
就是 Jekyll 最重要的文件了.
这两个文件夹里面就储存了所有的博文.
所有存在这两个文件夹中的 markdown 与 html 文件都会被当成博文.
但是注意, _posts/
中的文件名必须包含日期, 比如 2022-06-18-demo.md
并且包含 front-matter 才能被编译.
front-matter 是在文件头标注的的一些信息, 用 3 条横线隔开.
在 front-matter 中其实可以什么都不写, 但是它可以定义一些局域变量.
比如下面的就是我这篇博文的 front-matter.
---
title: Jekylltag: 服务器
---
_drafts/
, 即草稿文件夹里面的是正在写的博文, 一般不会被编译.
但是在编译的时候使用 jeykll build --drafts
会编译所有的草稿, 并且根据它们最后修改时间赋予时间属性.
所有的博文都会被加入到 posts
集合中, 在 Liquid 中可以被调用生成时间线等页面.
它们默认按日期从近到远排序.
_includes/
_includes/
文件夹里面包含了用于 Liquid 的 html 文件.
这个文件夹主要是用来做代码复用.
它包含的是一些代码碎片.
我们可以在任何页面的任何位置插入一个 _includes/
中的代码碎片.
甚至因为 Liquid 的强大功能我们甚至能用 Liquid 写一些简单的语法分析器, 做一些后处理工作.
_layouts/
_layouts/
文件夹的作用与 _includes/
相反.
_layouts/
文件夹里的文件可以把其他的页面包裹起来.
这主要被用来定义所有网页共用的一些 html 元素, 比如头部, 注脚, 分栏之类的元素.
_sass/
_sass/
文件夹其实并不是 Jekyll 本体的一部分.
_sass/
里面存放的是一些 scss 和 sass 文件.
这说起来就很复杂了.
它们是 css 文件的母文件.
可以用 Jekyll 自带的 sass 插件把它们编译成 css 文件.
而 css 文件定义了网页中每一个元素的大小, 颜色, 位置等所有的视觉效果, 动画效果等.
index.html
最后的 index.html
就是网站的主页了.
在网站中, index.html
代表的是当前文件夹本身对应的页面.
比如说我们有一个 foo/
文件夹, 里面又有一个 foo/bar.html
文件.
这个网页 foo/bar.html
的 url 就是 https://域名/foo/bar
.
但是我们在日常访问网页的时候我们同样可以访问 https://域名/foo/
.
这实际上访问的就是 foo/index.html
文件.
所以我们文件夹根目录下的 index.html
文件就是访问 https://域名/
时会看到的网页.
建站
虽然我上面介绍了这么多结构, 但其实自己想建站的话并不需要一上来就理解所有这些概念.
最简单的办法其实就是在网上找一个模板, 直接套用就好.
Jekyll 的官网给出了很多模板站: https://jekyllrb.com/docs/themes/.
但是我还是比较推荐 minima 主题.
因为 minima 是最简洁的模板, 很容易在上面个人定制自己想要的内容.
但是如果是不想自己写模板的话, 推荐使用 GitHub Pages 自带的主题.
它们可以直接在 GitHub Pages 上找到: https://pages.github.com/themes/.
直接点链接, 然后在 Git 仓库的右边找到最新的包下载即可.
解压后在根目录就可以使用 bundle exec jekyll serve
看到编译的效果了.
Jekyll 的 serve
功能默认会在 http://localhost:4000
host 网站, 在浏览器中输入就可以访问.
如果是把网站部署到 GitHub Pages, 那么直接把文件夹 push 到仓库即可.
如果想把这个网站部署到自己的服务器, 那么需要先 bundle exec jekyll build
.
这会把网站编译到 _site/
文件夹内.
此时只要把整个 _site/
文件夹复制到服务器上, 然后使用 Nginx 之类的网页服务器把 _site/
作为根目录发布出来就可以了.