普通视图

发现新文章,点击刷新页面。
昨天以前首页

如何利用 Telegram 打造 0 成本微博客

作者 青山
2024年10月13日 23:48

如何利用 Telegram 打造 0 成本微博客 - 第1张图片

看到标题可能有人就说了,Telegram Channel 本身就可以作为一个微博客使用,但问题是并不是所有人都有能力和方法使用并访问 Telegram Channel,CloudFlare 和开源项目 BroadcastChannel 巧妙地解决了这个问题。

BroadcastChannel 介绍

BroadcastChannel面条大佬开发的项目,可以将 Telegram Channel 转为微博客使用,通过 Telegram Channel 发布内容,另一端通过 Astro 程序进行呈现。

事先需要准备好 CloudFlare 账号和可以使用 Telegram 的网络。

项目提供了 Serverless 和 Docker 两种部署方式,前者简单易懂,也是我目前使用的。

BroadcastChannel 部署

第一步,Fork 该项目到自己的 GitHub,接着前往 CloudFlare 或者 Vercel、Netlify 等平台创建项目,仓库即选择刚刚 Fork 的 BroadcastChannel。

如何利用 Telegram 打造 0 成本微博客 - 第2张图片

选择 BroadcastChannel 项目和 Astro 框架,然后再配置环境变量,其中必须事先配置的是 CHANNEL 变量,内容填频道名称,例如我的 @FindBlog 频道,变量就填写 FindBlog 即可。

如何利用 Telegram 打造 0 成本微博客 - 第3张图片

其他保持默认即可,该项目还提供了其他环境变量可供配置,可以在部署之后自行添加。

如何利用 Telegram 打造 0 成本微博客 - 第4张图片

只需一眨眼的功夫,该项目成功在 CloudFlare Pages 上部署,可以访问默认域名,也可以添加自定义域名。

后续只需要在 Telegram Channel 更新内容,即可自动同步并部署至 CloudFlare Pages,无需动手。

我在该项目开源之后第一时间部署了 @FindBlog 的微博客,效果很惊人,不仅界面美观,SEO 友好,还提供了 RSS,对于想简单写点博客的人来说,是一种简单、快捷的体验方式。

地址:https://broadcastchannel.pages.dev/

如何利用 Telegram 打造 0 成本微博客 - 第5张图片

其他变量:

## Telegram 频道用户名,必须配置。 t.me/ 后面那串字符
CHANNEL=FindBlog

## 语言和时区设置,语言选项见[dayjs](https://github.com/iamkun/dayjs/tree/dev/src/locale)
LOCALE=zh-cn
TIMEZONE=Asia/Shanghai

## 社交媒体用户名
TELEGRAM=huhexian
TWITTER=huhexian
GITHUB=huhexian

## 下面两个社交媒体需要为 URL
DISCORD=https://DISCORD.com
PODCASRT=https://PODCASRT.com

## 头部尾部代码注入,支持 HTML
FOOTER_INJECT=FOOTER_INJECT
HEADER_INJECT=HEADER_INJECT

## SEO 配置项,可不让搜索引擎索引内容
NO_FOLLOW=false
NO_INDEX=false

## Sentry 配置项,收集服务端报错
SENTRY_AUTH_TOKEN=SENTRY_AUTH_TOKEN
SENTRY_DSN=SENTRY_DSN
SENTRY_PROJECT=SENTRY_PROJECT

## Telegram 主机名称和静态资源代理,不建议修改
HOST=telegram.dog
STATIC_PROXY=

如何利用 Telegram 打造 0 成本微博客》最先出现在印记

如何利用 Telegram 打造 0 成本微博客

作者 青山
2024年10月13日 23:48

如何利用 Telegram 打造 0 成本微博客 - 第1张图片

看到标题可能有人就说了,Telegram Channel 本身就可以作为一个微博客使用,但问题是并不是所有人都有能力和方法使用并访问 Telegram Channel,CloudFlare 和开源项目 BroadcastChannel 巧妙地解决了这个问题。

BroadcastChannel 介绍

BroadcastChannel面条大佬开发的项目,可以将 Telegram Channel 转为微博客使用,通过 Telegram Channel 发布内容,另一端通过 Astro 程序进行呈现。

事先需要准备好 CloudFlare 账号和可以使用 Telegram 的网络。

项目提供了 Serverless 和 Docker 两种部署方式,前者简单易懂,也是我目前使用的。

BroadcastChannel 部署

第一步,Fork 该项目到自己的 GitHub,接着前往 CloudFlare 或者 Vercel、Netlify 等平台创建项目,仓库即选择刚刚 Fork 的 BroadcastChannel。

如何利用 Telegram 打造 0 成本微博客 - 第2张图片

选择 BroadcastChannel 项目和 Astro 框架,然后再配置环境变量,其中必须事先配置的是 CHANNEL 变量,内容填频道名称,例如我的 @FindBlog 频道,变量就填写 FindBlog 即可。

如何利用 Telegram 打造 0 成本微博客 - 第3张图片

其他保持默认即可,该项目还提供了其他环境变量可供配置,可以在部署之后自行添加。

如何利用 Telegram 打造 0 成本微博客 - 第4张图片

只需一眨眼的功夫,该项目成功在 CloudFlare Pages 上部署,可以访问默认域名,也可以添加自定义域名。

后续只需要在 Telegram Channel 更新内容,即可自动同步并部署至 CloudFlare Pages,无需动手。

我在该项目开源之后第一时间部署了 @FindBlog 的微博客,效果很惊人,不仅界面美观,SEO 友好,还提供了 RSS,对于想简单写点博客的人来说,是一种简单、快捷的体验方式。

地址:https://broadcastchannel.pages.dev/

如何利用 Telegram 打造 0 成本微博客 - 第5张图片

