Hexo+Github搭建个人Wiki风格博客


介绍

以前一直不理解更新博客的用处,后来发现记录一些学到的东西和处理问题的经验对个人还是互联网都是有促进作用的(希望不是在生产互联网垃圾)。

所以本文会介绍一下个人搭建这个博客的过程。

后面博客有添加双主题的教程。

博客风格

  • 简洁(本来想弄点二次元风格的,但是博客还是减少点无用东西吧)(后来还是加了二次元主题来使用双主题
  • 多级分类:多级分类可以帮助来快速浏览学过的知识点
  • 标签:标签还是比较重要的,可以实习对相关博客的快速定位

主题选择

基于上述的需求,最终选择了Wikitten作为自己的博客主题

顺便放一下这个大佬的相关链接:

环境搭建

参考地址:使用 Hexo+GitHub 搭建个人免费博客教程(小白向) - 知乎 (zhihu.com)

  1. Github创建项目并取名为 用户名.github.io

  2. 使用 npm 一键安装 Hexo 博客程序

    npm install -g hexo-cli

  3. 准备一个空文件,进行hexo初始化:

    hexo init      # 初始化

  4. 使用npm安装package.json里面的依赖

    npm install

  5. 安装用于部署的包hexo-deployer-git

    npm install hexo-deployer-git --save

  6. 修改_config.yml文件末尾的Deployment部分

    deploy:
    type: git
    repository: git@github.com:用户名/用户名.github.io.git
    branch: master

公式

公式引擎有 mathjaxkatex两种,前者的功能多一点,后者则更加轻量化。可以根据自己的需要进行选择或者尝试后再做选择。

Mathjax

参考文章:Hexo显示Latex公式最新解决方案_hexo latex-CSDN博客

  1. 卸载部分插件

    npm un hexo-math
    npm un hexo-renderer-marked
  2. 安装hexo-renderer-pandoc渲染器

    npm i hexo-renderer-pandoc
    
  3. 配置主题配置下的mathjax设置(文件位置在 \themes\{主题名}\ _config.yml

    # MathJax
    mathjax:
      enable: true
      per_page: true
  4. 安装Pandoc

    去Pandoc官网下载最新版本pandoc:Pandoc - About pandoc (参考文章说 Anaconda自带的 pandoc可能会引起问题并且提供了解决方案,但是笔者使用的是 miniconda,没有遇到任何问题

Katex

参考文章:如何在 Butterfly 主题中使用 KaTeX 数学公式 | Proton's Blog

  1. 卸载部分插件(如果还装了什么其他的旧渲染器,也要一并卸载

    sudo npm un hexo-renderer-marked --save
  2. 安装 hexo-renderer-markdown-it-katex

    npm i hexo-renderer-markdown-it-katex
  3. 然后在hexo的博客文件 _config.yml里添加

    markdown:
      render:
        html: true
        xhtmlOut: false
        breaks: true
        linkify: true
        typographer: true
      plugins:
      anchors:
        level: 1
        collisionSuffix: ''

图片

参考文章:Hexo 引用本地图片以及引用本地任意位置图片的一点思路 | 养恐龙 (leay.net)

对于图片显示,hexo的原生设置较为冷门,hexo-asset-image等插件也提供了一定的解决方法,在博客文件同目录下设置个同名文件夹存放图片。但是笔者习惯使用 vscode编辑 markdown文章,而vscode默认在同目录下的 /image/{文件名}下存放图片文件。

笔者最后没有找到已有的较好的解决方案,于是写了个脚本文件进行处理(仅供参考)。

首先安装 hexo-asset-image插件,然后在 _config.yml里设置:

post_asset_folder: true  # 注意这个不能简单设置为false,否则插件hexo-asset-image会直接跳过(可以看看源码
marked:
  prependRoot: true
  postAsset: true

然后构建一个脚本文件在每次更新完后进行预处理,其中重要函数为

import os
import shutil
import re
from functools import partial

def move_directory(src, dst):
    """把src下所有内容复制到dst下,并删除src"""
    # 确保目标目录存在
    if not os.path.exists(dst):
        os.makedirs(dst)

    # 遍历源目录中的所有文件和子目录
    for item in os.listdir(src):
        s = os.path.join(src, item)
        d = os.path.join(dst, item)

        # 如果是目录,递归移动子目录
        if os.path.isdir(s):
            move_directory(s, d)
        else:
            # 移动文件,如果目标文件已存在,则跳过
            if not os.path.exists(d):
                shutil.copy(s, d)

    # 最后,删除空的源目录
    os.rmdir(src)


def img_url_replace(match, file_name):
    pattern = r"!\[(.*?)\]\((.*?)\)"
    name, old_link = re.findall(pattern, match.group(0))[0]
    if old_link.startswith("./{file_name}"):
        # 如果格式正确
        return match.group(0)
    if old_link.startswith("./"):
        old_link = old_link[2:]
    if old_link.startswith("image/"):
        old_link = old_link[6:]
    return f"![{name}](./{old_link})"


def remedy_image_path(md_file_path):
    """修改md文件中的图片路径"""
    with open(md_file_path, "r", encoding="utf-8") as f:
        text = f.read()
    img_patten = r"!\[.*?\]\((.*?)\)"
    file_name = os.path.basename(md_file_path).split(".")[0]
    # img_patten = r'!\[.*?\]\((.*?)\)|<img.*?src=[\'\"](.*?)[\'\"].*?>'
    updated_text, changed_num = re.subn(
        img_patten, partial(img_url_replace, file_name=file_name), text
    )
    if changed_num>0:
        with open(md_file_path, 'w', encoding='utf-8') as f:
            f.write(updated_text)

def process_md_file(file_path):
    """处理md文件"""
    # 如果不是md文件,返回
    if not file_path.endswith(".md"):
        return
    file_dir, file_name = os.path.split(file_path)
    # 如果没有需要处理的文件
    if not os.path.exists(os.path.join(file_dir, "image", file_name.split(".")[0])):
        return
    # 移动图片文件
    move_directory(
        src=os.path.join(file_dir,'image',file_name.split('.')[0]),
        dst=os.path.join(file_dir,file_name.split('.')[0])
    )
    # 修改连接
    remedy_image_path(file_path)


def dfs(dir):
    """dfs处理所有文件"""
    for root, dirs, files in os.walk(dir):
        for file in files:
            file = os.path.join(root, file)
            process_md_file(file)
        for sub_dir in dirs:
            sub_dir = os.path.join(root, sub_dir)
            dfs(sub_dir)

Hexo常用命令

hexo clean #清除生成的网页文件
hexo g     #生成静态网页
hexo s     #本地运行博客
hexo d     #将网页文件推送至远程服务器

Hexo常用文件夹

文件夹 备注
node_modules 依赖文件
.deploy_git 推送到远程的文件
public 生成的网页文件
themes 主题文件夹
scaffolds 博客模板文件夹
source 博客源文件

主题安装

Wikitten主题地址:https://github.com/zthxxx/hexo-theme-Wikitten/ 里面提供了双语详细的安装步骤,笔者使用的版本是 5b0d493

注意:里面有个可选步骤 配置mathjax渲染,笔者发现进行这个步骤后会出现生成网页文件失败的情况,跳过即可,并且暂时没发现有什么问题

评论系统giscus

由于不知名的原因,Gitment和Gitalk无法使用,选择了giscus来替代,参考Hexo静态博客使用giscus评论系统教程

1.打开自己的GitHub,选择博客所在仓库或可新建一个仓库

  • 确保仓库是公开的(新建的时候选择 private或者在仓库的 Settings - General,选择 change visibility - change to public)
  • 确保仓库开启了 Discussions(在仓库的 Settings - General,勾选 Discussions)
  • 确保安装了 giscus app

2.打开官方配置页面giscus,生成代码

  • 语言
  • 仓库:填写格式:你的用户名/你的仓库名
  • 页面 与 discussion 映射关系:由于本博客会分级,所以选择路径pathname
  • Discussion分类:General
  • 特性:按个人喜好即可,本博客加载了:启用主贴上的反应,将评论框放在评论上方,懒加载评论
  • 主题:选择与博客风格一致的主题

3.修改主题 _config.yml 在文件末尾添加

giscus:
  enable: true

方便以后直接从配置文件开关评论区

4.粘贴代码 网页会自动生成代码,复制粘贴到网页模板文件即可 不同主题的模板文件位置可能不同,wiki主题在 themes/Wikitten/layout/comment/giscus.ejs下添加代码 (然后检查同目录的引入giscus的文件:counter.ejsindex.ejsscripts.ejs,仿照之前代码添加引入)

<% if (theme.comment.giscus.enable) { %>
    <div id="giscus-container"></div>
    <script src="https://giscus.app/client.js"
            data-repo="<%= theme.comment.giscus.repo %>"
            data-repo-id="<%= theme.comment.giscus.repo_id %>"
            data-category="<%= theme.comment.giscus.category %>"
            data-category-id="<%= theme.comment.giscus.category_id %>"
            data-mapping="title"
            data-strict="0"
            data-reactions-enabled="1"
            data-emit-metadata="0"
            data-input-position="top"
            data-theme="<%= theme.comment.giscus.theme || 'light' %>"
            data-lang="<%= theme.comment.giscus.lang || 'zh-CN' %>"
            data-loading="lazy"
            crossorigin="anonymous"
            async>
    </script>
    <noscript>请启用 JavaScript 以查看评论。</noscript>
    <% } %>

然后修改 themes/Wikitten/layout/common/article.ejs文件,把

<% if (!index) { %>
    <%- partial('comment/index') %>
<% } %>

移动到

<footer class="article-footer">
</footer>

前面,两个代码块在同一个 div内。

然后在 themes/Wikitten/_config.yml内修改:

comment:
    disqus: # enter disqus shortname here
    duoshuo: # enter duoshuo shortname here
    youyan: # enter youyan uid here
    giscus:
        enable: true
        repo: ''  # 添加
        repo_id: ''  # 添加
        category: 'General'
        category_id: ''  # 添加
        theme: 'light'
        lang: 'zh-CN'

对于不同的主题添加的方式可能不同

常见QA

  1. 修改配置文件应该修改站点的 _config.yml 还是主题的 _config.yml?

    具体使用哪个,要看主题的源代码,如果是 config.xxx那就是用的根目录配置文件,如果是 theme.xxx那就用的是主题目录的配置文件。

  2. 怎么让自己的博客可以被常用搜索引擎搜索到?

    很多搜索引擎可以在搜索框里用 site:网址来判断是否被收录 Google

    1. 打开Google搜索,搜索“Google Search Console”
    2. 根据提示登录你的Google账号
    3. 选择资源类型
    4. 选择验证方式(本博客用的是HTML标记,把对应代码添加到主题文件里面,本主题是 themes/Wikitten/layout/common/head.ejs)
    5. 在Google Search Console后台添加站点地图

参考资料


文章作者: bg51717
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 bg51717 !
由于评论系统依托于Github的Discuss存在,因此默认评论者会收到所有通知。可以在邮件里点击"unsubscribe"停止接受,后续也可以点击下列仓库进行通知管理: bg51717/Hexo-Blogs-comments
Since the comment system relies on GitHub's Discussions feature, by default, commentators will receive all notifications. You can click "unsubscribe" in the email to stop receiving them, and you can also manage your notifications by clicking on the following repositories: bg51717/Hexo-Blogs-comments
  目录