(本文在移动设备上显示效果可能不佳)
啰嗦一会
微博微信等软件用久了,对碎片化资讯便开始厌烦,仍想回到节奏稍慢的时代。
一直以来想自己动手搭博客写点东西。但由于各种事(jie)情(kou),一直没有搭好。万事开头难, 尝试过不少姿势搭建博客,好用的确实有很多,但顺心的直到最近才找到。
在一切都是刚刚开始之前,我对博客平台有下面一些期望:
- 美观;
- 轻量,快速,简单;
- 不需要租 VPS,免去配置和维护(其实是寒碜);
- 能将内容和配置存储,换一个地儿后能快速还原;
- 容易 DIY 和 Hacking;
- 支持 Markdown(格式易于控制和统一,显示代码也好看);
- 用 GitHub 托管和版本控制;
- 能支持评论和分享就更好了。
到这里就想到了 GitHub Pages,但 GitHub 官方主推 Jekyll。照着教程,在自己 机器上试了试,安装过程就很蓝瘦。终于装好后,生成网站时又出现了问题。Google 扒了好一阵, 在 Jekyll GitHub Issue 中遇到了同样的问题,但按照上面给的方案,并没有解决我的问题。 罢了,折腾之心已死,消停了几个月。
开发时,用 Golang 比较多,也知道 Hugo 的存在,但当时并不知道 Hugo 能够无缝支持 GitHub Pages。直到有一天还是发现了,惊喜,立刻安装试用起来。经过一 段时间摸索,一个能看的博客出锅了,就是你现在看到的样子。
如果你像我一样,也想按着这样的方式写博文:
- 用简单的文本编辑器(如 Vim、Atom)编写 Markdown 格式的文章;
- 用 Hugo 快速生成静态内容,打开 Chrome 实时预览改动;
- 用 Git 进行版本控制,并将博客配置、文章、主题、图片等文件提交到 GitHub;
- 在 push 到 GitHub 后,Travis CI 默默生成网站,并发布到 GitHub Pages。
那么,继续阅读,这篇教程正适合你。
熟悉 Hugo 与 GitHub Pages 的读者,可直接访问 本博客源文件 查看配置、主题吧。
需要哪些东西?
那么先列一下炖这锅博客需要的原材料和烹饪技术:
- GitHub 帐号 × 1;
- Travis CI 帐号 × 1;
- 计算机(Linux、MacOS 或 Windows) × 1;
- 熟悉 Markdown 语法;
- 熟悉控制台的使用;
- 有一定前端基础(HTML / CSS )就完美了。
开始
笔者在一台 CentOS 7 x64 的机器上写博文。因此这里只说 Linux 环境下的步骤,Windows 与 MacOS 用户可类推过程。
下载 Hugo
从 Hugo 官网 或 GitHub Release 页面 获取 Hugo。
Linux 用户打开控制台,直接执行:
# 将 0.21 替换为目标版本
$ curl -sSL -o ./hugo.tar.gz \
https://github.com/spf13/hugo/releases/download/v0.21/hugo_0.21_Linux-64bit.tar.gz
$ sudo tar -xzf ./hugo.tar.gz -C /usr/local/bin/
$ rm ./hugo.tar.gz
确保 Hugo 已正确安装。
$ hugo version
Hugo Static Site Generator v0.21 linux/amd64 BuildDate: 2017-05-22T21:12:19+08:00
生成一个样例站点
创建一个目录
用于存放博客配置、文章、主题、图片等。
$ mkdir blog
$ cd blog
后面未经特别说明,执行路径均为 blog 下。
生成模板
$ hugo new site .
Congratulations! Your new Hugo site is created in /tmp/blog.
...
将会生成下面文件和目录
$ tree
.
├── archetypes
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes
6 directories, 1 file
其中,config.toml
为配置文件,在里面可以定义博客网站地址、构建配置、标题、导航栏
等等,后面都会提到。
除了
toml
语法,还支持yaml
和json
格式配置。如果想现在了解配置文件的使用, 见 Configuring Hugo。
选择一个主题
访问 Hugo Themes 查找你喜欢的主题,并下载到 themes
目录下。
比如想使用 Lithium 主题,则按照安装说明,clone 下来。
$ git clone https://github.com/jrutheiser/hugo-lithium-theme --depth=1 themes
修改 config.toml
文件,添加下面一行
theme = "hugo-lithium-theme"
这个主题干净简介,但对代码、引用显示效果不好,后面我得改改 Markdown Render。
预览内容
执行下面命令,使用 Hugo 生成静态内容并在本地启动 HTTP Server。
hugo server
打开浏览器,访问 http://localhost:1313/
预览生成的内容。
你应该能够看到这样的页面。
图 1. 首次生成的页面
好了,尽管没有什么文章,但可以看到下面 “RSS feed” 字样了,说明的确是生成了 一个空的框架出来。
添加一篇文章
下面,开始写你的第一篇文章吧。
新建文章
content
目录用于分类存储博文的 Markdown 文件,也可存放图片文件(资源文件)。
在 content
内创建 post
目录,用于放博文,然后在里面创建 Markdown 文件。
$ mkdir content/post
$ touch content/post/first-article.md
也可以使用 Hugo 的命令,新建一篇文章。
hugo new post/first-article.md
Hugo 的 Markdown 文件顶部,用一对 “+++
” 标识特殊字段,包含文章标题、日期、作者等信息。
有的主题还支持 tag
和 category
这样的字段,用于分类和检索博文。
+++
date = "2017-05-28T20:06:42+08:00"
title = "first article"
+++
下面就是用自己喜欢的文本编辑器,编写这个 Markdown 文件。
如果还不熟悉 Markdown 语法,可以参考这篇 《Markdown——入门指南》。
写好后,在新的控制台里执行 hugo server
生成页面并预览。
图 2. 新建的文章
图 3. 新建的文章内容
Hugo Server 可以在你一边写 Markdown 时,一边监视文件改动,在文件保存后,自动重新生成 静态内容,并自动刷新浏览器页面。
添加图片
假如你当前编辑的文章 Markdown 文件为 content/post/my-lovely-cat.md
,而且你有一张
cat.jpg
的文件要添加到文章中。一种方法是,按照下面的步骤:
- 创建目录
content/post/my-lovely-cat/
; - 拷贝
cat.jpg
到上面目录里; - 在
first-article.md
文件适当位置,添加![MyCat](cat.jpg)
。
这样,就可以添加图片了。
图片示例 1. 简单方式
![MyCat](cat.jpg)
图片示例 2. 限定宽度(高度按比例缩放)
如果想限制图像的宽度、高度,或者设置对齐方式。那么可以嵌入 HTML 。
<img src="cat.jpg" width=400 />
图片示例 3. 居中对齐,并添加文本
<center>
<img src="cat.jpg" width=400 />
图 xx. 暗中窥视
</center>
图 xx. 暗中窥视
使用 Hugo 的 Shortcodes 也可以引入图片。
添加下载链接
如果想在文章中,提供一些文件供下载,可以插入链接。
如果文件在别的地方可以长期下载,比如 Hugo 的安装包,那最好定义一个重定向链接。如:
[hugo_0.21_Linux-64bit.deb](https://github.com/spf13/hugo/releases/download/v0.21/hugo_0.21_Linux-64bit.deb)
如果别的地方下载不到,想自己上传。一种方式是像引用图片一样,把文件放在对应目录下, 适用于 1MB 内小文件。(如果文件较大,但这样的方式并不推荐,因为这会让 Repo 变大变慢。)
一种较好的方式是将文件上传到 Release 中。然后引用 Release 中的下载链接。
进一步配置
配置 baseURL
文件 config.toml
中,设置如下:
baseurl = "https://zyfdegh.github.io/"
title = "My Blog"
添加导航栏分类
导航栏中可以添加链接对内容进行分类。
图 4. 导航栏
编辑文件 config.toml
。比如想要添加一个 “Articles”,一个“About” 页面,则添加如下内容。
[[menu.main]]
name = "Articles"
url = "/"
weight = 1
[[menu.main]]
name = "About"
url = "/about/"
weight = 2
其中,weight
为从左向右的显示顺序。
图 5. 导航栏新增链接
此时,点击 “About” 后,出现 404 page not found
,原因是未创建相应的文件。
下面在 content
目录下,新建文件 about.md
,并使用写上一些介绍文字。
图 6. About 页面
设置左上角 Logo
左上角无法显示的图片为 Logo,需要准备一张约 64×64 的图标文件(ico、png、jpg 格式都可以)。
图 7. 小拳头
拷贝文件到 static/images/
目录下。
编辑文件 config.toml
,在 [params]
段下设置如下内容 。
[params]
[params.logo]
url = "logo.ico"
width = 50
height = 50
alt = "Logo"
这样,再查看时候,应该有了 Logo 图标。
图 8. 导航栏设置 Logo
并不是所有主题都是这样设置的。需要了解所用的主题 template 文件里是怎样写的。 如 Lithium 主题中,文件 themes/hugo-lithium-theme/layouts/partials/nav.html 写了
<img src="{{ .Site.BaseURL}}images/{{.Site.Params.logo.url}}"
所以得知 用的 Logo 文件路径与配置文件里的层次关系。
启用 Disqus 开启评论
还没写。
启用 emoji 表情支持
还没写。
设置 Favicon
还没写。
设置底部信息
还没写。
插入 Tweet
还没写。
假装是个数学男
还没写。
替换 Markdown Render
还没写。
提交到 GitHub
在 GitHub 创建一个新的 Repo,名称如 blog
,用于存储这个博客配置、文章、静态资源等。
本地初始化 git 。
$ git init
$ git commit --allow-empty
在本地创建 commit 时,至少将下面的文件或目录 add 进去。
$ git add config.toml
$ git add content/
$ git add static/
由于 themes/hugo-lithium-theme
目录本身也是一个 git repo,所以可以使用 git submodule 来添加。
$ git submodule add \
https://github.com/jrutheiser/hugo-lithium-theme themes/hugo-lithium-theme
在一个新的地方 clone 下 blog 项目后,要同步 git modules,执行
git submodule sync && git submodule update --init --recursive
执行 hugo
不加任何参数,会生成静态内容到 public/
下。这个目录无需添加,因为内容都是可以
再次生成的。为了防止被 add 到 commit 中,可以将 public/
加入 .gitignore
中。
$ echo "public/" >> .gitignore
$ git add .gitignore
接着提交到你的 GitHub 中。
$ git commit -am "add files"
$ git remote add origin https://github.com/<yourname>/blog
$ git push origin master
将 替换为你的 GitHub 用户名,下文同。
到这里,只是把博客配置、文章还有静态资源给上传到了 GitHub,还不能访问 GitHub Pages。
发布到 GitHub Pages
一些基础知识
GitHub Pages 是 GitHub 推出的一个类似于 WordPress、Medium 的静态内容托管平台。适合一些 开源项目的文档。当然托管博文也不赖。
GitHub Pages 需要一堆生成好的 HTML、CSS 与资源文件才能工作,生成工具不限于 Hugo 或者 Jekyll 等。
GitHub Pages 静态内容放在 GitHub 的 Repo 中。
在 GitHub Pages 中,一个用户(或者组织)拥有一个 <yourname>.github.io
这样的域名,
访问这个域名,就能访问到某个 Repo 中的静态内容。
在 GitHub 中,<yourname>.github.io
这样的 Repo 具有特殊含义。GitHub 能自动识别,
并认为这是存放 <yourname>.github.io
这个域名静态内容的 Repo。GitHub 会自动启用
GitHub Pages。
当然,如果 Repo 名字和域名不一样,也是可以的。但需要一些额外的配置。 见 Configuring a publishing source for GitHub Pages。
如果将生成的静态内容,放到
blog
的gh-pages
分支也是可以的。但这里为了分离,还是 将静态内容单独存放。
一些 HTML、CSS 与资源文件引用的路径需要是绝对路径,也就是说,引用路径需要带上域名。
在 Hugo 中,有个参数叫 baseURL,设置后,可以在生成的静态内容引用路径前,带上域名。
生成并上传
在 blog
的上一级目录,创建一个 <yourname>.github.io
的目录。这个目录用于存储
Hugo 生成好的静态内容。
$ mkdir ../<yourname>.github.io
执行下面命令,生成静态内容到 <yourname>.github.io
中。
$ hugo --baseURL=https://<yourname>.github.io/ -d ../<yourname>.github.io
接着在 GitHub 创建一个名为 <yourname>.github.io
的 Repo,并将上面目录
<yourname>.github.io
中的全部文件提交到这个 Repo 中。
$ cd ../<yourname>.github.io
$ git init
$ git commit --allow-empty
$ git add --all
$ git commit -am "add files"
$ git add origin master https://github.com/<yourname>/<yourname>.github.io
$ git push origin master
上传完成后,浏览器打开 <yourname>.github.io
,应该可以看到博客页面了。
图 9. GitHub Pages 页面
至此,一个博客已经出锅了。
样例 Blog 已经开源,见 github.com/zyfdegh/blog-example
配置 Travis CI(拓展部分)
Travis CI 是一款云端持续集成工具,对个人开放 Repo 免费使用。使用 GitHub 帐号可以启用 Travis CI 并允许 Travis CI 访问你的 GitHub Repo。
图 10. Travis CI 首页
如果想在每一次新建、修改文章或替换主题后,只需要 commit 和 push 两条命令提交改动到
blog
这个 Repo,而无需重新生成和更新 <yourname>.github.io
这个 Repo, 就能让
GitHub Pages 自动更新。那么使用 Travis CI 便能实现。
这里 Travis CI 会在云端自动检测 blog 这个 Repo 的更新,并代替人工生成静态内容、 提交改动的过程(即上面 “发布到 GitHub Pages” 这个过程)。
用 “检测” 一词并不准确,其实是在对 blog 的 push 操作后,GitHub 发了通知触发 Travis CI 。
生成 GitHub Token
直接访问 https://github.com/settings/tokens/new,或打开 GitHub -> Settings -> Personal access tokens -> Generate new token,输入密码。
填入 Token 名称,并只勾选 public_repo
这一项目。
图 11. 生成 Token
点底部 Generate token,复制这个 Token,下面将用到。
添加 Repo
点击这里的加号。
图 12. 添加 Repo
点击滑条启用 Repo。
图 13. 启用 Repo
设置 Job
点击齿轮图标,进入设置页面。勾选 “Build only if .travis.yml is present”。
在 “Environment Variables” 中,创建环境变量,键为 “GITHUB_API_KEY”,值为上面复制的 Token。
图 14. 配置 Job
确保右侧按钮处于 ** 灰色 OFF** 状态,否则构建日志中,将会输出 Token,并容易泄漏。
最后,点最右侧 “ADD” 按钮。
图 15. 添加变量
添加 .travis.yml
在 blog
这个 Repo 里,创建文件 .travis.yml
,内容参考下面。
sudo: false
language: go
git:
depth: 1
install: go get -v github.com/spf13/hugo
script:
- hugo
deploy:
provider: pages
skip_cleanup: true
# token is set in travis-ci.org dashboard
github_token: $GITHUB_API_KEY
on:
branch: master
local_dir: public
repo: zyfdegh/zyfdegh.github.io
target_branch: master
email: deploy@travis-ci.org
name: deployment-bot
这个文件将会告诉 Travis CI 做下面步骤。
- 启动一个有 go 语言环境的容器;
- 在容器内用 go get 安装 Hugo;
- 克隆当前 Repo 并进入目录;
- 执行 hugo 命令(将生成静态内容到 public/ 下);
- 部署内容到 GitHub Pages。对 public/ 目录下所有内容提交到 github.com/zyfdegh/zyfdegh.github.io 的 master 分支上。使用 Token 访问,并用帐号 deployment-bot。
添加文件 .travis.yml
并 push 到 blog
中,接着将会进行一次构建。
图 16. 构建过程
如果生成、部署结果没有错,那将会 GitHub Pages 页面将会更新。
使用 Travis CI 构建 GitHub Pages 会清空
<yourname>.github.io
中所有原有 commits, 并且只保留最新生成的内容。这个要注意,一不小心无法回退了。
总结
到这里,配置完成,其实花了很大功夫,但是这样一次配置后,后面写博文的过程就爽歪歪了。 只需要对 blog 进行改动,然后提交。像写程序一样,写博文了。较为 nerd 的一种方式。 折腾至死。
头一次写这么长的教程,如有误,求轻喷并指正。
FAQ
如果我有自己的域名,并想重定向到 GitHub Pages,可以嘛?
答: 似乎不行,我试过 CNAME 重定向,结果 GitHub Pages 是工作了。但自己的域名显示不了。 可以试一试,改掉 baseURL 为自己的域名,然后重新生成、提交一次。但这样就 牺牲 GitHub Pages 了。