其他变量:

## Telegram 频道用户名,必须配置。 t.me/ 后面那串字符
CHANNEL=FindBlog

## 语言和时区设置,语言选项见[dayjs](https://github.com/iamkun/dayjs/tree/dev/src/locale)
LOCALE=zh-cn
TIMEZONE=Asia/Shanghai

## 社交媒体用户名
TELEGRAM=huhexian
TWITTER=huhexian
GITHUB=huhexian

## 下面两个社交媒体需要为 URL
DISCORD=https://DISCORD.com
PODCASRT=https://PODCASRT.com

## 头部尾部代码注入,支持 HTML
FOOTER_INJECT=FOOTER_INJECT
HEADER_INJECT=HEADER_INJECT

## SEO 配置项,可不让搜索引擎索引内容
NO_FOLLOW=false
NO_INDEX=false

## Sentry 配置项,收集服务端报错
SENTRY_AUTH_TOKEN=SENTRY_AUTH_TOKEN
SENTRY_DSN=SENTRY_DSN
SENTRY_PROJECT=SENTRY_PROJECT

## Telegram 主机名称和静态资源代理,不建议修改
HOST=telegram.dog
STATIC_PROXY=

如何利用 Telegram 打造 0 成本微博客》最先出现在印记

入门blog回忆录

作者 xrspook
2024年9月29日 09:33

当年今日

周六早上,我发现有人在我的blog上留言,问我为什么可以坚持那么久,为什么要写blog,以及怕不怕有隐私的问题。这条评论我已经回复过了,所以具体是怎么回复的,我也就没有必要再详细说明。

每一代人都有每一代人的特点以及习惯。对我来说,我在最花样的时候接触到了blog这种东西,也把这个东西一直坚持了下来。在开始blog之前,我已经有了做网站的想法,但是要怎么做网站呢?自己用花生壳搭建一个,然后买个域名绑上去?我真的有想象过那样做,但是这样干的话,如果我把电脑关了,那岂不是不能访问?如果不是这样,我还得先买个空间。在哪里买?得花多少钱?对学生时代的我来说,那些要花钱的东西基本上我都不会考虑。还有一点,搭建一个网站,我应该用什么软件呢?当时我想搭建一个网站,主要的思路是搭建一个静态的网站,所以肯定得把整个网站的内容都做好了,然后放到网上,但关键是我要做什么内容呢?一开始我想到的是The X-Files。我为什么要做那个呢?纯粹因为喜欢?别人的网站做得比我详细比我好,唯一的问题就是那些都是英文的,仅此而已。我把那全站翻译过来也没什么意义,因为我模仿不出那个效果。当我有那个念头的时候,网站上很流行用flash之类的东西。那个时候的我对flash可以说是一窍不通的。高中的时候,电脑选修课程我选的是photoshop。在我有网站念头,但不知道该如何操作的时候,我遇到了blog。因为Yo soy Betty la Fea,我遇到了danzhu,准确来说是遇到了danzhu的网站。没有那么多花哨的东西,吸引我的只有内容。她的网站几乎没有图片,又或者说实际上是有的,但不是直接以图片的方式贴出来,而仅仅是发一个链接而已。如果某篇里有个图片,大多时候是某个工具的使用,而不是粉丝花痴的内容。从那个时候开始,我就觉得blog这种方式很赞。之所以我会停留在那个网站不停地翻看,一遍又一遍阅读是因为那些内容、那些文字,以及那些链接带出来的信息。第一次看的时候可能是看文字。第二次看的时候是找链接。第三次看的时候可能是记得好像见过某个东西,但又好像找不到了,于是不停地在那里翻。当时danzhu的网站是在blogger上面建的,域名是新浪的。当时danzhu的那个网站不完全是Yo osy Betty la Fea 的内容,也有她自己的东西,她自己的生活以及她的生活和这部电视剧产生的某些联系,还有一些她对这部电视剧又或者是她搜索相关资料之后的感想。那是我第一次知道,原来网站是可以这么干的。有些人把blog作为一个专业的网站,但我更习惯于danzhu的这种方式,以至于后来其实我也在遵循或者说是模仿,或者是融入了自己的东西继续这种形式。在Google上建立网站不用钱,但关键是在国内不能直接访问,所以你得买个域名,然后绑上去。虽然当年我经常访问那个网站,基本上打开电脑之后,我就一定要去那个地方,但现在我居然忘了域名到底是什么,网站名到底是什么?后来新浪的域名估计再也没有续费了,这网站不能访问。因为那里丢空了太久,danzhu自己也忘记了对应的blogger账号,所以她也没办法访问后台,把网站的内容导出。当时我称呼danzhu为danzhu姐姐。唯一肯定的是她一定比我大,因为我首次接触的时候,我只是个高中生,但她已经工作多年了。她好像是从事IT工作的,但具体做的是什么,她并没有在那个网站上有非常详细的描述,不像现在我自己的blog那样,基本上里里外外没有什么保留着。

那个网站,让我明白到分享的乐趣,或许写那些的时候,她没有想过其他人会搜索,会喜欢上,而且是非常喜欢。对她自己而言,可能更是一个记录,因为她自己喜欢那个东西,所以她就把自己的爱好记录下来。可能,她开始做的时候,没有想过因为她的这个网站,会聚集了一帮喜欢的人,同时也让我成为了她的粉丝之一,最后也让我走上了blog这条不归路,一发不可收拾。

现在如果你突然问我,有什么是让我觉得很骄傲的。把一件事坚持20年,而且还一直保留着高度的热情。我觉得,起码对我来说,到现在为止,这肯定是我觉得最骄傲的事情。

14年的独立blog

作者 xrspook
2024年8月29日 08:45

当年今日

blog在WordPress上,不知不觉已经14个年头。如果没记错的话,是在2010年开始的,因为那个时候BlogBus崩掉了。这14年,我都是跟着同一个团长。那个团长是在豆瓣上认识的,估计现在那个团里面就只剩下我和他了,其他人可能都已经渐渐退掉。实际上,对blog有需求的人,可能只剩下我一个,只有我一个积极用户。团长本身就只是做那个事而已,我不知道他有没有在服务器上折腾些什么。以前可能他是有折腾的,但折腾这种事,对普通人来说不可能一直都折腾。因为写blog本身不算太折腾,每天都耗费基本上相似的时间,习惯下来就好。

我有想过有一天团长不干了,我该怎么办。我自己独立一个门户吗?那个时候,如果遇到一些技术上的故障,我该怎么办呢?现在实际上,我们也的确遇到了技术上的故障。因为团长换电脑了,所以那个服务器的账号密码不见了。理论上联系服务商,只要你提供足够的资料,对方是可以帮你找回密码或者帮你重置密码的,但关键是邮件发过去,对方完全不理你,还真一点办法都没有。当然,如果服务商是大型的,估计不会发生这种事,但如果那只是一个小众的服务商,那么发生这种事,绝对是有可能的,中途跑路也是有可能的。这么多年下来一直都相安无事,我觉得都已经是个奇迹了。中途我们有没有搬过家呢?我没什么印象,因为不是我操作的,我顶多是一段时间开不了网页,但实际上,无论我开得了还是开不了网页,我的blog都会继续,都会在记事本上写下来。重新能开网页的时候,我就把之前囤下的那些东西发布上去,仅此而已。

如果有一天团长不干了,我还会继续每天写,但那个时候估计就不能称之为blog,要称之为日记了,blog和日记对我来说,最大的区别在于一个自己存着,另外一个放在网上,谁都可以看到。

服务商这种东西,即便是最大型的,也说不准靠谱不靠谱,因为大型的服务商也非常有可能有倒闭的那一天,某一天,他们不再开展这个业务了,转而开展别的,把这个业务关闭了,你一点办法都没有。一直以来我们的数据都是放在外国的服务器的。以现在的局势看来,继续放在外国好像有点风险。倒不是因为我的数据有什么问题,涉及了什么方面的东西,而是如果一旦某些事情发生,互联网中断,即便我的东西还存在着,但我再也接触不到了。

我从2004年开始写自己的blog,到昨天为止,我备份了一下全站的内容,媒体资料有400多MB,数据库有70多MB,其它的都是一些很小的脚本。文字内容的东西基本上都在数据库的SQL文件里,附件类图片音频之类的东西其实这么多年下来也不是很大,最主要的原因是可能一开始我会用得比较多,尤其是在我刻橡皮章的时候,后来越来越少了,尤其是近几年,我基本上没有了什么兴趣爱好之后。

还记得一开始在BlogBus上开我自己的blog的时候,我的誓言是一辈子都写,每天不间断,但现在看来,写不写下去靠的是我个人,但能不能让其成为blog,外部干扰因素很大。如果是短时间内,外部因素干扰可以忽略,但如果把时间延长到十年甚至几十年,外部干扰因素影响非常大。

支持 Side Note 和 Margin Note

作者 Lenciel
2023年9月27日 17:45
这次加上对「Side Note」和「Margin Note」的支持,是因为发现自己写东西越来越多使用到 Markdown 默认支持的脚注。但其实脚注不是一个很好的设计。我很仰慕的,跨了不知道多少学科的数据可视化泰斗 Edward Tufte 干脆就觉得它是个很糟的设计,所以在著名的 Tufte-CSS 里基本上只强调边注的使用...

Hexo blog 的升级与同步方案

作者 anran758
2019年11月2日 09:44

前一篇我们介绍了如何使用 Hexo 框架及 Next 主题搭建博客。这次来聊聊如何安全的更新博客与主题的版本。

next theme


早期写博客时笔者就有考虑过使用 git 来做版本控制,那时 github 私人仓库还没有免费开放,国内虽然有 coding 和码云这些平台有开放少量的私人仓库,但由于懒得折腾就选了最方便同步的 OneDrive(因为它只需将文件夹移入就可以实现跨设备共享)。

后来笔者因为工作的原因,需要在多设备中频繁切换,这种简单同步方式就会暴露出一些问题。比如说,在设备 A 想对博客做一些自定义的修改,其中可能会动到依赖,但此时设备 B 的文件正在同步,那这样可能会导致文件不一致的问题。可能会将旧的文件重新同步过来,这可能会导致程序报错,还不易于排查。

冲突文件合并失败会额外添加如 index-anran758's MacBook Pro.js 之类的同名文件,并且发生冲突时是隐式的,你甚至不知道发生了冲突,这种体验使用不太友好。

因此 OneDrive 的同步方式适用于改动不会太大的文件。


如果你对 git 版本控制比较熟悉的话,那可以通过 git 对 blog 进行版本控制。

使用源码托管平台的话就如上文所说主要有这么几种选择:

国内的 gitee(码云)coding 是一个不错的选择,代码的上传于下载速度也比较可观。国外可以使用 github,github 的私人仓库是今年才开放无限制免费创建仓库数量的,缺点由于众所周知的问题,有时可能拉代码速度较慢。

笔者使用的是 github 作为源码托管,下文将要介绍的方法对于 git 仓库是通用,因此根据自身的喜好选择对应的平台。

博客托管

托管 blog 源码的步骤如下:

  1. 找到对应的平台,创建私人仓库(注意是 Private,不要将自己的私人配置也开源咯)。

  2. 仓库创建完毕后,得到仓库的地址。打开命令行,进入 /blog 目录下并输入命令:

    1
    2
    3
    4
    5
    6
    # 初始化 git 项目
    git init

    # 添加一个名为 origin 的 remote
    # your_repo_path 是你创建仓库得到的仓库地址
    git remote add origin your_repo_path
  3. 由于 /theme/next 本身也是一个仓库,git 无法提交嵌套仓库的文件夹,因此需要在 .gitignore 添加配置,忽略该文件夹

    1
    2
    # 其他忽略规则...
    themes/next/
  4. 提交代码

    1
    2
    3
    4
    5
    6
    # 提交代码
    git add .
    git commit -m "new: blog 数据开始进行版本控制"

    # 设置上游(-u)并推送至远程的 master 分支
    git push -u origin master
  5. 这样我们就完成了博客的源码托管。

主题托管

Next theme 官网介绍的安装方式如下:

1
2
3
4
5
# 进入 blog 目录
cd blog

# 言下之意就是将该库克隆到 themes 目录下的 next 文件夹中
git clone https://github.com/theme-next/hexo-theme-next themes/next

Next theme 7.0+ 版本中,主题嵌入了检查版本更新的代码,每当运行本地服务器时,都会进行检查版本号的更新。当有新的版本发布时会在命令行输出警告:

1
2
3
WARN  Your theme NexT is outdated. Current version: v7.4.2, latest version: v7.5.0
WARN Visit https://github.com/theme-next/hexo-theme-next/releases for more information.

这时你想体验 Next 的新特性的话可能会有点麻烦,因为原先我们在旧版本上修改了配置,或添加了一些自定义的布局。这将会造成代码冲突。

因此我们需要独立开两条分支:

  • master 分支是官方发布的正式版本,我们不去修改 master 分支的中的任何文件。
  • 另一条是我们自己创建的新分支,笔者命名为 customize, 言下之意为该分支含有我们自定义的修改,包括私人配置等。

除此之外,由于主题配置文件(theme/next/_config.yml)中含有某些应用的 appid 或者 secret,这些配置不应该被其他人随意看到以防冒名滥用。因此我们应该将该项目额外添加一个 remote 来保存我们的私人配置。 具体操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 此时已经下载到了主题文件夹

# 创建并切换新分支
git checkout -B customize

# 进行主题配置或其他修改操作

# 提交改动(未推送)
git add .
git commit -m "chg: 修改为自定义配置"

# 添加一个名为 userRepo(名字可以自己定义,只要自己能搞清是哪个来源即可) 的新 remote,
git remote add userRepo git@github.com:anran758/hexo-xxx-next.git

# 设置上游(即以后使用 git pull/status 时默认拉取 userRepo 源的 customize 分支),并推送指定 remote
git push -u userRepo customize

如此就完成了代码的追踪,以后使用 next 主题就不是从 hexo-theme-next 中获取了,而是我们自己的私人仓库 hexo-xxx-next 中获取,安装方式是一样的。

版本升级

Next

前文说过我们将源码托管的需求之一就是为了解决代码合并的问题,为了体验新版本的特性,我们需要将新版本的代码合并进我们的分支:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 从 origin/master 获取最新版本的代码
# 理论上我们不修改 master 分支的代码不会发生冲突
git fetch origin
git pull --no-commit origin master

# 切换至 customize 分支
git checkout customize

# 检查本地是否有文件改动,有的话需要进行 commit 提交或者使用 git stash 藏起来
git status

# 合并代码
git merge master

我们最起码修改过 _config.yml,因此会发生冲突也不奇怪,有冲突咱们就解决冲突。

如果你使用 vscode 进行编码,侧边栏有一个源代码管理,打开它可以看到冲突的文件。

打开冲突的文件,判断冲突项确定要保留(删除)的代码,解决冲突后,提交到缓存区(git add .(file))。缓冲区有本次升级所涉及的代码,可以大致预览一下本次的更新都做了什么事

1
2
3
4
5
6
7
8
9
10
11
12
13
# 将缓冲区的文件提交至 commit
git commit -m "Merge release v(version) into customize branch"

# 提交代码
git push
# Counting objects: 99, done.
# Delta compression using up to 4 threads.
# Compressing objects: 100% (57/57), done.
# Writing objects: 100% (99/99), 12.86 KiB | 346.00 KiB/s, done.
# Total 99 (delta 71), reused 64 (delta 42)
# remote: Resolving deltas: 100% (71/71), completed with 41 local objects.
# To github.com:anran758/hexo-xxx-next.git
# 4a70c18..54805a2 customize -> customize

升级完后运行本地服务器最后会输出一条:

1
INFO  Congratulations! Your are using the latest version of theme NexT.

Hexo

若最新版本的 Hexo 引入了你想要的新功能,你想更新 Hexo 版本的话,首先确定版本号变动的是哪一位。

package.json 的版本号格式是数字由点分隔,如 主版本号.功能版本号.补丁版本号。若更新是主(大)版本号的话,则需要先修改 dependencies 依赖中 hexo 的主版本号,再输入 npm update

以下是 hexo@v3 更新为 hexo@v4 的示例:

1
2
3
4
5
6
7
{
// ...
"dependencies": {
+ "hexo": "^4.0.0",
- "hexo": "^3.9.0",
}
}

命令行输入:

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
$ npx hexo -v
hexo: 3.9.0
hexo-cli: 2.0.0
os: Darwin 17.7.0 darwin x64
node: 12.13.1
v8: 7.7.299.13-node.16
uv: 1.33.1
zlib: 1.2.11
brotli: 1.0.7
ares: 1.15.0
modules: 72
nghttp2: 1.39.2
napi: 5
llhttp: 1.1.4
http_parser: 2.8.0
openssl: 1.1.1d
cldr: 35.1
icu: 64.2
tz: 2019c
unicode: 12.1

$ npm update
+ hexo@4.2.0
added 71 packages from 90 contributors, updated 14 packages and moved 5 packages in 12.513s

$ npx hexo -v
hexo: 4.2.0
hexo-cli: 3.1.0
os: Darwin 17.7.0 darwin x64
node: 12.13.1
v8: 7.7.299.13-node.16
uv: 1.33.1
zlib: 1.2.11
brotli: 1.0.7
ares: 1.15.0
modules: 72
nghttp2: 1.39.2
napi: 5
llhttp: 1.1.4
http_parser: 2.8.0
openssl: 1.1.1d
cldr: 35.1
icu: 64.2
tz: 2019c
unicode: 12.1

若只是后面两位版本号有变更的话,仅需输入 npm update 即可。

总结

单单从升级版本来合并代码的角度来看,实际上本地 commit 也可以做这种事,将 commit 储存在本地(.git)中不提交远端也是没有问题的,OneDrive也可以完成同步。

但从安全和可调试的角度来看,OneDrive的同步方式存在一定风险(懒的代价)。使用 git 版本控制可以清晰看到每一次提交的修改,不会多出奇奇怪怪的东西。必要的时候还可以进行回滚,相对来说更安全。但这种方案需要使用者了解一定的 git 知识。

从操作步骤来看,使用的 git 同步方案会产生多个仓库,这些仓库一般是拥有权限的人才能查看(修改)源码。比如完成了本文中两个仓库源码同步后,在另一台设备初次同步的步骤是:

  1. 通过 git clone 下载 blog 本体。
  2. 通过 git clone 下载私人仓库 next theme/theme 目录下。
  3. 进入两个仓库内安装对应的依赖

以上可以在 blog 项目下的 package.json 设置 scripts,通过一条命令来完成这些事。

由此我们可以看到,相比 OneDrive 的懒人方案,git 方案的操作步骤会更繁琐。更新方式也从自动更新变成手动更新。

两者种方案各有利弊,具体采用什么方案就看朋友们的习惯啦~


本文涉及到的 git 命令都是可以在 git 速查方案 查找相应的解释。

从搭建到部署,快速构建一个私人博客

作者 anran758
2019年8月19日 00:33

有时候我们希望有一个受控的博客,来记录或分享一些东西。这个博客的主题内容由你自己来决定,可以是技术分享(编程、汉化分享等),也可以是生活感想。

本文将介绍一个可以迅速搭建并部署的受控博客。阅读本文前,希望你对以下知识点有所了解:

  • git(版本控制) 的基础使用
  • markdown 的使用

为什么要搭建博客

在线类博客有很多选择,为什么我们需要从零搭建新的博客呢?自己搭建的博客有什么好处吗?

首先,前文所提的 “博客受控”,指的就是能够自己控制的博客的样式、内容等,自己想怎么改就怎么改。

内容受控是指我们知道在线类的博客是受平台限制的,这意味着你所发表的内容是需要受审才能发出的,一些敏感的技术词汇,该篇文章都可能会被和谐或被删除。但在自己搭建博客就没有这样的问题,最起码能保留源文件。

其二,博客的样式是受控的。像著名在线博客CSDN上一些博主的文章确实是有学习参考的价值,但问题的是该站广告是在是太多了,字体和排版的阅读体验并不太好。但如果是自己搭建的博客的话,就可以自己着手优化这些问题。

但博客的搭建还需要我们从各方面考虑利弊。平台类博客会有相应的推荐系统,会对同类型文章相互引流,在 SEO 方面会做得比我们好。

个人搭建的博客,刚起步时的浏览量并不高,但是可以通过SEO等方式来逐步增加自己网站的权重。或者提高博客的质量和干货,读者认为文章有价值,自然会收藏起来形成熟客。

那么博客能写什么东西呢?在日常生活中,有很多知识点是呈碎片状,写博客的本质上就是对自己知识的一种梳理,然后再将这些知识分享出来,可能会有对这方面知识有疑惑,或者想找到解决方案,自身分享出来的东西能给读者做一定的参考。同时这也会是一个良性循环,因为分享的同时,你可能也需要去查询一些资料,同时也可以找到别人遇到过并分享出来的解决方案,是一个相互收益的过程。

我们的基本需求是梳理与分享,那么更应该把注意力放在内容本身,网站布局的排版样式等则是增加读者阅读体验的问题。因此我们可以使用现成的博客框架快速完成这些事。

博客框架有很多种选择,笔者选择的是 Hexo,因为它足够便捷优雅。

start

Hexo 依赖 Node.jsNPM包管理,Node.js 安装后一般会自带NPM

我们打开终端(Windows PowerShell / cmd.exebashmacOS 里的终端),输入以下命令:

1
2
3
4
5
6
7
8
9
10
# 检查 npm 是否安装成功
npm -v

# 安装 hexo cli,
# 如果安装速度过慢的话,可以安装国内的淘宝镜像
# 在命令行输入 ` npm install -g cnpm --registry=https://registry.npm.taobao.org`
npm install -g hexo-cli

# 检查 hexo 是否安装成功,并查看版本
hexo -v

依赖安装成功后,我们可以在命令行输入 hexo help 查看使用方式(描述是英文,示例部分笔者将其转为中文):

Usage: hexo <command>

commanddescription
help获取命令的帮助
init创建一个新的 Hexo 文件夹
version显示版本信息

使用 hexo help [command] 可以查看更多的信息, 如:

1
2
3
4
5
6
7
8
9
10
11
12
hexo help init
# Usage: hexo init [destination]

# Description(描述):
# 在指定的路径或当前目录中创建一个新的Hexo文件夹.

# Arguments(参数):
# destination 文件夹路径。 如果未指定,则在当前文件夹中初始化

# Options(选项):
# --no-clone 复制文件而不是从GitHub克隆
# --no-install 跳过 npm 依赖安装(默认初始化会自动装依赖)

全局选项:

optionsdescription
--config指定配置文件而不是使用默认的 _config.yml
--cwd指定 CWD
--debug显示终端中的所有详细消息
--draft显示草稿帖子
--safe禁用所有插件和脚本
--silent在控制台上隐藏输出

在官网 commands 中可以找到全部完整的解释。

建站

在终端上,我们可以看到有一个 init 的命令,我们可以使用这个命令来初始化 hexo 项目,但再建站之前我们需要先决定在哪里存放博客源代码。

我推荐使用如微软的 OneDrive(win10 系统自带)之类的云文件夹。你可以白嫖它 5G 的云储存空间。当你在设备A下修改了文件,它会自动同步到云端上。切换回设备B并登录账号后,它又会自动从云端下载数据,是一个便捷的方式。

但值得注意的是 OneDrive 毕竟是国外服务,由于众所周知的原因可能需要科学上网才能使用。该方式只是数据备份与同步的问题,不使用它也不会影响下文的构建。

1
2
3
4
5
6
7
8
9
10
11
# 如果你是 unix 系统的话,可以使用该命令查看当前路径
pwd
# /Users/anran/OneDrive

# 初始化文件夹名为 blog
hexo init blog
# INFO Cloning hexo-starter https://github.com/hexojs/hexo-starter.git
# other install info ...

# 进入文件夹
cd blog

安装完成后目录如下:

1
2
3
4
5
6
7
8
9
.
├── _config.yml (网站的配置信息)
├── package.json (应用依赖信息)
├── node_modules (依赖包)
├── scaffolds (模板文件)
├── source (资源文件夹是存放用户资源的地方)
| ├── _drafts (草稿文件夹,刚初始化时可能不存在)
| └── _posts (文章/帖子源码列表)
└── themes (主题)

配置

建站完成后我们需要进行 配置hexo 中主要有两项配置。一项是站点配置文件,路径为 /_config.yml。另一项是主题配置文件,路径是/themes/(下载的主题)/_config.yml

我们可以先在站点配置文件修改以下基础选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Hexo Configuration

# 网站主标题,SEO元素之一
title: blog

#网站副标题,可选
subtitle:

# 网站描述, SEO元素之一,用于告诉搜索引擎关于这个站点的描述
description: 分享生活、分享技术

# 网站的关键词,如:
keywords: Front end

# 网站作者
author: anran758

# 网站使用的语言, 由于 Hexo 具备多语言配置,默认为英文,我们需要修改回中文语言
language: zh-CN

启动

初始化项目后默认会安装相关的依赖,接着在命令行输入如下命令来运行博客

1
2
3
4
5
6
7
8
# 启动服务,默认端口为 4000,启动服务后可以在浏览器输入 `http://localhost:4000` 查看效果
hexo server

# or 简写方式
hexo s

# 还可以使用 -p, 指定 9000 端口
hexo s -p 9000

写作步骤

我们一般通过命令行来操作博客:

比如创建文章的方式如下: hexo new [layout] <title>

layout是指定布局,Hexo默认有postpagedraft 三种布局,它们分别对应不同的路径。我们也可以自定义布局,但实际页面会和post相同,都将储存到source/_posts文件夹。

按照我个人的写作习惯,通常写作步骤是:

  1. 创建草稿(drafts)
  2. 在草稿上进行写作
  3. 整理细节并在本地服务器上查看效果(server)
  4. 发布至正式的帖子上
  5. 生成静态文件并部署(后续讲)

创建草稿(drafts)

1
2
$ hexo new draft "My first post"
# INFO Created: ~/blog/source/_drafts/My-first-post.md

在初次创建草稿会生成一个名为 _drafts 的草稿文件夹,接着该文件夹下有一个我们刚刚创建的草稿,名为 My-first-post.mdmarkdown 文件,文件内容如下:

1
2
3
4
---
title: My first post
tags:
---

在本地服务器查看草稿(drafts)

我们可以启动本地服务器一边写作一边预览,但默认情况下草稿是不会被展示出来的,如果你想查看草稿的话,可以输入以下命令:

1
2
3
4
5
$ hexo s -p 9000 --draft
# INFO Start processing
# INFO Hexo is running at http://localhost:9000 . Press Ctrl+C to stop.

# 如果需要退出服务器,按住 control + c

发布草稿(publish)

如果我们在本地服务器上校队完草稿细节后,可以将草稿发布为文章,否则在后续生成博客静态文件时不会被打包出来:

1
2
3
4
# hexo publish [layout] <filename>
# 将草稿发布为文章
$ hexo publish post My-first-post
# INFO Published: ~/blog/source/_posts/My-first-post.md

输入命令后你可以发现发布的文章被转移到了source/_posts/上,这样就完成了本地的文章发布。

生成静态文件(generate)

Hexo框架的一项工作就是将源文件 markdown 最后生成为 HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 生成文件
$ hexo generate
# INFO Start processing
# INFO Files loaded in 275 ms
# INFO Generated: 2019/08/11/My-first-post/index.html
# INFO 1 files generated in 152 ms

# 简写形式
$ hexo g

# 监控文件变化,并生成静态文件
$ hexo g --watch

# 生成文件并部署(部署后面单独章节来讲解)
$ hexo g -d

主题

我们熟悉完博客系统的操作后,接下来就是美化博客。Hexo 支持主题,我们可以根据官网的创建主题教程自己来设计,也可以直接在主题商城 中找现成的主题。这里以笔者推荐的主题 Next 为例:

theme next

笔者一开始使用 next 主题时,版本才 5.x,当时仍有很多博客所需的东西没有集成。如今回头一看,发现 next 升级了好几个大版本。github 主题仓库也迁移至了 https://github.com/theme-next 里,乃至文档都有两个不同的版本。

新文档是采用它自身主题的一个scheme来建成,是全英文文档,可以保证信息资料是最新的。旧文档布局便于阅读,同时是中文文档,大多参数也能在该文档找到,但毕竟没有再过多的维护,建议还是以最新文档为参考。

安装主题可以通过git clone克隆至blog/theme/下:

1
2
3
4
5
6
7
8
$ pwd
# /Users/anran/OneDrive/Blog

# 启动主题前需要清除缓存与已部署的文件
$ hexo clean

# clone 主题
$ git clone https://github.com/iissnan/hexo-theme-next themes/next

接着在 站点配置文件(/_config.yml) 中启动 theme。再打开主题配置文件(/themes/next/_config.yml)选择 Scheme:

1
2
3
4
5
6
7
8
9
# _config.yml
- theme: landscape
+ theme: next

# /themes/next/_config.yml
# 提供三种模式
#scheme: Muse
#scheme: Mist
scheme: Pisces

评论、订阅、数据统计、SEO 等部分功能配置已经集成至 next 主题配置中,但大多还需要额外添加依赖还需要根据文档来配置。next 在主题配置中集成了由于配置自定义项过多,读者可以根据自己所需添加相应的统计、SEO 相关的 app key 等就不进一步展开讲。

部署

我们使用git进行部署,可以将网站部署至私人服务器、也可以部署到免费的github pages上。本文将介绍部署至github的方法,如果你还没有github账号的话,那你需要先注册一个账号

步骤如下:

  1. 访问github.com,点击sign up注册账号。

  2. 进入注册页,输入账号密码和邮箱,输入验证码!

  3. 选择免费用户

  4. 接着是关于github推荐服务的调查,当然你也可以跳过它.

  5. 验证完毕后,它会提示你创建一个仓库,这里我们先创建一个blog

  6. 复制仓库链接,copy 至 站点配置文件(/_config.yml)里。同时安装hexo-deployer-git的依赖:

    1
    npm install hexo-deployer-git --save
    1
    2
    3
    4
    5
    6
    7
    url: https://yourname.github.io/blog   # 修改为 github io 的地址
    root: /blog/ # 要将资源映射到仓库名

    deploy:
    type: git
    repo: https://github.com/yourname/blog.git # blog 的 git 地址
    branch: gh-pages # 发布至 gp-pages 分支,如果该分支不存在,就会自动创建它
  7. 接着开始部署。如果你还没配置git账号的话,它会提示你输入账号密码,输入正确的账号密码后就部署成功了。

    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
    # 或者使用`hexo d -g`, 两者是等价的效果
    hexo g -d

    # *** Please tell me who you are.

    # Run
    # git config --global user.email "you@example.com"
    # git config --global user.name "Your Name"

    # to set your account's default identity.
    # Omit --global to set the identity only in this repository.

    # fatal: unable to auto-detect email address (got '29625@DESKTOP-0R7P8H4.(none)')
    # Logon failed, use ctrl+c to cancel basic credential prompt.
    # Username for 'https://github.com': anran758
    INFO Start processing
    INFO Files loaded in 621 ms
    INFO 0 files generated in 424 ms
    INFO Deploying: git
    INFO Clearing .deploy_git folder...
    INFO Copying files from public folder...
    INFO Copying files from extend dirs...

    INFO Congratulations! Your are using the latest version of theme NexT.
    Enumerating objects: 131, done.
    Counting objects: 100% (131/131), done.
    Delta compression using up to 8 threads
    Compressing objects: 100% (91/91), done.
    Writing objects: 100% (131/131), 257.72 KiB | 2.48 MiB/s, done.
    Total 131 (delta 43), reused 0 (delta 0)
    remote: Resolving deltas: 100% (43/43), done.
    To https://github.com/yourname/blog.git
    * [new branch] HEAD -> gh-pages
    Branch 'master' set up to track remote branch 'gh-pages' from 'https://github.com/yourname/blog.git'.

    # 如果没有配置全局 git 账号的话可以先配置,不然下次部署还是会提示你输入账号密码
    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
  8. 接着在我们创建的blog下进入settings项,设置 github pagesgh-pages 也就是之前在配置里设置的分支即可。这样就可以在线上查看我们部署的状况啦~

优化与扩展

下面介绍一下文档中没有提到的相关问题与扩展。

本地搜索

next 有内置本地搜索的配置项,但文档上说明需要额外安装 hexo-generator-searchdb 这个依赖。但该项目现在已经被归档了,它还存在一些问题没有修复。你可以使用 hexo-generator-search 来代替它。接者在站点配置文件添加如下配置:

1
2
3
4
5
6
7
8
# Expansion: hexo-generator-search
# 站内搜索
# https://github.com/wzpan/hexo-generator-search
search:
path: search.xml
field: post
format: html
limit: 10000

在使用本地搜索功能时,你可能会遇到以下错误:

1
2
3
4
This page contains the following errors:
error on line 86 at column 35: Input is not proper UTF-8, indicate encoding !
Bytes: 0x08 0xE8 0xB7 0x9F
Below is a rendering of the page up to the first error.

出现这种错误原因大多是因为搜狗输入法带来的特殊字符串,我们在源码中替换它即可。打开编辑器(比如vscode),在全局搜索错误信息Bytes 第一个字节 /x08 替换为空。

github emoji

如果你希望在博客中支持 emoji 的话,你可以安装 hexo-filter-github-emojis

1
2
3
4
5
6
7
8
# Use Github Emojis
# Docs: https://github.com/crimx/hexo-filter-github-emojis
githubEmojis:
enable: true
className: github-emoji
unicode: false
styles:
localEmojis:

sitemap

为了让搜索引擎能找到我们的网站,我还需要给搜索引擎的网络蜘蛛提供站点地图文件

1
2
# hexo sitemap 生成器以及百度的 sitemap 生成器
npm install hexo-generator-sitemap hexo-generator-baidu-sitemap --save

依赖安装完后在站点配置文件中添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
# Expansion: hexo-generator-sitemap
# generate sitemap.
# https://github.com/hexojs/hexo-generator-sitemap
sitemap:
path: sitemap.xml

# Expansion: hexo-generator-baidu-sitemap
# 针对百度进行优化的 sitemap,作者还是建议手动提交至百度会比较好
# https://github.com/coneycode/hexo-generator-baidu-sitemap
baidusitemap:
path: baidusitemap.xml

设置无分页的归档

如果你期望将归档目录在一页中全部加载出来,那么你可以添加如下配置:

1
2
3
4
5
# hexo-generator-archive
# 该插件默认内置于 hexo 中,只需参考文档添加配置即可
# https://github.com/hexojs/hexo-generator-archive
archive_generator:
per_page: 0

图片的引入

hexo 中引用图片主要有两种方式:

  • 在本地通过资源文件夹引入
  • 使用图床

在本地资源的引入,需要修改 _config.yml 的配置:

1
post_asset_folder: true

设置完选项后,以后每次使用 hexo new [layout] <title> 后就会生成一个同名的文件夹。然后可以使用 `

` 来引入图片资源:
1
2
3
4
<!-- 例如插入一个 banner 图,hexo 会自动寻找同名文件夹下的文件 -->
{% asset_img banner.png banner %}

这里是一段示例内容。

该方法的缺点是需要占用本地资源,如果你是使用 git 进行部署,因为使 .git 文件变大(即便删除了该文件,它还会存在 git 的 commit 信息中)。

第二种方式可以使用图床,免费图床有个问题就是服务可能会不稳定,风险不由自己掌控,相对没那么保险。但是它能节省空间,甚至在网络传输上下载速度更快。如果使用图床的话,可以尝试新浪微博图床,将插件下载至 chrome,登录后即可上传得到相应的 url.

README

默认情况下,将源码生成部署至服务器会将上一次生成的数据覆盖掉。如果你期望在 github上保留一个 README.md 给读者看说明的话,可以通过 _config.yml 来设置它:

1
skip_render: ['images/loading.gif', 'README.md']

外链音乐播放器插件

网易云音乐提供了一个外链音乐播放器,可以插入博客中,样式以及播放的歌单都是通过url控制的。我们稍微封装一下,添加如下代码:

/next/_config.yml
1
2
3
4
5
6
7
8
9
10
11
12
# 网易云音乐插件
# 控制台: https://music.163.com/#/outchain/0/{% music.id %}/m/use/html
# 网易云音乐插件默认提供三种模式,不同模式设有不同宽高,样式也可能会略有不同。
# 如果你想调整默认的宽高的话,可以设置 width | height 覆盖原先 modal 的宽度
# modal: 1(310 X 430) | 2(310 X 90) | 3(278 | 32)
music:
enable: true
id: 102842761 # 网易云分享的ID
autoplay: false # 是否开启自动播放
modal: 2 # 模式, 默认为 modal 2
# width: 310 # 宽度, 默认为 modal 2
# height: 90 # 高度, 默认为 modal 2

添加 netease-cloud-music.swig 模板:

/next/layout/_partials/sidebar/netease-cloud-music.swig
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
{##
# extend layout: 网易云音乐外链播放器
# @author anran758
#}
{%- if theme.music and theme.music.enable %}
{# default size #}
{%- set music_model = theme.music.modal or 2 %}
{%- set music_width = 310 %}
{%- set music_height = 90 %}
{%- set music_padding = 20 %}

{# default config #}
{%- set music_id = theme.music.id or 102842761 %}
{%- set music_auto = 0 %}
{%- if theme.music.autoplay %}
{%- set music_auto = 1 %}
{%- endif %}

{%- if theme.music.width %}
{%- set music_width = theme.music.width %}
{%- elif music_model === 1 or music_model === 2 %}
{%- set music_width = 310 %}
{%- elif music_model === 3 %}
{%- set music_width = 278 %}
{%- endif %}

{%- if theme.music.height %}
{%- set music_height = theme.music.height %}
{%- elif music_model === 1 %}
{%- set music_height = 430 %}
{%- elif music_model === 2 %}
{%- set music_height = 90 %}
{%- elif music_model === 3 %}
{%- set music_height = 32 %}
{%- endif %}

<iframe
frameborder="no"
border="0"
marginwidth="0"
marginheight="0"
width="{{ music_width + music_padding}}"
height="{{ music_height + music_padding }}"
src="//music.163.com/outchain/player?type=0&id={{ music_id }}&auto={{ music_auto }}&height={{ music_height }}"
style="margin: 10px 0 50px;"
></iframe>
{%- endif %}

layout/_macro/sidebar.swig 中插入模板:

layout/_macro/sidebar.swig
1
2
3
4
5
6
7
8
<div class="site-overview-wrap sidebar-panel">
{{ partial('_partials/sidebar/site-overview.swig', {}, {cache: theme.cache.enable}) }}

<!-- 插入下列代码 -->
{{ partial('_partials/sidebar/netease-cloud-music.swig', {}, {cache: theme.cache.enable}) }}

{{- next_inject('sidebar') }}
</div>

不过值得注意的是,虽然插件能用,但由于博客渲染的是多页面,如果是跳到了别的页面,原先播放状态就会被破坏,从用户体验来看,这个功能并不太实用。


Hexo 的介绍就说到这里了,虽然还有一些技巧相关的内容,如果有读者感兴趣的话到时候再深入讲吧~

❌
❌