基于Hexo的matery主题搭建博客并深度优化


All in one 一站式Hexo配置优化教程!

如果你遇到了什么问题,搜索本文,你很可能有收获! CtRL + F

Hexo入门

Docker 版 hexo 环境一键部署

博主开源定制,推荐使用!省去您大量环境配置时间。

使用推荐Docker来搭配本文,阅读使用,将更省事,方便,快捷。hexo环境一键搞定!

Docker一键安装

docker create --name=hexo \
-e HEXO_SERVER_PORT=4000 \
-e GIT_USER="17lai" \
-e GIT_EMAIL="17lai@domain.tld" \
-v /mnt/blog.17lai.site:/app \
-p 4000:4000 \
bloodstar/hexo

ssh key 部署

Docker会自动随机生成ssh key 在 /app/.ssh 目录下面。自动部署请把ssh key添加到github 等平台。

Github详细教程

  1. SSH 公钥复制到剪贴板。 …
  2. 在任何页面的右上角,单击您的个人资料照片,然后单击Settings(设置)。
  3. 在用户设置侧边栏中,单击SSH and GPG keys(SSH 和GPG 密钥)。
  4. 单击New SSH key(新SSH 密钥)或Add SSH key(添加SSH 密钥)。

进入docker

docker exec -it hexo bash

然后就可以正常运行hexo的各种命令了,是不是非常简单? 快来试试吧。

用户自动运行脚本

用户可以在这里添加自动配置,自动安装插件,等各种启动docker运行的命令。

vi /app/useRun.sh

Hexo 通用简明教程

Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。

前提

安装 Hexo 相当简单,只需要先安装下列应用程序即可:

  • Node.js (Node.js 版本需不低于 8.10,建议使用 Node.js 10.0 及以上版本)
  • Git
  • nmp

安装

所有必备的应用程序安装完成后,即可使用 npm 安装 Hexo。

npm install -g hexo-cli

安装以后,可以使用以下两种方式执行 Hexo:

  1. npx hexo
  2. 将 Hexo 所在的目录下的 node_modules 添加到环境变量之中即可直接使用: hexo
echo 'PATH="$PATH:./node_modules/.bin"' >> ~/.profile

安装淘宝镜像, 加NPM

npm config set registry https://registry.npm.taobao.org

安装CNPM

npm install -g cnpm --registry=https://registry.npm.taobao.org

升级

后期需要升级的化,进入 blog 目录,先检查更新:

$ npm outdated
Package                  Current  Wanted  Latest  Location
hexo                       3.9.0   3.9.0   4.2.0  hexo-site
hexo-deployer-git          1.0.0   1.0.0   2.1.0  hexo-site
hexo-generator-archive     0.1.5   0.1.5   1.0.0  hexo-site
hexo-generator-category    0.1.3   0.1.3   1.0.0  hexo-site
hexo-generator-feed        1.2.2   1.2.2   2.2.0  hexo-site
hexo-generator-index       0.2.1   0.2.1   1.0.0  hexo-site
hexo-generator-tag         0.2.0   0.2.0   1.0.0  hexo-site
hexo-renderer-ejs          0.3.1   0.3.1   1.0.0  hexo-site
hexo-renderer-marked       0.3.2   0.3.2   2.0.0  hexo-site
hexo-renderer-stylus       0.3.3   0.3.3   1.1.0  hexo-site
hexo-server                0.3.3   0.3.3   1.0.0  hexo-site

修改 package.json 文件,基于 Latest 列内容更新版本号,然后更新并检查版本号:

$ npm install --save

# 检查版本号
$ hexo -v
hexo: 4.2.0
hexo-cli: 3.1.0
......

建站

安装 Hexo 完成后,请执行下列命令,Hexo 将会在指定文件夹中新建所需要的文件。

hexo init <folder>
cd <folder>
npm install

启动网页服务

此时,通过 hexo s 命令即可在本地启动您的博客站点了。

$ hexo s
INFO  Start processing
INFO  Hexo is running at http://localhost:4000 . Press Ctrl+C to stop.

接下来将安装主题,配置博客托管平台,实现一键发布并刷新 CDN 缓存。

hexo目录结构说明

在执行过Hexo deploy命令之后,目录结构新增了.deploy_gitpublic.gitignore,如下:

 $ tree -L 2
.
├── .deploy_git
├── node_modules
├── public
├── scaffolds
│   ├── draft.md
│   ├── page.md
│   └── post.md
├── source
│   ├── _posts
│   ├── _drafts
├── themes
├── _config.yml
├── db.json
├── package.json
└── package-lock.json
_config.yml

用来配置博客相关的参数,初始化时自动创建。具体参数设置,可参照 Hexo 配置 文档。

node_modules 和 package.json

都是在初始化时自动创建。

  • node_modules用来存储已安装的各类依赖包。
  • package.json用来查看 Hexo 的版本以及相关依赖包的版本。

Hexo 会默认安装:

  • hexo:主程序
  • hexo-deployer-git:实现 git 部署方式
  • hexo-generator-archive:存档页面生成器
  • hexo-generator-category:分类页面生成器
  • hexo-generator-index:index 生成器
  • hexo-generator-tag:标签页面生成器
  • hexo-renderer-ejs:支持 EJS 渲染
  • hexo-renderer-marked:Markdown 引擎
  • hexo-renderer-stylus:支持 stylus 渲染
  • hexo-server:支持本地预览,默认地址 localhost:4000

新安装的依赖包,也会保存在node_module文件夹下。

scaffold

模板文件夹,初始化时自动创建。包含pagepostdraft三种模板,分别对应 页面、要发布的文章、草稿。

themes

主题文件夹,初始化时自动创建。每一个主题,都有一个单独的文件夹。默认主题为 landscape

source , public 和 .deploy_git
  • source:资源文件夹。用来存放图片、Markdown 文档(文章、草稿)、各种页面(分类、关于页面等)。
  • public:将 source 文件夹里的 Markdown 文档,转换成 index.html。再结合主题进行渲染,就是我们最终看到的博客。
  • .deploy_git:将 public 文件夹的内容提交到 Github 后生成,内容与 public 文件夹基本一致。

这三者的关系大致是:source -> public -> .deploy_git

  • 执行hexo generate,根据 source,更新 public。
  • 执行hexo deploy,根据 public,更新 .deploy_git。

常用命令

指令说明

  • hexo server #启动本地服务器,用于预览主题。Hexo 会监视文件变动并自动更新,除修改站点配置文件外,无须重启服务器,直接刷新网页即可生效。

  • hexo server -s #以静态模式启动

  • hexo server -p 5000 #更改访问端口 (默认端口为 4000,’ctrl + c’关闭 server)

  • hexo server -i IP地址 #自定义 IP

  • hexo clean #清除缓存 ,网页正常情况下可以忽略此条命令,执行该指令后,会删掉站点根目录下的 public 文件夹

  • hexo g #生成静态网页 (执行 $ hexo g后会在站点根目录下生成 public 文件夹, hexo 会将”/blog/source/“ 下面的.md 后缀的文件编译为.html 后缀的文件,存放在”/blog/public/ “ 路径下)

  • hexo d #自动生成网站静态文件,并将本地数据部署到设定的仓库(如 github)

  • hexo init 文件夹名称 #初始化 XX 文件夹名称

  • npm update hexo -g#升级

  • npm install hexo -g #安装

  • node-v #查看 node.js 版本号

  • npm -v #查看 npm 版本号

  • git --version #查看 git 版本号

  • hexo -v #查看 hexo 版本号

简写指令

hexo n "我的第一篇文章"` 等价于 `hexo new "我的第一篇文章"` 还等价于 `hexo new post "我的第一篇文章"
hexo p` 等价于 `hexo publish
hexo g` 等价于 `hexo generate
hexo s`等价于 `hexo server
hexo d` 等价于 `hexo deploy
hexo g -d`等价于`hexo generate --deploy

注: hexo clean 没有 简写, git --version 没有简写

Hexo基础配置

下载主题

hexo-theme-matery 是一个采用 Material Design 和响应式设计的 Hexo 博客主题,点击 这里 可以查看示例效果。点击 这里 下载 master 分支的最新稳定版的代码,解压缩后,将 hexo-theme-matery 的文件夹复制到 Hexo 的 themes 文件夹中即可。

Docker环境命令

git clone https://github.com/blinkfox/hexo-theme-matery.git /app/themes/matery; 

切换主题

修改 Hexo 根目录下的 _config.ymltheme 的值:theme: hexo-theme-matery

_config.yml 文件的其它修改建议

  • 请修改 _config.ymlurl 的值为你的网站主 URL(如:http://xxx.github.io)。
  • 建议修改两个 per_page 的分页条数值为 6 的倍数,如:1218 等,这样文章列表在各个屏幕下都能较好的显示。
  • 如果是中文用户,则建议修改 language 的值为 zh-CN

新建主题必备about、tags、404等页面

新建分类 categories 页

categories 页是用来展示所有分类的页面,如果 source 目录下还没有 categories/index.md 文件,那么就需要新建一个,命令如下:

hexo new page "categories"

编辑你刚刚新建的页面文件 /source/categories/index.md,至少需要以下内容:

---
title: categories
date: 2018-09-30 17:25:30
type: "categories"
layout: "categories"
---

新建标签 tags 页

tags 页是用来展示所有标签的页面,如果 source 目录下还没有 tags/index.md 文件,那么就需要新建一个,命令如下:

hexo new page "tags"

编辑刚刚新建的页面文件 /source/tags/index.md,至少需要以下内容:

---
title: tags
date: 2018-09-30 18:23:38
type: "tags"
layout: "tags"
---

新建留言板 contact 页

contact 页是用来展示留言板信息的页面,如果在你的博客 source 目录下还没有 contact/index.md 文件,那么你就需要新建一个,命令如下:

hexo new page "contact"

编辑你刚刚新建的页面文件 /source/contact/index.md,至少需要以下内容:

---
title: contact
date: 2018-09-30 17:25:30
type: "contact"
layout: "contact"
---

:本留言板功能依赖于第三方评论系统,请激活你的评论系统才有效果。并且在主题的 _config.yml 文件中,第 1921 行的“菜单”配置,取消关于留言板的注释即可。

新建友情链接 friends 页

friends 页是用来展示友情链接信息的页面,如果在你的博客 source 目录下还没有 friends/index.md 文件,那么你就需要新建一个,命令如下:

hexo new page "friends"

编辑你刚刚新建的页面文件 /source/friends/index.md,至少需要以下内容:

---
title: friends
date: 2018-12-12 21:25:30
type: "friends"
layout: "friends"
---

同时,在你的博客 source 目录下新建 _data 目录,在 _data 目录中新建 friends.json 文件,文件内容如下所示:

[{
    "avatar": "https://blog.17lai.site/favicon.png",
    "name": "夜法之书的Blog",
    "introduction": "嵌入式,Linux Kernel&Driver, PT, Docker, Nas等等",
    "url": "https://blog.17lai.site",
    "title": "前去学习"
},{
    "avatar": "http://image.luokangyuan.com/1_qq_27922023.jpg",
    "name": "码酱",
    "introduction": "我不是大佬,只是在追寻大佬的脚步",
    "url": "http://luokangyuan.com/",
    "title": "前去学习"
}, {
    "avatar": "http://image.luokangyuan.com/4027734.jpeg",
    "name": "闪烁之狐",
    "introduction": "编程界大佬,技术牛,人还特别好,不懂的都可以请教大佬",
    "url": "https://blinkfox.github.io/",
    "title": "前去学习"
}, {
    "avatar": "http://image.luokangyuan.com/avatar.jpg",
    "name": "ja_rome",
    "introduction": "平凡的脚步也可以走出伟大的行程",
    "url": "https://me.csdn.net/jlh912008548",
    "title": "前去学习"
}]

新建关于我 about 页

about 页是用来展示关于我和我的博客信息的页面,如果 source 目录下还没有 about/index.md 文件,那么就需要新建一个,命令如下:

hexo new page "about"

编辑刚刚新建的页面文件 /source/about/index.md,至少需要以下内容:

---
title: about
date: 2018-09-30 17:25:30
type: "about"
layout: "about"
---

新建404页

新建一个404.md文件

  在hexo的souce文件夹下创建一个404.md,之后输入如下内容:

---
title: 404
date: 2019-11-23 21:10:10
type: "404"
layout: "404"
---

新建404.md

然后hexo g生成页面中就有404。只是页面较丑。

404页面美化

下载404特效

点击下载代码:点我去代码出处

移植
放入js文件到主题中

  将下载的压缩包解压,会发现里面有两个js文件和一个html页面,重要的就是js文件,将文件移植到主题的source文件的libs文件夹下,需要自己创建一个文件夹,我给文件夹取的名字叫做404。

导入404 js

因为该主题的js文件都是写_config.yml文件里面的,为了规范,也需要将文件的路径写到该文件夹下

如下,之后导入js文件的时候就可以使用404bodymovin和404data来代替了

修改主题_config.yml文件

编辑404.esj
<style type="text/css">
    /* don't remove. */
    .page404-cover {
        /* height: 75vh; */
        height: 88vh;
    }
 
    #svgContainer {
      width: 100%;
      height: 100%;
      background-color: white;
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      margin: auto;
    }
</style>
 
 
<script src="<%- theme.libs.js.my404bodymovin %>"></script>
<script src="<%- theme.libs.js.my404data %>"></script>
 
<div class="bg-cover pd-header page404-cover">
    <div id="svgContainer"></div>
 
    <script type="text/javascript">
        var svgContainer = document.getElementById('svgContainer');
        var animItem = bodymovin.loadAnimation({
          wrapper: svgContainer,
          animType: 'svg',
          loop: true,
          animationData: JSON.parse(animationData)
        });
    </script>
</div>

现在就移植成功了,使用下面命令上传,之后输入一个错误的页面就可以查看到了

hexo cl && hexo g -d

Tips: 不要再本地试验,本地的时候输入错误的页面不会显示404页面的。

新建友情连接 friends 页(可选的)

friends 页是用来展示友情连接信息的页面,如果 source 目录下还没有 friends/index.md 文件,那么就需要新建一个,命令如下:

hexo new page "friends"

编辑刚刚新建的页面文件 /source/friends/index.md,至少需要以下内容:

---
title: friends
date: 2018-12-12 21:25:30
type: "friends"
layout: "friends"
---

同时,在 source 目录下新建 _data 目录,在 _data 目录中新建 friends.json 文件,文件内容如下所示:

[
  {
    "avatar": "https://www.lixl.cn/medias/avatar.jpg",
    "name": "悟尘记",
    "introduction": "人生就是一场修行,上善若水,厚德载物。",
    "url": "https://www.lixl.cn/",
    "title": "前去参观"
  },
  {
    "avatar": "https://wiki.hyperledger.org/download/attachments/2392069/fabric?version=1&modificationDate=1540928132000&api=v2",
    "name": "Fabric",
    "introduction": "A Blockchain Platform for the Enterprise",
    "url": "https://hyperledger-fabric.readthedocs.io/en/master/",
    "title": "前去学习"
  },
  {
    "avatar": "https://www.bootcdn.cn/assets/img/maoyun.svg",
    "name": "BootCDN",
    "introduction": "稳定、快速、免费的前端开源项目 CDN 加速服务。",
    "url": "https://www.bootcdn.cn/",
    "title": "前去加速"
  }
]

菜单导航配置

配置基本菜单导航的名称、路径url和图标icon.

  • 1.菜单导航名称可以是中文也可以是英文(如:Index主页)
  • 2.图标icon 可以在Font Awesome 中查找
menu:
  Index:
    url: /
    icon: fas fa-home
  Tags:
    url: /tags
    icon: fas fa-tags
  Categories:
    url: /categories
    icon: fas fa-bookmark
  Archives:
    url: /archives
    icon: fas fa-archive
  About:
    url: /about
    icon: fas fa-user-circle
  Friends:
    url: /friends
    icon: fas fa-address-book

二级菜单配置方法

如果你需要二级菜单则可以在原基本菜单导航的基础上如下操作

  1. 在需要添加二级菜单的一级菜单下添加children关键字(如:About菜单下添加children)
  2. children下创建二级菜单的 名称name,路径url和图标icon.
  3. 注意每个二级菜单模块前要加 -.
  4. 注意缩进格式
menu:
  Index:
    url: /
    icon: fas fa-home
  Tags:
    url: /tags
    icon: fas fa-tags
  Categories:
    url: /categories
    icon: fas fa-bookmark
  Archives:
    url: /archives
    icon: fas fa-archive
  About:
    url: /about
    icon: fas fa-user-circle-o
  Friends:
    url: /friends
    icon: fas fa-address-book
  Medias:
    icon: fas fa-list
    children:
      - name: Music
        url: /music
        icon: fas fa-music
      - name: Movies
        url: /movies
        icon: fas fa-film
      - name: Books
        url: /books
        icon: fas fa-book
      - name: Galleries
        url: /galleries
        icon: fas fa-image

文章 Front-matter 介绍

Front-matter 选项详解

Front-matter 选项中的所有内容均为非必填的。但仍然建议至少填写 titledate 的值。

配置选项 默认值 描述
title Markdown 的文件标题 文章标题,强烈建议填写此选项
date 文件创建时的日期时间 发布时间,强烈建议填写此选项,且最好保证全局唯一
author _config.yml 中的 author 文章作者
img featureImages 中的某个值 文章特征图,推荐使用图床(腾讯云、七牛云、又拍云等)来做图片的路径.如: http://xxx.com/xxx.jpg
top true 推荐文章(文章是否置顶),如果 top 值为 true,则会作为首页推荐文章
hide false 隐藏文章,如果hide值为true,则文章不会在首页显示
cover false v1.0.2版本新增,表示该文章是否需要加入到首页轮播封面中
coverImg v1.0.2版本新增,表示该文章在首页轮播封面需要显示的图片路径,如果没有,则默认使用文章的特色图片
password 文章阅读密码,如果要对文章设置阅读验证密码的话,就可以设置 password 的值,该值必须是用 SHA256 加密后的密码,防止被他人识破。前提是在主题的 config.yml 中激活了 verifyPassword 选项
toc true 是否开启 TOC,可以针对某篇文章单独关闭 TOC 的功能。前提是在主题的 config.yml 中激活了 toc 选项
mathjax false 是否开启数学公式支持 ,本文章是否开启 mathjax,且需要在主题的 _config.yml 文件中也需要开启才行
summary 文章摘要,自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要
categories 文章分类,本主题的分类表示宏观上大的分类,只建议一篇文章一个分类
tags 文章标签,一篇文章可以多个标签
keywords 文章标题 文章关键字,SEO 时需要
reprintPolicy cc_by 文章转载规则, 可以是 cc_by, cc_by_nd, cc_by_sa, cc_by_nc, cc_by_nc_nd, cc_by_nc_sa, cc0, noreprint 或 pay 中的一个

注意:

  1. 如果 img 属性不填写的话,文章特色图会根据文章标题的 hashcode 的值取余,然后选取主题中对应的特色图片,从而达到让所有文章都的特色图各有特色
  2. date 的值尽量保证每篇文章是唯一的,因为本主题中 GitalkGitment 识别 id 是通过 date 的值来作为唯一标识的。
  3. 如果要对文章设置阅读验证密码的功能,不仅要在 Front-matter 中设置采用了 SHA256 加密的 password 的值,还需要在主题的 _config.yml 中激活了配置。有些在线的 SHA256 加密的地址,可供使用:开源中国在线工具chahuo站长工具

以下为文章的 Front-matter 示例。

最简示例

---
title: 基于Hexo的hexo-theme-matery主题搭建博客并优化
date: 2019-10-03 14:25:00
---

最全示例

---
title: 基于Hexo的hexo-theme-matery主题搭建博客并优化
date: 2019-12-30 09:25:00
author: 17lai.site
img: /medias/cover/hexo.jpg
top: true
cover: true
coverImg: /medias/cover/hexo.jpg
password: 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
toc: false
mathjax: false
summary: 这是你自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要
categories: Hexo
keywords: Hexo GitHub blog
tags:
  - Hexo
  - Blog
  - GitHub
---

新建文章模板修改

首先为了新建文章方便,我们可以修改一下文章模板,建议将/scaffolds/post.md修改为如下代码:

---
title: {{ title }}
date: {{ date }}
author: 
img: 
coverImg: 
top: false
cover: false
toc: true
mathjax: false
password:
summary:
tags:
categories:
---

这样新建文章后 一些Front-matter参数不用你自己补充了,修改对应信息就可以了。

代码高亮

由于 Hexo 自带的代码高亮主题显示不好看,所以主题中使用到了 hexo-prism-plugin 的 Hexo 插件来做代码高亮,安装命令如下:

npm i -S hexo-prism-plugin

然后,修改 Hexo 根目录下 _config.yml 文件中 highlight.enable 的值为 false,并新增 prism 插件相关的配置,主要配置如下:

highlight:
  enable: false

prism_plugin:
  mode: "preprocess" # realtime/preprocess
  theme: "tomorrow"
  line_number: false # default false
  custom_css:

添加文章搜索功能

本主题中还使用到了 hexo-generator-search 的 Hexo 插件来做内容搜索,安装命令如下:

npm install hexo-generator-search --save

在 Hexo 根目录下的 _config.yml 文件中,新增以下的配置项:

search:
  path: search.xml
  field: post

修改页脚

页脚信息可能需要做定制化修改,而且它不便于做成配置信息,所以可能需要你自己去再修改和加工。修改的地方在主题文件的 /layout/_partial/footer.ejs 文件中,包括站点、使用的主题、访问量等。

修改社交链接

在主题的 _config.yml 文件中,默认支持 QQGitHub 和邮箱的配置,可以在主题文件的 /layout/_partial/social-link.ejs 文件中,新增、修改需要的社交链接地址,增加链接可参考如下代码:

<a
  href="https://github.com/blinkfox"
  class="tooltipped"
  target="_blank"
  data-tooltip="访问我的GitHub"
  data-position="top"
  data-delay="50"
>
  <i class="fa fa-github"></i>
</a>

其中,社交图标(如:fa-github)可以在 Font Awesome 中搜索找到。以下是常用社交图标的标识,供参考:

  • Facebook: fa-facebook
  • Twitter: fa-twitter
  • Google-plus: fa-google-plus
  • Linkedin: fa-linkedin
  • Tumblr: fa-tumblr
  • Medium: fa-medium
  • Slack: fa-slack
  • 新浪微博: fa-weibo
  • 微信: fa-wechat
  • QQ: fa-qq

修改打赏的二维码图片

在主题文件的 source/medias/reward 文件中,可以替换成你的的微信和支付宝的打赏二维码图片。

配置文章基本信息

new_post_name: :title.md   # 新文章的文件名称
default_layout: post       # 预设布局
auto_spacing: false        # 在中文和英文之间加入空格
titlecase: false           # 把标题转换为 title case
external_link:             # 在新标签中打开链接
  enable: true             # 在新标签中打开链接
  field:                   # 对整个网站(site)生效或仅对文章(post)生效
  exclude:                 # 需要排除的域名。主域名和子域名如 www 需分别配置	[]
filename_case: 0           # 把文件名称转换为 (1) 小写或 (2) 大写
render_drafts: false       # 显示草稿,默认为:false
post_asset_folder: true    # 启动 Asset 文件夹
relative_link: false       # 把链接改为与根目录的相对位址
future: true               # 显示未来的文章
highlight:                 # 代码块的设置
  enable: false            # 开启代码块高亮
  line_number: false       # 显示行数
  auto_detect: false       # 如果未指定语言,则启用自动检测
  tab_replace:             # 用 n 个空格替换 tabs;如果值为空,则不会替换 tabs

配置代码高亮及样式

highlight:                      # 代码块的设置
  enable: false                 # 开启代码块高亮
  line_number: true             # 显示行数
  auto_detect: false            # 如果未指定语言,则启用自动检测
  tab_replace: ''               # 用 n 个空格替换 tabs;如果值为空,则不会替换 tabs
  wrap: true
  hljs: false
prismjs:
  enable: true
  preprocess: true
  line_number: true
  tab_replace: ''

配置代码的样式

code:
  lang: true     # 代码块是否显示名称
  copy: true     # 代码块是否可复制
  shrink: false  # 代码块是否可以收缩
  break: false   # 代码是否折行

配置是否启用转载限制模块

reprint:
  enable: false   #是否启用“转载规则限定模块”
  default: cc_by

文章转载规则,可以是 cc_by, cc_by_nd, cc_by_sa, cc_by_nc, cc_by_nc_nd, cc_by_nc_sa, cc0, noreprintpay 中的一个

配置文章阅读密码功能

阅读文章的密码验证功能,如要使用此功能请激活该配置项,并在对应文章的 Front-matter 中写上 password 的键和加密后的密文即可。

请注意:为了保证密码原文不会被泄露到网页中,文章的密码必须是通过 SHA256 加密的,这样就不会被破解。

verifyPassword:
  enable: true
  promptMessage: 请输入访问本文章的密码
  errorMessage:  密码错误,将返回主页!

如何一键部署hexo

通过 hexo-deployer-git 插件可以实现一键将博客同时部署到多个 git 仓库中。如同时发布到 github 及 gitee 提供的 pages 服务。安装:

npm install hexo-deployer-git --save

修改 Hexo 根目录下的 _config.yml 文件中的如下内容:

## Docs: https://hexo.io/docs/deployment.html
deploy:
  - type: git
    repo: https://github.com/lxl80/blog.git
    branch: gh-pages
    ignore_hidden: false
  - type: git
    repo: https://gitee.com/lxl80/lxl80.git
    branch: master
    ignore_hidden: false

也可以如本站一样,采用 hexo-deployer-cos-enhanced 插件将静态内容部署到腾讯云对象存储服务中,在 DNS 配置中将境内线路解析到腾讯云 CDN 地址,实现加速。部署完成后会自动刷新被更新文件的 CDN 缓存。

安装:

npm install hexo-deployer-cos-enhanced --save

_config.yml 配置如下:

deploy:
  - type: git
    repo: https://github.com/lxl80/blog.git
    branch: gh-pages
    ignore_hidden: false
  - type: cos
    bucket: lxl80-130****
    region: ap-beijing
    secretId: AKIDh9****F8FvL
    secretKey: Z3IGiur****QZR3PgjXmlVg
    cdnConfig:
      enable: true
      cdnUrl: https://static.lixl.cn
      bucket: static-130****
      region: ap-beijing
      folder: static
      secretId: AKIDh9****F8FvL
      secretKey: Z3IGiur****QZR3PgjXmlVg

然后通过 hexo g -d 即可实现一键发布,并更新 CDN 缓存。

文章链接转静态短地址(可选的)

如果文章名称是中文的,那么 Hexo 默认生成的永久链接也会有中文,这样不利于 SEO,且 gitment 评论对中文链接也不支持。我们可以用 hexo-permalink-pinyin Hexo 插件生成文章时生成中文拼音的永久链接,或者用hexo-abbrlink 生成静态文章链接。以下结合 hexo-abbrlink 生成类似 /yyyy/mmdd+随机数.html 的文章链接地址。

安装命令如下:

npm install hexo-abbrlink --save

在 Hexo 根目录下的 _config.yml 文件中,修改 permalink: ,并在文件末尾新增 abbrlink:配置项:

permalink: :year/:month:day:abbrlink.html

abbrlink:
  alg: crc16 #算法选项:crc16丨crc32
  rep: dec #输出进制:dec为十进制,hex为十六进制

添加 emoji 表情支持(可选的)

Matery主题新增了对 emoji 表情的支持,使用到了 hexo-filter-github-emojis 的 Hexo 插件来支持 emoji 表情的生成,把对应的 markdown emoji 语法(::, 例如::smile:)转变成会跳跃的 emoji 表情,安装命令如下

npm install hexo-filter-github-emojis --save

在 博客根目录下的 _config.yml 文件中,新增以下的配置项:

githubEmojis:
  enable: true
  className: github-emoji
  inject: true
  styles:
  customEmojis:

执行 hexo clean && hexo g 重新生成博客文件,然后就可以在文章中对应位置看到你用 emoji 语法写的表情了。

文章字数统计插件

如果你想要在文章中显示文章字数、阅读时长信息,可以安装 hexo-wordcount插件。

安装命令如下:

npm i --save hexo-wordcount

然后只需在本主题下的 _config.yml 文件中,激活以下配置项即可:

wordCount:
  enable: false # 将这个值设置为 true 即可.
  postWordCount: true
  min2read: true
  totalCount: true

添加 RSS 订阅支持

本主题中还使用到了 hexo-generator-feed 的 Hexo 插件来做 RSS,安装命令如下:

npm install hexo-generator-feed --save

在 Hexo 根目录下的 _config.yml 文件中,新增以下的配置项:

feed:
  type: atom
  path: atom.xml
  limit: 20
  hub:
  content:
  content_limit: 140
  content_limit_delim: " "
  order_by: -date

执行 hexo clean && hexo g 重新生成博客文件,然后在 public 文件夹中即可看到 atom.xml 文件,说明已经安装成功了。

增加百度统计功能

首先注册百度统计站长版,登陆后点击 新增网站,然后直接输入你的博客地址例如: https://blog.17lai.site,网站域名 和 网站首页 都写这个,网站名称 可以填 我的博客,
行业类别: 博客—空间周边。

然后点击左侧菜单的 代码获取,找到

hm.src = "https://hm.baidu.com/hm.js?……"

问号后的这一段十六进制代码
复制下来,粘贴到 主题配置文件 中的baidu_analytics:后面,注意冒号和值之间要有一个空格,然后将该字段前面的#号删除代表启用此功能。保存后即可

# Add baidu analytics configuration
# 添加 baidu Analytics 配置
baiduAnalytics:
  enable: false
  id: f614xxxxxxxxxxxxxxxx05d25e

Leancloud+Valine打造Hexo个人博客极简评论系统

Leancloud配置

首先访问Leancloud官网https://leancloud.cn/
有Github账号的小伙伴可以用Github账号进行登陆然后绑定邮箱就可以啦!
进入之后点击创建应用

这样我们就创建好啦!

接着点击应用右上角的设置进入设置界面

选择应用key,这样就可以看到我们接下来需要使用到的key

接着进入应用中心绑定你的个人博客域名

Valine配置

然后我们去主题配置文件中进行修改
主题配置文件路径:matery_config.yml
找到以下参数进行修改

# Valine.
# You can get your appid and appkey from https://leancloud.cn
# more info please open https://valine.js.org
valine:
  enable: true //打开valine评论功能
  appid: 你的leancloud appid 
  appkey: 你的leancloud appkey 
  notify: false //邮件提醒
  verify: true //评论时是否有验证码,需要在Leancloud 设置->安全中心 中打开
  placeholder: 说点什么吧! //评论框默认显示
  avatar: hide //评论者的头像,我这里设置的不显示
  guest_info: nick # custom comment header
  pageSize: 10 # pagination size

PS:评论者头像可以进行如下设置

到此,一个极简评论系统就完成啦!

自定制修改

在本主题的 _config.yml 中可以修改部分自定义信息,有以下几个部分:

  • 菜单
  • 我的梦想
  • 首页的音乐播放器和视频播放器配置
  • 是否显示推荐文章名称和按钮配置
  • faviconLogo
  • 个人信息
  • TOC 目录
  • 文章打赏信息
  • 复制文章内容时追加版权信息
  • MathJax
  • 文章字数统计、阅读时长
  • 点击页面的’爱心’效果
  • 我的项目
  • 我的技能
  • 我的相册
  • GitalkGitmentValinedisqus 评论配置
  • 不蒜子统计和谷歌分析(Google Analytics
  • 默认特色图的集合。当文章没有设置特色图时,本主题会根据文章标题的 hashcode 值取余,来选择展示对应的特色图

如果本主题中的诸多功能和主题色彩你不满意,可以在主题中自定义修改,很多更自由的功能和细节点的修改难以在主题的 _config.yml 中完成,需要修改源代码才来完成。以下列出了可能有用的地方:

更换字体

一般网站的web字体都可以直接从Google-Font获取资源,这样不用担心字体商业带来的法律问题。

常见的开源字体有:

思源黑体 、 文泉驿 、 文鼎开放字体 、 柳体 、 cwTeX中文字体 、 濑户字体、江西拙楷体等。

1)创建web字体引用

@font-face{
    font-family: '引用的字体名称';
    src: url('谷歌字体路径(或者其他什么字体引用)');   
}

2)在网页合适的位置进行字体引用

①利用浏览器检查元素,获取需要定义字体的部分

②在主体的配置文件中(hexo-theme-matery/layout/…)找到对应的渲染(.ejs)文件,查找需要修改的部分

①演示一下利用浏览器获取定义字体的部分

对获取到的id选择器:#artDetail进行css渲染

#artDetail {
    font-family: '引用的web字体';
}

②利用主体的ejs渲染文件找出需要修饰的部分(加入自定义类)

/*使用我在文章内容详情定义的diyFnot类**/
.diyfont {
   font-family: '引用的web字体'; 
}

/*也可以使用自带的id*/
#artDetail {
    font-family: '引用的web字体'; 
}

网站全局化字体定义

@font-face{
    font-family: '引用的字体名称';
    src: url('谷歌字体路径(或者其他什么字体引用)');   
}

body {
    font-family: '引用的web字体名称'; 
}

引用本地的字体文件

当然有时候那个谷歌字体的网站可能登录不上去,需要科学上网,很烦人!我们也可以直接下载下字体文件,将他放在本地,进行直接引用!看下面操作👇

①在本地的hexo根目录的source文件下创立diy-font文件夹:/source/diy-font

在该文件下存放你的字体文件,比如:/source/diy-font/IBMPlexMono-Italic.ttf

②引用本地字体(仍然是在my.css文件中书写代码)

@font-face{
    font-family: 'hl';
    src: url('../diy-font/IBMPlexMono-Italic.ttf');
}

/** 表示全局使用,如果不想全局使用不要添加该段 */
body{
    font-family: 'hl';
}


/* 可以局部使用,建议添加 */
.diyFont{
    font-family: 'hl';
}

这样我们就可以实现引用本地的字体了,并且在web有效!

在你想要使用的元素的 class 里面加上 diyFont 即可。

  • 直接使用

    F12,找到对应的代码片段即可:

<span class="logo-span diyFont">测试字体</span>
  • 模板使用

    找到对应的模板 header.ejs中的代码片段使用即可:

<span class="logo-span diyFont"><%= config.title %></span>

修改主题颜色

在主题文件的 /source/css/matery.css 文件中,搜索 .bg-color 来修改背景颜色:

/* 整体背景颜色,包括导航、移动端的导航、页尾、标签页等的背景颜色. */
.bg-color {
  background-image: linear-gradient(to right, #4cbf30 0%, #0f9d58 100%);
}

@-webkit-keyframes rainbow {
  /* 动态切换背景颜色. */
}

@keyframes rainbow {
  /* 动态切换背景颜色. */
}

修改 banner 图和文章特色图

可以直接在 /source/medias/banner 文件夹中更换喜欢的 banner 图片,主题代码中是每天动态切换一张,只需 7 张即可。如果会 JavaScript 代码,可以修改成自己喜欢切换逻辑,如:随机切换等,banner 切换的代码位置在 /layout/_partial/bg-cover-content.ejs 文件的 <script></script> 代码中:

$(".bg-cover").css("background-image", "url(/medias/banner/" + new Date().getDay() + ".jpg)");

/source/medias/featureimages 文件夹中默认有 24 张特色图片,你可以再增加或者减少,并需要在 _config.yml 做同步修改。

Hexo 跳过渲染

  在Hexo部署时会默认渲染source下的所有html页面,但有时候想在Hexo博客上单独自定义html页面或README.md时,却不希望被Hexo渲染。因此对某个文件或者目录进行排除渲染是非常必要的。

方法一:font matter

Hexo新建网站页面,然后将你的代码直接写入 index.md

Front matter 中添加 layout: false,此方法适用于单一的纯HTML
CSS 页面。

---
title: tools
date: 2020-04-28 00:00:00
type: "tools"
layout: false
---

0x003 方法二:skip rende

在博客根目录下的 _config.yml,找到 skip_render,大概在32行左右,写入你想要的跳过渲染的路径,注意缩进和空格。

# 指定目录跳过hexo渲染
skip_render:
  - 'tools/*'
  - 'tools/**'

注释:tools/* 表示在目录 source/fireworks 下的文件全部跳过渲染,tools/** 表示在博客根目录 source/tools/ 文件夹下的文件全部跳过渲染(例如页面的 js、css 在另一个文件夹中)。

各种优化

CDN 加速(强烈建议启用)

  • 为什么强烈建议启用CDN?

研究表明,用户最满意的打开网页时间,是在 2 秒以下。用户能够忍受的最长等待时间在 6~8 秒之间。就是说,8 秒是一个临界值,如果你的网站打开速度在 8 秒以上,那么你将失去大部分用户。研究显示,如果等待 12 秒以后,网页还是没有载入,那么 99% 以上的用户会选择关闭网页。

Google 做过一个试验,10 条搜索结果的页面载入时间需要 0.4 秒,显示 30 条搜索结果的页面载入时间需要 0.9 秒,结果后者使得 Google 总的流量和收入减少了 20%。Google 地图上线的时候,首页大小有 100KB,后来下降到 70~80KB。结果,流量在第一个星期上升了 10%,接下来的 3 个星期又再上升了 25%。Amazon 的统计也显示了相近的结果,首页打开时间每增加 100 毫秒,网站销售量会减少 1%。

以上数据说明了一个非常重要的问题,如果你的网站速度如果超过 2s 以上,那么你的客户可能在流失和离你而去了。这一点对于电商网站尤其重要,打开速度慢,那么将造成转化率降低,损失将会大量增加。

放在 Github 的资源在国内加载速度比较慢,因此需要使用 CDN 加速来优化网站打开速度,jsDelivr + Github 便是免费且好用的 CDN,非常适合博客网站使用。也可以选择主流云服务商提供的对象存储+CDN 来获得更快速及稳定的访问效果,费用低到几乎可忽略。

用法:

https://cdn.jsdelivr.net/gh/你的用户名/你的仓库名@发布的版本号/文件路径

例如:

https://cdn.jsdelivr.net/gh/lxl80/blog@gh-pages/medias/banner/1.jpg

注意:版本号不是必需的,是为了区分新旧资源,如果不使用版本号,将会直接引用最新资源。

还可以配合 PicGo图床上传工具的自定义域名前缀来上传图片,使用极其方便。具体使用方法可参见我的另一篇文章: 使用 Typora+iPic/PicGo 图床+CDN 实现高效 Markdown 创作

Cloudflare CDN

配置最简单的CDN方式了。在github raw链接地址前面加https://images.weserv.nl/?url=, 就会自动使用cloudflare cdn来加速图片访问。使用发现无法加速gif。

本blog主要使用这个方法,如下所示。

  • 未加速图片地址
https://raw.githubusercontent.com/appotry/cloudimg/main/data/2021/09/1020210910231815.png
  • Cloudflare加速图片地址
https://cimg1.17lai.site/data/2021/09/1020210910231815.png

SEO 优化

搜索引擎优化,又称为 SEO,即 Search Engine Optimization,它是一种通过分析搜索引擎的排名规律,了解各种搜索引擎怎样进行搜索、怎样抓取互联网页面、怎样确定特定关键词的搜索结果排名的技术。Google 自动收录效果还不错,百度就差得远了(GitHub不允许百度的Spider爬取GitHub上的内容)。

网域提交方式

  1. 自动提交

    (分三种)

    • 主动推送
    • 自动推送
    • sitemap(站点地图)
  2. 手动提交

    • 即手动地将链接一次性提交给百度

一般自动提交比手动提交效果好一点,自动提交又从效率上来说:

主动推送>自动推送>sitemap

自动提交的三种方式

  1. 主动推送:最为快速的提交方式。将站点当天新产出链接通过此方式推送给百度,以保证新链接可以及时被百度收录。
  2. 自动推送:最为便捷的提交方式。将自动推送的JS代码部署在站点的每一个页面源代码中,当部署代码的页面在每次被浏览时,链接就会被自动推送给百度。可以与主动推送配合使用。
  3. sitemap:您可以定期将网站链接放到sitemap文件中,然后将sitemap文件提交给百度。百度会周期性的抓取检查您提交的sitemap,对其中的链接进行处理,但收录速度慢于主动推送。

使用sitemap方式推送

安装 sitemap 插件生成站点地图文件:

npm install hexo-generator-sitemap --save
npm install hexo-generator-baidu-sitemap --save  #百度专用

安装后直接执行 hexo cl&&hexo g -d 命令,就会在网站根目录生成 sitemap.xmlbaidusitemap.xml 文件。

  • 在博客目录的_config.yml中添加如下代码
# 通用站点地图
sitemap:
  path: sitemap.xml

# 百度站点地图
baidusitemap:
  path: baidusitemap.xml
百度优化

登录百度搜索资源平台, 登录成功之后在 用户中心 –> 站点管理 页面中点击添加网站,按提示操作。

添加网站

添加网站

提示:由于百度的 spider 是爬取不到 GitHub 的内容的,所以在第三步验证网站的时候,建议选择CNAME验证的方式。

经过以上步骤,百度已经知道有我们网站的存在了,但是百度还不知道我们的网站上有什么内容,所以要向百度推送我们的内容。点击 网站支持 –> 数据引入 –> 链接提交菜单,提交站点地图:

提交站点地图

提交站点地图

另外,hexo-theme-matery主题已经内置了 自动推送 的功能, 检查 themes/hexo-theme-matery/_config.yml 文件中如下配置:

# 百度搜索资源平台提交链接
baiduPush: true

自动推送的 JS 代码部署在站点的每一个页面源代码中,当页面在每次被浏览时,链接就会被自动推送给百度。

谷歌优化

登录 Google Search Console,点击添加资源,输入自己的域名,按提示操作。

添加资源

添加资源

提示:需要进行 DNS 验证,进入 DNS 域名解析设置页面,按提示增加 TXT 记录,如下图:

DNS验证内容填写示例

DNS验证内容填写示例

验证成功后,需要提交站点地图。参照下图提交,然后等待收录。

提交站点地图

提交站点地图

注意:hexo 配置文件中的 url 一定要输入正确的域名,插件是根据 url 生成站点地图的。

其它搜索引擎

百度自动推送方式

只要每个需要被百度爬取的HTML页面中加入一段JS代码即可:

<script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script>

我所使用的matery主题可以自动给每个页面加上这段代码,只需在主题配置文件中配置:

# 百度搜索资源平台提交链接
baiduPush: true

即可!

其他主题一般都有这个功能的实现,如果没有的话,想办法在每个页面加入以上JS代码即可,原理是一样。

百度主动推送SEO方式

  • 配置文章自动推送到百度蜘蛛
获取百度推送密钥

百度资源 注册你的网址,验证完后可在站点管理->资源提交->链接提交->主动推送(实时) 中找到你的推送密钥,下面说明中的 token= 后的内容即为推送密钥。

推送接口
接口调用地址:http://data.zz.baidu.com/urls?site=https://ifibe.com&token=xxxxxxxxxx
安装主动推送插件:hexo-baidu-url-submit
$ npm install hexo-baidu-url-submit --save
然后打开hexo配置文件,在末尾加入以下配置:
# hexo-baidu-url-submit  百度主动推送
baidu_url_submit:
  count: 80 # 提交最新的一个链接
  host: https://blog.17lai.site # 在百度站长平台中注册的域名
  token: xxxxxxx # 请注意这是您的秘钥, 所以请不要把博客源代码发布在公众仓库里!
  path: baidu_urls.txt # 文本文档的地址, 新链接会保存在此文本文档里

密匙的获取是在百度的自动提交的主动推送那里。

再加入新的deploy
deploy:
- type: baidu_url_submitter

如图:

这样每次执行 hexo d 的时候,新的链接就会被推送了。

$ hexo clean
$ hexo g
$ hexo d

推送成功时,会有如下终端提示!

baidu_url_submitter

各种不同的推送反馈字段说明点我查看,一般来说,推送失败基本都是地址不相符造成的,我们只需对比baidu_url_submitpublic中生成的baidu_urls.txt的地址,与自己填写在host字段中的地址对比看是否一样即可。

Github Action 自动提交SEO方式

安装插件
npm i hexo-seo-autopush --save
配置

在hexo 的config.yml里添加

hexo-seo-autopush配置

# enable: 开启/关闭 推送
# count: 每次提交最新的10篇文章
# https://github.com/lete114/hexo-seo-autopush
hexo_seo_autopush:
  baidu:
    enable: true
    count: 100
  bing:
    enable: true
    count: 10
  google:
    enable: true
    count: 10
    google_file: google_service_account.json # 谷歌服务账户

添加Google Push配置和解决push后没有GitHub Actions .github\workflows\AutoPush.yml文件的问题

# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
   - type: git
     repo: https://github.com/lete114/Test.git
     branch: main
     ignore_hidden: false  # 忽略隐藏文件及文件夹(目录)
   - type: GooglePush # 谷歌提交
获取站长平台密钥
Baidu Key
  1. 打开百度站长平台,点击左侧的普通收录https://ziyuan.baidu.com/
Bing Key
  1. 打开Bing站长平台,https://www.bing.com/webmasters/home
  2. 点击右上角头像 旁边的齿轮,跟着下图操作
Google Key

Google Wiki, 使用参考。

  1. 打开Google indexing API官网

  2. 选择创建项目,点击继续

  3. 点击转到凭据页面

  4. 跟着如下图片步骤

    GoogleProof

    GoogleAddProof

    GoogleNone

    GoogleKey

    json文件内的内容

    {
      "type": "service_account",
      "project_id": "elated-guild-298003",
      "private_key_id": "cf58d669c0e8c8e082b2c403ade5e2548078e384",
      "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEAJw89yeylRrA\nB+bzOAfQQNgOCABIwEKCy5mMxWSaiXy2RktyCJWjMR2Pgz770NJgClQHPJjsFn0c\nukHufpnuiX3VPlimLANPCRFdU/qp+yiaw4quIhYF1UZJkhmhL30anghUcvi+r9hQ\nw+RwcKrgA4EUzqUJaPdvjtzSoo315PPGfR91ASD5S8gE02yVI8igtYMX7v2x1JYR\n7PwHJwOVemiM9lot8ilvoUbV4BU0vSlwFoxKMJAbEXTmJjEKQi9992rcMW0GzXO8\ncHldUUtURXkt3VFjYTH27KhHiTkTXw+uZRBu1rkubDJkS8lGIWN7Fc/r4HMMCVTu\nXPS6HbJ/AgMBAAECggEANSS7OBaFd3jRL3cVCiZLjA5A5pEJzq/+eKtOn2oYDISx\nwVRO+YTVWdGj47kg1zM4D11NikbGaeDxHFxuKwW9o/04lpyYebneTcw2Hpl6EiOs\nz0WssOlCEmPQ8nrAI0GWiKSHuqoPwtg37TIoGsqZsjKRCby759DDokZYnm3/0sc+\niEllT0ZyBZhGDzyguVLEdCIR2P02q/hQzLyd6ejWGGwZebImbGoILhmuOjVrco0p\nV0JbrrNskjM5Epe7w+CpGftEASJ7Dxa8oj0qIT6cyAipra2AZAGnG9jrLcWpJuhu\nvNeDIFnTfpNEac+khXZZE2++MIQfTX9wGJc8tox2vQKBgQD6yiNvAL7sxExiy6ER\ntLtFQ3bvmMpKRFGvFOyPOtMbmjZ3D1GEtNNKGH4v1TI+tncEy7Q5Dm7nWwpi8yvL\nbh8xKghelAc/CU1nw0xDEDCkMbAwpFg5A5ZDImy3LZsQh0kNXniIMy1vMSt5yLKS\n80gXQKGCxG8t3rP8Qd/2a55g1QKBgQDIExP1nG9sHJaigmitEUwr0Ow6Shqr56Me\nd7995gaV1oLWWCQzrXt/viWkb1W5ZGIxzcWNWz99m4CbvqfewRr598Eenald0csN\nVcIEk+0C+6KqA+jU9Tfs2zow/C7JuKULP2N++o0EoSz/ngokP7f1yLOYbr507v/R\n0cLElQBQAwKBgAbxDWYHKUG4dTzO0hiBXiWepm4fVooTtgcYlyunvywmapeFDwaT\nUr3cS7HbPtbJiiXR1Z02rw8sT+9JN88brzVXKoAjrMer5D6ZA0Vf71i8H1pZUi/R\nz5jwHP48/uvIMtdx4/gxInLPc5qdWYQDw90Q5ueNtF4aqfSzhhV2CR45AoGBAJN9\nPOF6iMjx6jmyWOf8MGK8iOgPaMoA4Ea9j/SHdaNPlvPb1hQid0AcNDObv14Dmj+M\nqW0jLxKxZ4VobufPAsvyz/J51zjKRx11cqldQwNH7QnYB/O1MZzxn1wtC3C5JTG9\ncONSYFJhXoKxRliigEI3ye089jnNVdifAS1ZiflxAoGBANTX1fEMEeNuYU0v3rtd\n5CkPZg4TNZ+y2MGl5xR1LdIgrJ8c9xKoW4rpp7SsOIvHpWX494f90D7o9uFEGSQ4\nyQK53jVzJ0ekGV5BdPF3n3/2j2VEqFLHi7LL4CJSxr6ci7OfBoHOGE8odhevQCCK\njnFzEin0QsBEgIC73fBh6XcH\n-----END PRIVATE KEY-----\n",
      "client_email": "googleindexing@elated-guild-298003.iam.gserviceaccount.com",
      "client_id": "103034240916368863393",
      "auth_uri": "https://accounts.google.com/o/oauth2/auth",
      "token_uri": "https://oauth2.googleapis.com/token",
      "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
      "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/googleindexing%40elated-guild-298003.iam.gserviceaccount.com"
    }
  5. 打开谷歌站长平台
    GoogleAddUser
    GoogleAddEmail

配置博客仓库
  1. Name必须是baidu_tokenbing_apikey(不区分大小写)
  2. 添加完成后
    Secrets-token
谷歌的一些问题

触发谷歌提交的命令是hexo d

由于谷歌需要配合Google indexing API平台提供的json进行提交,而这个json格式不能泄露
为防止json泄露只能本地提交,将json放到hexo根目录可自定义重命名(必须对应插件的配置)
如果你的使用Github Actions自动部署的话请把仓库设置为私有
GoogleConfig

提交成功返回状态码

以上步骤完成后即可hexo d部署了

  1. 看看Github仓库是否上传成功

  2. 点击Actions查看是否执行

  3. 点击 Auto Push—->build—–>点击第2步 自动提交

    如图43行

    // baidu返回的结果
    {
    	"remain": 2060,  // 表示当天剩余的可推送url条数
    	"success": 47    // 成功推送的url条数
    } 
    // bing返回结果(错误)
    {
    	"ErrorCode": 2,  // 错误 
    	"Message": "ERROR!!! Quota remaining for today: 2, Submitted: 47"
        // Message:表示 你目前只剩2个url推送,而你现在推送的是47条url
        // bing新用户开始每日只有10个推送额,据我了解连续推送10天(这我也不确定)
        // 如果出现这个错误的话,你就只能先手动添加等系统给你分配额了(分配9999)
    }
    // bing返回结果(成功)
    {"d":null}
  4. Google 返回状态码

    成功返回

    Google response:  {
      urlNotificationMetadata: {
        url: 'https://blog.lete114.top/article/hexo-seo-autopush.html',
        latestUpdate: {
          url: 'https://blog.lete114.top/article/hexo-seo-autopush.html',
          type: 'URL_UPDATED',
          notifyTime: '2020-12-08T02:31:32.871417693Z'
        }
      }
    }

    出现此错误需要: 翻墙

    FetchError: request to https://www.googleapis.com/oauth2/v4/token failed, reason: connect ETIMEDOUT 172.217.27.138:443
        at ClientRequest.<anonymous> (D:\Lete\GitHub\Hexo-Butterfly\node_modules\node-fetch\lib\index.js:1461:11)
        at ClientRequest.emit (events.js:321:20)
        at TLSSocket.socketErrorListener (_http_client.js:426:9)
        at TLSSocket.emit (events.js:321:20)
        at emitErrorNT (internal/streams/destroy.js:92:8)
        at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
        at processTicksAndRejections (internal/process/task_queues.js:84:21) {
      message: 'request to https://www.googleapis.com/oauth2/v4/token failed, reason: connect ETIMEDOUT 172.217.27.138:443',
      type: 'system',
      errno: 'ETIMEDOUT',
      code: 'ETIMEDOUT',
      config: {
        method: 'POST',
        url: 'https://www.googleapis.com/oauth2/v4/token',
        data: {
          grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
          assertion: 'eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJnb29nbGVpbmRleGluZ0BzdGF0ZWx5LXRyYW5zaXQtMjk3NzE1LmlhbS5nc2VydmljZWFjY291bnQuY29tIiwic2NvcGUiOiJodHRwczovL3d3d

本地主动提交SEO

hexo-url-submission

Wiki

安装方法
  1. 在终端中输入:
npm i hexo-url-submission
  1. blog/_config.yml 文件中添加配置:
url_submission:
   enable: true
   type: 'latest' # latest or all( latest: modified pages; all: posts & pages)
   channel: ['baidu', 'bing', 'google', 'shenma'] # Included channels are `baidu`, `google`, `bing`, `shenma`
   prefix: ['/post', '/wiki'] # URL prefix
   count: 10 # Submit limit
   proxy: '' # Set the proxy used to submit urls to Google
   urls_path: 'submit_url.txt' # URL list file path
   baidu_token: '' # Baidu private key
   bing_token: '' # Bing private key
   google_key: '' # Google key path (e.g. `google_key.json` or `data/google_key.json`)
   shenma_token: '' # ShenMa private key
   shenma_user: '' # Username used when registering
   sitemap: '' # Sitemap path(e.g. the url is like this https://abnerwei.com/baidusitemap.xml, you can fill in `baidusitemap.xml`)
更新方法

在站点根目录执行:

npm update hexo-url-submission
deploy
deploy:
  - type: us_baidu_deployer
  - type: us_bing_deployer
  - type: us_google_deployer
  - type: us_shenma_deployer
good job

Run:

hexo clean && hexo g && hexo d

enjoy it!

提交 robots.txt

robots.txt是干嘛的?

robots.txt 是一种存放于网站根目录下的 ASCII 编码的文本文件,它的作用是告诉搜索引擎此网站中哪些内容是可以被爬取的,哪些是禁止爬取的。
robots.txt 要放在 Hexo根目录 下的 source 文件夹中。

每个人站点目录可能不太一样,可以参考下我的 robots.txt 文件,内容如下:

User-agent: *
Allow: /
Allow: /posts/
Disallow: /about/
Disallow: /archives/
Disallow: /js/
Disallow: /css/
Disallow: /contact/
Disallow: /fonts/
Disallow: /friends/
Disallow: /libs/
Disallow: /medias/
Disallow: /page/
Disallow: /tags/
Disallow: /categories/

更多关于 robots.txt 的写法参见 https://blog.csdn.net/fanghua_vip/article/details/79535639

编写完以上内容再重新部署一下,然后到百度资源平台的数据监控->Robots点击检测并更新 看能不能检测到。

配置 Nofollow

  • nofollow 是HTML页面中 a标签 的 属性值。
  • 这个属性的作用是:告诉搜索引擎的爬虫不要追踪该链接,为了对抗博客垃圾留言信息

URL优化

一般来说,SEO搜索引擎优化认为,网站的最佳结构是 用户从首页点击三次就可以到达任何一个页面,但是我们使用Hexo编译的站点结构的URL是:域名/年/月/日/文章标题四层的结构,这样的URL结构很不利于SEO,爬虫就会经常爬不到我们的文章,于是,我们需要优化一下网站文章的URL

方案一

直接改成域名/文章标题的形式,在Hexo配置文件中修改permalink如下:

# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: https://blog.sky03.cn
root: /
permalink: :title.html
permalink_defaults:

这个方式有个不好的地方:

直接以文章的标题作为URL,而我们所写的文章的标题一般都是中文,但是URL只能用字母数字和标点符号表示,所以中文的URL只能被转义成一堆符号,而且还特别长。

方案二

安装固定链接插件:hexo-abbrlink

插件作用:自动为每篇文章生成一串数字作每篇文章的URI地址。每篇文章的Front-matter中会自动增加一个配置项:abbrlink: xxxxx,该项的值就是当前文章的URI地址。

  1. Hexo根目录执行:

    npm install hexo-abbrlink --save
  2. Hexo配置文件末尾加入以下配置:

    # hexo-abbrlink config 、固定文章地址插件
    abbrlink:
      alg: crc16  #算法选项:crc16、crc32,区别见之前的文章,这里默认为crc16丨crc32比crc16复杂一点,长一点
      rep: dec    #输出进制:十进制和十六进制,默认为10进制。丨dec为十进制,hex为十六进制
  3. Hexo配置文件中修改permalink如下:

    # URL
    ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
    url: https://blog.17lai.site
    root: /
    permalink: posts/:abbrlink.html
    permalink_defaults:

这样站点结构就变成了:域名/posts/xxx.html

异步加载JS

方法:将JS文件的引入,放到HTML的body结束标签的上方

<html>
    <head>
        <title>Hello World!</title>
    </head>
    <body>
        xxxxx....
        <script src="xx/xx.js"></script>
    </body>
</html>

原理:首先要明白,HTML的加载是从上往下一行一行解释执行的,把js文件的引入放到下面,这样就会先把HTML页面展示出来,然后再加载js。这样看起来的效果就是,大体的页面先出来,而js让它慢慢加载执行,如果你把js放到网页的上方,效果就是必须要加载完js才能继续展示网页,体验极差。

注意:原主题的js文件尽量不要动,我们只需将自己增加的一些js按照异步加载的方式做即可,比如一些音乐js插件、实时在线聊天js插件等放到最后即可!因为这些文件要加载的东西很多。

字蛛压缩字体

在上面我们介绍了如何在网站上引用自己喜欢的字体,但是这样会出现一个问题:字体文件太大!(尤其是中文,有时候为了几个字引入一个数十兆的字体文件,得不偿失),所有需要字体压缩!

官网 GitHub

使用场景

你的网站中需要自定义字体(额外添加一些普通电脑中没有的字体),但是一般字体是包含很多字符的,这就导致字体文件的体积很大

字蛛作用

字蛛就是自动检测网站的 CSS 与 HTML 文件中的自定义字体(额外加的字体),并将网站中用到的文字重新打包成一个新的字体文件,并自动引入;

没用到的文字就会删除,从而达到压缩字体文件体积的作用。

安装

npm install font-spider -g

在 CSS 中使用 WebFont:

/*声明 WebFont*/
@font-face {
  font-family: 'pinghei';
  src: url('../font/pinghei.eot');
  src:
    url('../font/pinghei.eot?#font-spider') format('embedded-opentype'),
    url('../font/pinghei.woff') format('woff'),
    url('../font/pinghei.ttf') format('truetype'),
    url('../font/pinghei.svg') format('svg');
  font-weight: normal;
  font-style: normal;
}

/*使用选择器指定字体*/
.home h1, .demo > .test {
    font-family: 'pinghei';
}
  1. @font-face 中的 src 定义的 .ttf 文件必须存在,其余的格式将由工具自动生成
  2. 开发阶段请使用相对路径的 CSS 与 WebFont

运行 font-spider 命令:

font-spider ./demo/*.html

页面依赖的字体将会自动压缩好,原 .ttf 字体会备份

webp图像大小优化

把所有图像都转换为webp格式,可以极大减小图片体积,加快加载速度。

gulp 体积压缩

使用 gulp 图片html, js, ccs

减小体积,加快加载速度

$ npm install gulp -g
$ npm install gulp-minify-css gulp-uglify gulp-htmlmin gulp-htmlclean gulp --save
 
或者使用yarn 
 
yarn global add gulp
yarn add gulp-minify-css gulp-uglify gulp-htmlmin gulp-htmlclean gulp

然后,在根目录新增 gulpfile.js :

 
var gulp = require('gulp');
var minifycss = require('gulp-minify-css');
var uglify = require('gulp-uglify');
var htmlmin = require('gulp-htmlmin');
var htmlclean = require('gulp-htmlclean');
// 压缩 public 目录 css
gulp.task('minify-css', function() {
    return gulp.src('./public/**/*.css')
        .pipe(minifycss())
        .pipe(gulp.dest('./public'));
});
// 压缩 public 目录 html
gulp.task('minify-html', function() {
  return gulp.src('./public/**/*.html')
    .pipe(htmlclean())
    .pipe(htmlmin({
         removeComments: true,
         minifyJS: true,
         minifyCSS: true,
         minifyURLs: true,
    }))
    .pipe(gulp.dest('./public'))
});
// 压缩 public/js 目录 js
gulp.task('minify-js', function() {
    return gulp.src('./public/**/*.js')
        .pipe(uglify())
        .pipe(gulp.dest('./public'));
});
// 执行 gulp 命令时执行的任务
// gulp 3.x
// gulp.task('default', [
//     'minify-html','minify-css','minify-js'
// ]);

// gulp 4.x
gulp.task('default', gulp.series('minify-html', 'minify-css', 'minify-js', done => done()));

运行:

hexo clean && hexo g && gulp &&  hexo g

使用 gulp 图片压缩

压缩 图片文件可降低文件大小,提高图片加载速度。

找到规律转换为 gulp 代码

规律

找到 images/ 目录下的所有文件,压缩它们,将压缩后的文件存放在 dist/images/ 目录下。

一、安装 gulp-imagemin 模块

提示:你需要使用命令行的 cd 切换至对应目录再进行安装操作和 gulp 启动操作。

学习使用命令行

在命令行输入

npm instal gulp-imagemin

安装成功后你会看到如下信息:(安装时间可能会比较长)

gulp-imagemin@2.2.1 node_modules/gulp-imagemin
├── object-assign@2.0.0
├── pretty-bytes@1.0.3 (get-stdin@4.0.1)
├── chalk@1.0.0 (escape-string-regexp@1.0.3, ansi-styles@2.0.1, supports-color@1.3.1, has-ansi@1.0.3, strip-ansi@2.0.1)
├── through2-concurrent@0.3.1 (through2@0.6.3)
├── gulp-util@3.0.4 (array-differ@1.0.0, beeper@1.0.0, array-uniq@1.0.2, lodash._reevaluate@3.0.0, lodash._reescape@3.0.0, lodash._reinterpolate@3.0.0, replace-ext@0.0.1, minimist@1.1.1, vinyl@0.4.6, through2@0.6.3, multipipe@0.1.2, lodash.template@3.3.2, dateformat@1.0.11)
└── imagemin@3.1.0 (get-stdin@3.0.2, optional@0.1.3, vinyl@0.4.6, through2@0.6.3, stream-combiner@0.2.1, concat-stream@1.4.7, meow@2.1.0, vinyl-fs@0.3.13, imagemin-svgo@4.1.2, imagemin-optipng@4.2.0, imagemin-jpegtran@4.1.0, imagemin-pngquant@4.0.0, imagemin-gifsicle@4.1.0)
二、创建 gulpfile.js 文件编写代码

在对应目录创建 gulpfile.js 文件并写入如下内容:

// 获取 gulp
var gulp = require('gulp');

// 获取 gulp-imagemin 模块
var imagemin = require('gulp-imagemin')

// 压缩图片任务
// 在命令行输入 gulp images 启动此任务
gulp.task('images', function () {
    // 1. 找到图片
    gulp.src('images/*.*')
    // 2. 压缩图片
        .pipe(imagemin({
            progressive: true
        }))
    // 3. 另存图片
        .pipe(gulp.dest('dist/images'))
});

// 在命令行使用 gulp auto 启动此任务
gulp.task('auto', function () {
    // 监听文件修改,当文件被修改则执行 images 任务
    gulp.watch('images/*.*)', ['images'])
});

// 使用 gulp.task('default') 定义默认任务
// 在命令行使用 gulp 启动 images 任务和 auto 任务
gulp.task('default', ['images', 'auto'])

你可以访问 gulp-imagemin 以查看更多用法。

三、在 images/ 目录下存放图片

gulpfile.js 对应目录创建 images 文件夹,并在 images/ 目录下存放图片。

四、运行 gulp 查看效果

在命令行输入 gulp +回车

你将看到命令行出现如下提示

gulp
[18:10:42] Using gulpfile ~/Documents/code/gulp-book/demo/chapter4/gulpfile.js
[18:10:42] Starting 'images'...
[18:10:42] Finished 'images' after 5.72 ms
[18:10:42] Starting 'auto'...
[18:10:42] Finished 'auto' after 6.39 ms
[18:10:42] Starting 'default'...
[18:10:42] Finished 'default' after 5.91 μs
[18:10:42] gulp-imagemin: Minified 3 images (saved 25.83 kB - 5.2%)

hexo 部署

将Hexo部署到vps,实现自动发布

搭建流程

  1. 服务器环境配置,安装Git、Nginx配置、创建git用户
  2. 本地hexo初始化
  3. 使用Git自动部署并发布博客

服务器环境搭建

  • 安装Git和NodeJS(Centos环境)
yum install git
# 安装NodeJS 
curl --silent --location https://rpm.nodesource.com/setup_5.x | bash -
  • 创建git账号
adduser git
chmod 740 /etc/sudoers
vim /etc/sudoers
  • 添加内容
    找到
## Allow root to run any commands anywhere
root    ALL=(ALL)     ALL
  • 添加以下内容
git     ALL=(ALL)     ALL
  • 保存退出并改回权限
chmod 400 /etc/sudoers
  • 设置git账号密码
sudo passwd git
  • 使用su git切换到git用户,再执行下列操作:
# 切换到git用户目录
cd /home/git
# 创建.ssh文件夹
mkdir ~/.ssh
# 创建authorized_keys文件并编辑
vim ~/.ssh/authorized_keys
# 如果你还没有生成公钥,那么首先在本地电脑中执行 cat ~/.ssh/id_rsa.pub | pbcopy生成公钥
# 再将公钥复制粘贴到authorized_keys
# 保存关闭authorized_keys后,修改相应权限
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh
  • 然后可以通过本地Git Bash执行ssh命令测试是否可以免密登录
ssh -v git@服务器ip地址

这样git用户就添加好了。

Tips: 将公钥拷贝到服务器的~/.ssh/authorized_keys文件中方法有如下几种:

  1. 将公钥通过scp拷贝到服务器上,然后追加到/.ssh/authorized_keys文件中,这种方式比较麻烦。scp -P 22 ~/.ssh/id_rsa.pub user@host:/。
  2. 通过ssh-copy-id程序,就是我演示的方法,ssh-copyid user@host即可
  3. 可以通过cat ~/.ssh/id_rsa.pub | ssh -p 22 user@host ‘cat >> ~/.ssh/authorized_keys’,这个也是比较常用的方法,因为可以更改端口号。
  • 安装Nginx
  • 准备工作
    首先由于nginx的一些模块依赖一些lib库,所以在安装nginx之前,必须先安装这些lib库,这些依赖库主要有g++、gcc、openssl-devel、pcre-devel和zlib-devel 所以执行如下命令安装
yum install gcc-c++
yum install pcre pcre-devel
yum install zlib zlib-devel
yum install openssl openssl--devel

Ubuntu系统安装命令如下:

sudo apt-get install libpcre3 libpcre3-dev
sudo apt-get install zlib1g-dev
sudo apt-get install openssl libssl-dev
  • 安装Nginx
    安装之前,最好检查一下是否已经安装有nginx
find -name nginx

如果系统已经安装了nginx,那么就先卸载

yum remove nginx

然后开始安装
首先进入/usr/local目录

cd /usr/local

从官网下载最新版的nginx

wget -c https://nginx.org/download/nginx-1.14.2.tar.gz 

(注:版本号可更改,去官网查看最新版本号修改即可)

解压nginx压缩包

tar -zxvf nginx-1.14.2.tar.gz

会产生一个nginx-1.14.2 目录,这时进入nginx-1.14.2 目录

cd  nginx-1.14.2

接下来安装,使用–prefix参数指定nginx安装的目录,make、make install安装

./configure

(默认安装在/usr/local/nginx,推荐使用默认设置)

make

make install

如果没有报错,顺利完成后,最好看一下nginx的安装目录

whereis nginx

(where和is要连这些,中间没有空格)

  • 启动和停止nginx
cd /usr/local/nginx/sbin/
./nginx 
./nginx -s stop
./nginx -s quit
./nginx -s reload
./nginx -s quit: 此方式停止步骤是待nginx进程处理任务完毕进行停止。
./nginx -s stop: 此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程。

查询nginx进程:

ps aux | grep nginx

  • 重启 nginx
  1. 先停止再启动(推荐):
    对 nginx 进行重启相当于先停止再启动,即先执行停止命令再执行启动命令。如下:
./nginx -s quit
./nginx
  1. 重新加载配置文件:
    当 nginx 的配置文件 nginx.conf 修改后,要想让配置生效需要重启 nginx,使用 -s reload 不用先停止 nginx 再启动 nginx 即可将配置信息在 nginx 中生效,如下:
./nginx -s reload

启动成功后,在浏览器可以看到如下页面:

  • 开机自启动

即在rc.local增加启动代码就可以了。

vim /etc/rc.local

增加一行

/usr/local/nginx/sbin/nginx

到这里,nginx安装完毕,启动、停止、重启操作也都完成。

建立git裸库

# 回到git目录
cd /home/git
# 使用git用户创建git裸仓库,以blog.git为例
git init --bare blog.git

检查用户组权限

我们的git裸仓库已经建立好了,离成功又近了一步。为了以防万一,我们要检查一下之前的blog.git、.ssh、blog目录的用户组权限是否都为git:git

# 还记得/var/www/吗?这是之前配置nginx时,我们自己选定的网站根目录,请依据你自己的设置更改,如果没有的话自己
ll -a /www/wwwroot/hexo
ll -a /home/git/

如果有哪个不是,执行下面相应的命令后再查看

sudo chown -R git:git /www/wwwroot/hexo
sudo chmod -R 755 /www/wwwroot/hexo
sudo chown git:git -R /home/git/blog.git

使用git-hooks同步网站根目录

简单来说,我们使用一个钩子文件:post-receive,每当git仓库接收到内容的时候,就会自动调用这个钩子,把内容同步到网站根目录。
在git用户下执行:

# 新建一个post-receive文件并编辑
vim ~/blog.git/hooks/post-receive

在里面输入以下内容,注意修改为自己的设置:

#!/bin/bash
set -e
GIT_REPO=/home/git/blog.git
TMP_GIT_CLONE=/tmp/blog
PUBLIC_WWW=/www/wwwroot/hexo
rm -rf ${TMP_GIT_CLONE}
git clone $GIT_REPO $TMP_GIT_CLONE
cd $TMP_GIT_CLONE
for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done
git checkout main
rm -rf ${PUBLIC_WWW}/*
cp -rf ${TMP_GIT_CLONE}/* ${PUBLIC_WWW}
ls ${PUBLIC_WWW}

保存退出后,执行以下赋予这个文件可执行权限。

chown -R git:git ~/blog.git/hooks/post-receive
chmod +x ~/blog.git/hooks/post-receive

好了,以上就是服务器端需要配置的内容。我们还差最后一步就可以完成整个部署了!

修改配置文件nginx.conf

修改上面的配置文件:

vim /usr/local/nginx/conf/nginx_config

然后修改其中两个部分,如下所示:

然后重启nginx,方法见nginx安装部分。

配置本地Hexo的_config.yml

非常简单,只需要找到本地Hexo博客的站点配置文件_config.yml,找到以下内容并修改:

deploy: 
  type: git
  repo: git@你的服务器IP:/home/git/blog.git
  branch: master

保存后,剩下的就是Hexo的日常操作了,这里就不赘述了,写完文章后,在你的本地博客根目录执行以下命令:

hexo c && hexo g -d

就可以实现线上博客的自动更新了!一切搞定!

Rsync同步部署静态文件方法

使用rsync同步

本地生成静态文件后rsync同步到vps网页目录,lnap使用宝塔配置,这里只需要一个nginx。

# rsync [options] from_dir to_dir
# 替换这里的ip为你的服务器ip
rsync -avzP  /home/17lai.blog  root@8.8.8.8:/www/wwwroot/hexo

Hexo 自动部署

准备

  1. Hexo 博客源码的仓库,在 GitHub 上。
  2. ssh 密钥,参考文章:Windows 下利用 Git 生成 SSH KEY 并配置到 GitHub

步骤

  1. 为需要部署的平台添加密钥
  2. 修改 _config.yml 中的 deploy 配置
  3. 在 GitHub 上设置 Secrets
  4. 创建 GitHub Action

为需要部署的平台添加密钥

按照之前的教程,只要你之前成功将 Hexo 的博客部署到 GitHub 上,那你电脑在 ~/.ssh 目录下一定有以下三个文件:

  • id_rsa:私钥
  • id_rsa.pub:公钥
  • known_hosts:记录对所有用户都可信赖的远程主机的公钥

id_rsa.pub(公钥)添加到不同平台中即可,参考文章:Windows 下利用 Git 生成 SSH KEY 并配置到 GitHub

下面是不同平台添加的地址:

修改 _config.yml 中的 deploy 配置

请使用 ssh (即以 git@ 开头的 clone 链接) 的连接方式,根据直接的实际地址填写。

deploy:
  - type: git
    repo:
      github: git@github.com:Sitoi/Sitoi.github.io.git
      coding: git@e.coding.net:Sitoi/Sitoi.git
      gitee: git@gitee.com:sitoi/sitoi.git
      gitlab: git@gitlab.com:Sitoi/sitoi.gitlab.io.git
    branch: master

在 GitHub 上设置 Secrets

  1. 进入到你在 GitHub 上面的源码仓库

  2. 点击右上角的 Settings

Settings

Settings

  1. 点击左侧的 Secrets

  2. 点击右上角的 New secret

New secret

New secret

  1. Name 中输入 HEXO_DEPLOY_PRI,在 Value 中填入 id_rsa(私钥)的全部内容

Add secret

Add secret

创建 GitHub Action

  1. 点击项目上方的 Action 按钮

Action

Action

  1. 点击 set up a workflow yourself 创建 Workflow

Workflow

Workflow

  1. 修改 main.yaml 的内容

Create Workflow

Create Workflow

根据实际情况修改成你自己的内容

  • Git 推送使用的用户名:git config –global user.name ‘sitoi’:
  • Git 推送使用的邮箱:git config –global user.email ‘133397418@qq.com
  • Hexo 的版本:npm i hexo@4.1.1 -g
name: Hexo CI

on:
  push:
    branches:
      - butterfly

jobs:
  butterfly-build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [10.x]

    steps:
      - uses: actions/checkout@v1
      - name: Use Node.js 10.x
        uses: actions/setup-node@v1
        with:
          node-version: '10.x'
      - name: env prepare
        env:
          HEXO_DEPLOY_PRI: ${{ secrets.HEXO_DEPLOY_PRI }}
        run: |
          mkdir -p ~/.ssh/
          echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan github.com >> ~/.ssh/known_hosts
          ssh-keyscan gitlab.com >> ~/.ssh/known_hosts
          ssh-keyscan e.coding.net >> ~/.ssh/known_hosts
          ssh-keyscan gitee.com >> ~/.ssh/known_hosts
          git config --global user.name 'sito'
          git config --global user.email '133397418@qq.com'
          npm i
          npm i hexo@4.1.1 -g
      - name: gen
        run: |
          hexo clean
          hexo generate
          hexo deploy
  1. 将你的源码推送到 GitHub 上,你的博客一会就会自动更新了。

以 token 方式部署到 Github

deploy:
  type: git
  repo:
    github:
      url: <repository url>
      branch: [branch]
      token: ''
  message: [message]
  name: [git user]
  email: [git email]
  extend_dirs: [extend directory]
  ignore_hidden: false # default is true
  ignore_pattern: regexp  # whatever file that matches the 

利用 GitLab 实现 Hexo 博客的 CI/CD

Portainer 提供了对服务在线更新的 WebHook,所以基于 GitLab 自带的 CI/CD 功能实现 Hexo 博客的持续部署,就非常轻松了。

CI/CD 其实本质上是一套流程,流程规则可以自行定义。在本文研究的主题下,流程分为三步:第一步是编译 Hexo 博客并生成静态文件;第二步是将静态文件打包成可提供 Web 服务的镜像;第三步则是通过 Portainer 的钩子触发服务更新。

.gitlab-ci.yml

stages:
  - compile
  - build
  - deploy

# CONTAINER_RELEASE_IMAGE 根据自己的仓库名修改
variables:
  DOCKER_HOST: tcp://docker:2375
  DOCKER_DRIVER: overlay2
  CONTAINER_RELEASE_IMAGE: registry.gitlab.com/xxx/xxx:latest

compile:
  stage: compile
  image: node:lts-alpine
  script:
    - npm install
    - ./node_modules/hexo/bin/hexo generate
  artifacts:
    paths:
      - public/
    expire_in: 20 minutes

build:
  stage: build
  image: docker:stable
  services:
    - docker:dind
  script:
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
    - docker info
    - docker build -f ./Dockerfile -t $CONTAINER_RELEASE_IMAGE public
    - docker push $CONTAINER_RELEASE_IMAGE

# 根据自己的钩子修改下方的 URL
deploy:
  stage: deploy
  script:
    - curl https://xxx.xxx.xxx/api/webhooks/xxx -X POST

为了保证服务更新的成功率,可以在 deploy 环节加个错误判断和重试次数,具体的看 GitLab 官方文档即可。

下面给出我的 Dockerfile 文件,供参考。

FROM nginx:alpine

COPY . /usr/share/nginx/html

RUN chmod 777 /usr/share/nginx/html -R \
    && sed -i 's/#error_page  404/error_page  404/' /etc/nginx/conf.d/default.conf

一堆个性定制

个性美化

修改主题颜色

配色包括导航栏,底部栏,a标签等,主题配色是绿色。

修改themes\Matery\source\css\matery.css样式
快捷键ctrl+F查找到#4cbf30(浅绿色)和#0f9d58(深绿色)还有首页字体颜色,修改为你喜欢的颜色

/* 整体背景颜色,包括导航、移动端的导航、页尾、标签页等的背景颜色. */ 
.bg-color { 
	background-image: linear-gradient(to right, #4cbf30 0%, #0f9d58 100%); 
} 
/*如果想去掉banner图的颜色渐变效果,请将以下的css属性注释掉或者删除掉即可*/ 
@-webkit-keyframes rainbow { 
	/* 动态切换背景颜色. */ 
} 
@keyframes rainbow { 
	/* 动态切换背景颜色. */ 
}

背景樱花飘落效果

修改已经提交到主线devlop分支,现在可以直接在主线配置文件中开启樱花特效了。

themes/matery/source/js目录下新建sakura.js文件,打开这个网址传送门,将内容复制粘贴到sakura.js即可。

然后在themes/matery/layout/layout.ejs文件内添加下面的内容:

<script type="text/javascript">
//只在桌面版网页启用特效
var windowWidth = $(window).width();
if (windowWidth > 768) {
    document.write('<script type="text/javascript" src="/js/sakura.js"><\/script>');
}
</script>

修改花瓣的数量

因为普遍在使用的樱花背景效果花瓣数太多了,一些人不太喜欢。

于是按不同花瓣数量做了几个新的 js ,并提供如下 cdn 形式的引用:

https://cdn.jsdelivr.net/gh/fz6m/Private-web@1.2/js/sakura/sakura-small.js

以上为少量樱花效果,另提供几个不同数量的文件引用名:

文件名 说明
sakura-small.js 少量樱花
sakura-half.js 樱花相对原效果数量减半
sakura-reduce.js 樱花相对原效果减少1/4
sakura-original.js 樱花数量不变(原效果)

自定义鼠标样式

首先将鼠标样式下载到本地,推荐大家一个网站:https://zhutix.com/ico/ori-cursors/

以我的为例,我将鼠标指针样式放在了主题文件夹下的medias目录下,然后打开themes\matery\source\css下的my.css文件,添加内容如下:

*{
    cursor: url("/medias/imgs/zhengchang.ico"),auto!important;
}
:active{
    cursor: url("/medias/imgs/dianji.ico"),auto!important;
}

取消首页渐变颜色动画

在themes\Matery\source\css\matery.css,ctrl+F快捷键查找.bg-cover:after,注释掉即可。

/* .bg-cover:after {
    -webkit-animation: rainbow 60s infinite;
    animation: rainbow 60s infinite;
} */

优化目录栏,透明化

目录样式竟然在:themes\Matery\layout\_partial\post-detail-toc.ejs

.toc-widget {
    width: 345px;
    padding-left: 20px;
    background-color: rgb(255, 255, 255,0.7);
    border-radius: 10px;
    box-shadow: 0 10px 35px 2px rgba(0, 0, 0, .15), 0 5px 15px rgba(0, 0, 0, .07), 0 2px 5px -5px rgba(0, 0, 0, .1) !important;
}

增加点击跳转评论按钮

新建文件themes\Matery\layout\_partial\back-comment.ejs,粘贴如下代码

我这里评论是valine,直接填写的valine的id——href="#vcomments",如果是其他评论,对应修改即可。

<!-- 直达评论 -->
<div id="to_comment" class="comment-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#vcomments" title="直达评论">
        <i class="fas fa-comments"></i>
    </a>
</div>

themes\Matery\layout\_partial\valine.ejs文末添加一条,引用第一步的内容;

<%- partial('_partial/back-comment.ejs') %>

则只在valine存在的页面才显示直达评论,防止首页其他地方也出现按钮。其实还可以优化为浮动出现,有一点麻烦,我这里没有设置。

增加样式在themes\Matery\source\css\matery.css添加内容如下:

/*直达评论按钮样式*/
.comment-scroll {
    position: fixed;
    right: 15px;
    bottom: 135px;
    padding-top: 15px;
    margin-bottom: 0;
    z-index: 998;
}

.comment-scroll .btn-floating {
    background: linear-gradient(to bottom right, #FF9999 0%, #ff6666 100%);
    width: 48px;
    height: 48px;
}

.comment-scroll .btn-floating i {
    line-height: 48px;
    font-size: 1.8rem;
}

bottom: 135px;是距离底部的高度,看看你是否需要修改。

修改滑动条

/* 滚动条 */
::-webkit-scrollbar-thumb {
    background-color: #FF2A68;
    background-image: -webkit-linear-gradient(45deg,rgba(255,255,255,.4) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.4) 50%,rgba(255,255,255,.4) 75%,transparent 75%,transparent);
    border-radius: 3em;
}
::-webkit-scrollbar-track {
    background-color: #ffcacaff;
    border-radius: 3em;
}
::-webkit-scrollbar {
    width: 8px;
    height: 15px;
}

添加博客看板娘 动漫人物挂件

方法:

获取模型:

npm install --save hexo-helper-live2d

安装喜欢的模型:

$ npm install packagename

将packagename换成模型名字,如我使用的模型:

$ npm install live2d-widget-model-shizuku

然后打开博客根目录下的 _config.yml文件,添加如下代码:

# Live2D
## https://github.com/EYHN/hexo-helper-live2d
live2d:
  enable: true
  # enable: false
  pluginRootPath: live2dw/ # Root path of plugin to be on the site (Relative)
  pluginJsPath: lib/ # JavaScript path related to plugin's root (Relative)
  pluginModelPath: assets/ # Relative model path related to plugin's root (Relative)
  scriptFrom: local # Default
  # scriptFrom: jsdelivr # jsdelivr CDN
  # scriptFrom: unpkg # unpkg CDN
  # scriptFrom: https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js # Your custom url
  tagMode: false # Whether only to replace live2d tag instead of inject to all pages
  log: false # Whether to show logs in console
  model:
    #use: live2d-widget-model-lwet # npm-module package name
    # use: wanko # folder name in (hexo base dir)/live2d_models/
    # use: ./wives/wanko # folder path relative to hexo base dir
    # 模型:https://huaji8.top/post/live2d-plugin-2.0/
    use: https://cdn.jsdelivr.net/npm/live2d-widget-model-wanko@1.0.5/assets/wanko.model.json # Your custom url
  display:
    position: left
    width: 300
    height: 400
    hOffset: 50
    vOffset: 10
  mobile:
    show: false

效果见本blog左下角

Tag标签外挂使用方法

Tag标签外挂使用方法

{%r%}
紅色
{%endr%}
{%g%}
綠色
{%endg%}
{%y%}
黃色
{%endy%}

图片懒加载

图片懒加载是提升网站性能和用户体验的一个非常很好方式,并且几乎所有的大型网站都使用到了,比如微博,仅把用户可见的部分显示图片,其余的都暂时不加载,做法就是:让所有图片元素src指向一个小的站位图片比如loading,并新增一个属性(如data-original)存放真实图片地址。每当页面加载(或者滚动条滚动),使用JS脚本将可视区域内的图片src替换回真实地址,并做请求重新加载。

那么,赶快用起来吧!

在站点根目录执行下面的命令:

npm install hexo-lazyload-image --save

之后在站点配置文件下添加下面的代码

lazyload:
  enable: true  # 是否开启图片懒加载
  onlypost: false  # 是否只对文章的图片做懒加载
  loadingImg: # eg ./images/loading.gif

最后执行 hexo clean && hexo g && hexo s 就可以看到效果了。

外链跳转插件

使用 npm 或者 yarn 安装

## npm 安装
npm install hexo-external-link --save
## yarn 安装
yarn add hexo-external-link

之后在博客站点根目录下添加如下配置:

hexo_external_link:
  enable: true
  enable_base64_encode: true
  url_param_name: 'u'
  html_file_name: 'go.html'
  target_blank: true
  link_rel: 'external nofollow noopener noreferrer'
  domain: 'your_domain' # 如果开启了防盗链,填写你的域名
  safety_chain: true

添加天气小插件

首先去中国天气官网:,配置自己的插件,选择自定义插件—>自定义样式——>生成代码,然后会生成一段代码,复制粘贴到 themes/matery/layout/layout.ejs 即可。

新增个人相册

新建相册目录

执行下面的命令:

hexo new page galleries

然后到站点根目录的 source 目录下找名称为 galleries 的目录,打开目录下的 **index.md ** 文档,在原有基础上添加一下配置:

type: "galleries"
layout: "galleries"

紧接着,在主题配置文件的 menu 属性添加关于相册的菜单

相册:
  url: /galleries 
  icon: fas fa-image

如果需要添加到二级菜单,添加格式为:

- name: 相册
  url: /galleries 
  icon: fas fa-image

添加 ejs 文件和 css 文件

首先新建 gallery.css,填写的代码内容如下:

.gallery-wrapper{
  padding-top: 30px;
}
.gallery-wrapper .gallery-box{
  padding: 5px !important;
}

.gallery-wrapper .gallery-item {
  display: block;
  overflow: hidden;
  background-color: #fff;
  padding: 5px;
  padding-bottom: 0;
  position: relative;
  -moz-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22);
  -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22);
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22);
}

.gallery-cover-box{
  width: 100%;
  padding-top: 60%;
  text-align: center;
  overflow: hidden;
  position: relative;
  background: center center no-repeat;
  -webkit-background-size: cover;
  background-size: cover;
}

.gallery-cover-box .gallery-cover-img {
  display: inline-block;
  width: 100%;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%,-50%);
}
.gallery-item .gallery-name{
  font-size: 14px;
  line-height: 24px;
  text-align: center;
  color: #666;
  margin: 0;
}

.waterfall {
  column-count: 3;
  column-gap: 1em;
}
.photo-wrapper{
  padding-top: 20px;
}
.photo-item {
  display: block;
  padding: 10px;
  padding-bottom: 0;
  margin-bottom: 14px;
  font-size: 0;
  -moz-page-break-inside: avoid;
  -webkit-column-break-inside: avoid;
  break-inside: avoid;
  background: white;
  -moz-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22);
  -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22);
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.22);
}
.photo-item img {
  width: 100%;
}
.photo-item .photo-name{
  font-size: 14px;
  line-height: 30px;
  text-align: center;
  margin-top: 10px;
  margin-bottom: 10px;
  border-top: 1px solid #dddddd;
}

/*适配移动端布局*/
@media only screen and (max-width: 601px) {
  .waterfall {
    column-count: 2;
    column-gap: 1em;
  }
}

然后保存,将此文件放在主题目录下,路径为 matery/source/css

紧接着,新建 galleries.ejs 文件,添加以下代码:

<link rel="stylesheet" href="/css/gallery.css">

<%- partial('_partial/bg-cover') %>

<main class="content">
    <div class="container">
        <% if (site.data && site.data.galleries) { %>
        <% var galleries = site.data.galleries; %>
        <div class="gallery-wrapper row">
            <% for (var i = 0, len = galleries.length; i < len; i++) { %>
            <% var gallery = galleries[i]; %>
            <div class="col s6 m4 l4 xl3 gallery-box">
                <a href="./<%- gallery.name %>" class="gallery-item" data-aos="zoom-in-up">
                     <div class="gallery-cover-box" style="background-image: url(<%- theme.jsDelivr.url %><%- gallery.cover%>);">
                    </div>
                    <p class="gallery-name">
                        <%- gallery.name %>
                    </p>
                </a>
            </div>
            <% } %>
        </div>
        <% } %>
    </div>
</main>

将此文件放在 matery/layout 目录下,同时再此目录下接着新建 gallery.ejs 文件,添加以下代码:

<link rel="stylesheet" href="/css/gallery.css">
<link type="text/css" href="/libs/fancybox/jquery.fancybox.css" rel="stylesheet">
<link type="text/css" href="/libs/justifiedGallery/justifiedGallery.min.css" rel="stylesheet">

<%- partial('_partial/post-cover') %>
<%
let galleries = [];
if (site.data && site.data.galleries) {
    galleries = site.data.galleries;
}
var pageTitle = page.title;
function getCurrentGallery(galleries, pageTitle) {
    for (let i = 0; i < galleries.length; i++) {
        if (galleries[i]['name'] == pageTitle) {
            return galleries[i];
        }
    }
}
var currentGallery = getCurrentGallery(galleries, pageTitle)

var photos = currentGallery.photos;
var galleryImageStr = theme.jsDelivr.url ? theme.jsDelivr.url : '';

let imageStr = ''

for (var i = 0, len = photos.length; i < len; i++) {
    var photo = photos[i];

    imageStr += "<a href=\"" + galleryImageStr + photo + "\"" +
            "     class=\"photo-item\" rel=\"example_group\"" +
            "     data-fancybox=\"images\">" +
            "      <img src=\"" + galleryImageStr + photo + "\"" +
            "       alt=" + photo + ">\n" +
            "    </a>"

}
%>  

<div class="container">
    <div class="photo-wrapper">
        <% if (page.password ) { %>

            <script src="/js/crypto-js.js"></script>
            <script src="/js/gallery-encrypt.js"></script>
            <div id="hbe-security">
                <div class="hbe-input-container">
                    <input type="password" class="hbe-form-control" id="pass"  placeholder="请输入密码查看内容"/>
                    <a href="javascript:;" class="btn-decrypt" id="btn_decrypt">解密</a>
                </div>
            </div>
            <div  id="mygallery">
                <div class="waterfall" id="encrypt-blog" style="display:none">
                    <%- aes(imageStr, page.password) %>
                </div>
            </div>
        <% } else { %>
            <div class="waterfall" id="encrypt-blog">
                <%- imageStr %>
            </div>
        <% } %>
    </div>
</div>

<script src="/libs/fancybox/fancybox.js"></script>
<script src="/libs/justifiedGallery/justifiedGallery.min.js"></script>
<script>

  $("a[rel=example_group]").fancybox();
  $("#encrypt-blog").justifiedGallery({margins: 5, rowHeight: 150});

</script>

注意:

  1. 需要几个文件,我把文件地址放在下面,用浏览器打开链接,就会显示出代码,然后复制粘贴到文加中去就行。开头的是文件路径,如果没有的话,就新建一个就 OK 了。

添加相册 json 配置文件

站点目录 source/_data/ 下新建一个 galleries.json 的文件,json 代码如下:

[
    {
      "name": "2020",
      "cover": "/medias/images/01.jpg",
      "description": "我的图床",
      "photos": [
        "/medias/images/01.jpg",
        "/medias/images/02.jpg",
        "/medias/images/03.jpg"
      ]
    }
]

字段含义:

  • name 是相册标题
  • cover 是封面图片
  • description 是相册介绍
  • photos 是图片列表

配置文件建好了之后还没完,只剩最后一个步骤了,在 galleries 目录下建立对应的相册名称目录和文件,比如我这个相册需要新建名称为 2020 目录,然后下面再分别新建 index.md 文件,文件内容为:

---
title: 2020
date: 2021-10-13 10:51:50
type: "gallery"
layout: "gallery"
---

查看效果

完成以上步骤,执行命令,在本地查看效果:

hexo clean && hexo g && hexo s

我的效果

新增折叠功能

这里利用hexo-sliding-spoiler插件间接实现折叠功能,在matery主题中零修改源代码实现折叠功能。

另一种修改代码实现折叠效果,参考Hexo next博客添加折叠块功能添加折叠代码块

安装插件

npm install hexo-sliding-spoiler --save

配置插件

根目录配置文件_config.yml中添加

plugin:
- hexo-sliding-spoiler

到这里已经实现折叠功能了。

进一步完善美化

修改node_modules_hexo-sliding-spoiler@1.2.1@hexo-sliding-spoiler\assets\spoiler.css

.spoiler {
    margin: 20px 0;
    padding: 15px;
    border: 1px solid #E5E5E5;
    background: #E5E5E5;
    position: relative;
    clear: both;
    border-radius: 3px;
    transition:all .6s
}

.spoiler .spoiler-title {
    margin: 0 -15px;
    padding: 5px 15px;
    color: #353535;
    font-weight: bold;
    font-size: 18px;
    display: block;
    cursor: pointer;
}

.spoiler.collapsed .spoiler-title:before {
    content: "▶ ";
}

.spoiler.expanded .spoiler-title:before {
    content: "▼ ";
}

使用方法

{% spoiler title %}
content
{% endspoiler %}

实例

{% spoiler 点击显/隐内容 %}

内容测试

{% endspoiler %}

{% spoiler 点击显/隐内容 %}

内容测试

{% endspoiler %}

让Hexo博客支持通知功能

安装插件

插件的 GitHub 仓库 hexo-web-push-notification

在你的博客站点目录执行下面的命令:

npm i hexo-web-push-notification --save

如果你安装了 cnpm 或者 yarn 等可执行下面的命令,安装依赖包的速度更快:

cnpm i hexo-web-push-notification --save #安装cnpm的执行这个命令
yarn add hexo-web-push-notification #安装yarn的执行这个命令

紧接着再你的博客站点目录下的配置文件,而不是主题配置文件,添加以下配置:

webPushNotification:
  webpushrKey: "your webpushr rest api key"
  webpushrAuthToken: "your webpushr authorize token"
  trackingCode: "AEGlpbdgvBCWXqXI6PtsUzobY7TLV9gwJU8bzMktrwfrSERg_xnLVbjpCw8x2GmFmi1ZcLTz0ni6OnX5MAwoM88"

其中 webpushrKey,webpushrAuthTokentrackingCode 的值在官网注册得到。

官网注册

点击右边的图标即可进入👉 : 传送门

注册完之后,然后会让你重新登录,登录之后,然后填写相关的信息即可。

  1. 填写图中所显示的相关网站信息,填写完之后,点击下一步

Web push notications 仅支持 HTTPS 的网站,不支持 HTTP 的网站

根据网站类型,并根据网站指引进行操作,以 Hexo 为例

info, 其中将第二步中所指的代码复制粘贴到你的 footer.ejs 或者 layout.ejs,对于 hexo 用户,建议将其加入 index.ejs 即可。因为主题的不同,所以代码添加的位置不同,简单的说,就是放在网站的 </body> 标签之前,根据你的主题而言,自己添加。

接着将以下代码插入到网页中就可以了。确保每一个你想要询问用户接受通知的页面都要包含以下代码。

其中,上图步骤二中的代码有 trackingCode 的值,如下图中所标明的一长串字母。

验证安装

安装成功

部署之后可能会遇到无法正常发送通知的情况.

进入目录 node_modules/hexo-web-push-notification/index.js文件中第22行'summary': util.stripHTML(newPost.excerpt),这里取值取的是excerpt,改成summary即可。

修改前

var JSONFeed = {
        'title': newPost.title,
        'id': newPost.path,
        'date_published': newPost.date.format('L'),
        'summary': util.stripHTML(newPost.excerpt),
        'url': newPost.permalink,
        'tags': newPost.tags.data.map(function (v) { return v.name }),
        'categories': newPost.categories.data.map(function (v) { return v.name })
    }
var JSONFeed = {
        'title': newPost.title,
        'id': newPost.path,
        'date_published': newPost.date.format('L'),
        'summary': util.stripHTML(newPost.summary),
        'url': newPost.permalink,
        'tags': newPost.tags.data.map(function (v) { return v.name }),
        'categories': newPost.categories.data.map(function (v) { return v.name })
    }

客服聊天窗口

1、在官网注册账号

官网地址:点我去crisp官网注册

2、注册完成后设置

登录刚才注册的账户——设置——网站设置——添加网站。

添加完成之后就多了一行网站信息。点网站整合,就有不同的站的整合方式。

比如:html方式

就是复制JS代码片段到你的到head标签里。

<script type="text/javascript">window.$crisp=[];window.CRISP_WEBSITE_ID="xxxxxxx-097e-402f-bb6b-xxxxxxx";(function(){d=document;s=d.createElement("script");s.src="https://client.crisp.chat/l.js";s.async=1;d.getElementsByTagName("head")[0].appendChild(s);})();</script>

3、其他的设置也
登录刚才注册的账户——设置——网站设置。
网站信息行——设置,自己根据需要设置即可,比如显示位置,颜色,自己的头像等。

整个使用非常简单的。

使用Valine-Admin管理评论和评论提醒

使用

首先其他的不错说了,在阅读本篇文章之前你最好已经整合了Valine留言。

由于我已经整合过了所以前面几个步骤的图片来源自@Valine-Admin

首先登陆账号,找到云引擎在点击设置。

复制仓库地址:DesertsP/Valine-Admin

把git仓库地址房子代码库输入框中。

切换到部署标签页,分支使用 master,点击部署。

接下来输入分支为master

部署完成之后就是设置环境变量

环境变量

点击设置,找到自定义环境变量点击新增变量

  • SITE_NAME : 网站名称。
  • SITE_URL : 网站地址, 最后不要加 /
  • SMTP_USER : SMTP 服务用户名,一般为邮箱地址。
  • SMTP_PASS : SMTP 密码,一般为授权码,而不是邮箱的登陆密码,请自行查询对应邮件服务商的获取方式
  • SMTP_SERVICE : 邮件服务提供商,支持 QQ163126Gmail"Yahoo"...... ,全部支持请参考 : Nodemailer Supported services。 — 如这里没有你使用的邮件提供商,请查看自定义邮件服务器
  • SENDER_NAME : 寄件人名称。
  • TO_EMAIL:这个是填收邮件提醒的邮箱地址,若没有这个字段,则将邮件发到SMTP_USER
  • TEMPLATE_NAME:设置提醒邮件的主题,目前内置了两款主题,分别为 defaultrainbow。默认为 default

设置好以上变量之后 点击实例

然后重启项目,注意任何变动都要重启项目

然后看一下效果

还不错

自定义后台

首先需要设置管理员信息。访问管理员注册页面https://云引擎域名/sign-up,注册管理员登录信息,如:https://deserts-io.avosapps.us/sign-up

点击设置然后点击Web主机域名找到自己的后台地址

然后在Usee表中增加账号, 只需要填写 emailpasswordusername 其中邮箱必须设置为你的上面环境变量的邮箱

设置完之后登录就能在你的后台管理评论

更多设置

邮件通知模板

邮件通知模板在云引擎环境变量中设定,可自定义通知邮件标题及内容模板。

环境变量 示例 说明
MAIL_SUBJECT ${PARENT_NICK},您在${SITE_NAME}上的评论收到了回复 [可选]@通知邮件主题(标题)模板
MAIL_TEMPLATE 见下文 [可选]@通知邮件内容模板
MAIL_SUBJECT_ADMIN ${SITE_NAME}上有新评论了 [可选]博主邮件通知主题模板
MAIL_TEMPLATE_ADMIN 见下文 [可选]博主邮件通知内容模板

邮件通知包含两种,分别是被@通知和博主通知,这两种模板都可以完全自定义。默认使用经典的蓝色风格模板(样式来源未知)。

默认被@通知邮件内容模板如下:

<div style="border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;"><h2 style="border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;">您在<a style="text-decoration:none;color: #12ADDB;" href="${SITE_URL}" target="_blank">            ${SITE_NAME}</a>上的评论有了新的回复</h2> ${PARENT_NICK} 同学,您曾发表评论:<div style="padding:0 12px 0 12px;margin-top:18px"><div style="background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;">            ${PARENT_COMMENT}</div><p><strong>${NICK}</strong>回复说:</p><div style="background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;"> ${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}" target="_blank">查看回复的完整內容</a>,欢迎再次光临<a style="text-decoration:none; color:#12addb" href="${SITE_URL}" target="_blank">${SITE_NAME}</a><br></p></div></div>

效果如下图:

mail-blue-template

@通知模板中的可用变量如下(注,这是邮件模板变量,是指嵌入到HTML邮件模板中的变量,请勿与云引擎环境变量混淆):

模板变量 说明
SITE_NAME 博客名称
SITE_URL 博客首页地址
POST_URL 文章地址(完整路径)
PARENT_NICK 收件人昵称(被@者,父级评论人)
PARENT_COMMENT 父级评论内容
NICK 新评论者昵称
COMMENT 新评论内容

默认博主通知邮件内容模板如下:

<div style="border-top:2px solid #12ADDB;box-shadow:0 1px 3px #AAAAAA;line-height:180%;padding:0 15px 12px;margin:50px auto;font-size:12px;"><h2 style="border-bottom:1px solid #DDD;font-size:14px;font-weight:normal;padding:13px 0 10px 8px;">您在<a style="text-decoration:none;color: #12ADDB;" href="${SITE_URL}" target="_blank">${SITE_NAME}</a>上的文章有了新的评论</h2><p><strong>${NICK}</strong>回复说:</p><div style="background-color: #f5f5f5;padding: 10px 15px;margin:18px 0;word-wrap:break-word;"> ${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}" target="_blank">查看回复的完整內容</a><br></p></div></div>

博主通知邮件模板中的可用变量与@通知中的基本一致,**PARENT_NICKPARENT_COMMENT 变量不再可用。**

这里还提供一个彩虹风格的@通知邮件模板代码:

<div style="border-radius: 10px 10px 10px 10px;font-size:13px;    color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="${SITE_URL}"> ${SITE_NAME}</a>上的留言有新回复啦!</p></div><div style="margin:40px auto;width:90%"><p>${PARENT_NICK} 同学,您曾在文章上发表评论:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${PARENT_COMMENT}</div><p>${NICK} 给您的回复如下:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}#comments">查看回复的完整內容</a>,欢迎再次光临<a style="text-decoration:none; color:#12addb"                href="${SITE_URL}"> ${SITE_NAME}</a></p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div></div>

效果如图:

彩虹模板

垃圾评论检测

Akismet (Automattic Kismet)是应用广泛的一个垃圾留言过滤系统,其作者是大名鼎鼎的WordPress 创始人 Matt Mullenweg,Akismet也是WordPress默认安装的插件,其使用非常广泛,设计目标便是帮助博客网站来过滤留言Spam。有了Akismet之后,基本上不用担心垃圾留言的烦恼了。 启用Akismet后,当博客再收到留言会自动将其提交到Akismet并与Akismet上的黑名单进行比对,如果名列该黑名单中,则该条留言会被标记为垃圾评论且不会发布。

如果还没有Akismet Key,你可以去 AKISMET FOR DEVELOPERS 免费申请一个当AKISMET_KEY设为MANUAL_REVIEW时,开启人工审核模式; 如果你不需要反垃圾评论,Akismet Key 环境变量可以忽略。

为了实现较为精准的垃圾评论识别,采集的判据除了评论内容、邮件地址和网站地址外,还包括评论者的IP地址、浏览器信息等,但仅在云引擎后台使用这些数据,确保隐私和安全。

如果使用了本站最新的Valine和Valine Admin,并设置了Akismet Key,可以有效地拦截垃圾评论。被标为垃圾的评论可以在管理页面取消标注。

环境变量 示例 说明
AKISMET_KEY xxxxxxxxxxxx [可选]Akismet Key 用于垃圾评论检测

手动配置邮件服务器

  • 自定义邮件服务器地址和端口信息,删除SMTP_SERVICE环境变量,新增以下变量:
变量 示例 说明
SMTP_HOST smtp.qq.com [可选]SMTP_SERVICE留空时,自定义SMTP服务器地址
SMTP_PORT 465 [可选]SMTP_SERVICE留空时,自定义SMTP端口
SMTP_SECURE true [可选]使用TLS

Troubleshooting

  • 部署失败,请在评论中附图,或去Github发起Issue
  • 邮件发送失败,确保环境变量都没问题后,重启云引擎 重启云引擎
  • 博主通知模板中不要出现PARENT*相关参数(请勿混用模板)
  • 点击邮件中的链接跳转至相应评论,这一细节实现需要在Web前端添加一点额外的代码:
<script>
    if(window.location.hash){
        var checkExist = setInterval(function() {
           if ($(window.location.hash).length) {
              $('html, body').animate({scrollTop: $(window.location.hash).offset().top-90}, 1000);
              clearInterval(checkExist);
           }
        }, 100);
    }
</script>

来自small-rose的模板

@邮件通知效果:

您在 ${SITE_NAME}上的留言有新回复啦!

${PARENT_NICK} 同学,您曾在文章上发表评论:

${PARENT_COMMENT}

${NICK} 给您的回复如下:

${COMMENT}

您可以点击查看回复的完整內容,欢迎再次光临 ${SITE_NAME}

@邮件通知模板代码:

<div style="border-radius: 10px 10px 10px 10px;font-size:13px; color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="${SITE_URL}"> ${SITE_NAME}</a>上的留言有新回复啦!</p></div><div style="margin:40px auto;width:90%"><p>${PARENT_NICK} 同学,您曾在文章上发表评论:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${PARENT_COMMENT}</div><p>${NICK} 给您的回复如下:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}#comments">查看回复的完整內容</a>,欢迎再次光临<a style="text-decoration:none; color:#12addb" href="${SITE_URL}"> ${SITE_NAME}</a></p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 0 0 10px 10px;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg,rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"></div></div>

博主通知效果:

您在 ${SITE_NAME}上的文章有了新的评论!

${NICK} 同学,发表评论说:

${COMMENT}

您可以点击查看回复的完整內容

<div style="border-radius: 10px 10px 10px 10px;font-size:13px; color: #555555;width: 666px;font-family:'Century Gothic','Trebuchet MS','Hiragino Sans GB',微软雅黑,'Microsoft Yahei',Tahoma,Helvetica,Arial,'SimSun',sans-serif;margin:50px auto;border:1px solid #eee;max-width:100%;background: #ffffff repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);"><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 10px 10px 0 0;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"><p style="font-size:15px;word-break:break-all;padding: 23px 32px;margin:0;background-color: hsla(0,0%,100%,.4);border-radius: 10px 10px 0 0;">您在<a style="text-decoration:none;color: #ffffff;" href="${SITE_URL}"> ${SITE_NAME}</a>上的文章有了新的评论!</p></div><div style="margin:40px auto;width:90%"><p><strong>${NICK}</strong> 同学,发表评论说:</p><div style="background: #fafafa repeating-linear-gradient(-45deg,#fff,#fff 1.125rem,transparent 1.125rem,transparent 2.25rem);box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);margin:20px 0px;padding:15px;border-radius:5px;font-size:14px;color:#555555;">${COMMENT}</div><p>您可以点击<a style="text-decoration:none; color:#12addb" href="${POST_URL}#comments">查看回复的完整內容</a></p><style type="text/css">a:link{text-decoration:none}a:visited{text-decoration:none}a:hover{text-decoration:none}a:active{text-decoration:none}</style></div><div style="width:100%;background:#49BDAD;color:#ffffff;border-radius: 0 0 10px 10px ;background-image: -moz-linear-gradient(0deg, rgb(67, 198, 184), rgb(255, 209, 244));background-image: -webkit-linear-gradient(0deg,rgb(67, 198, 184), rgb(255, 209, 244));height: 66px;"></div></div>

解决休眠

免费版的 LeanCloud 容器,是有强制性休眠策略的,不能 24 小时运行:

  • 每天必须休眠 6 个小时
  • 30 分钟内没有外部请求,则休眠。
  • 休眠后如果有新的外部请求实例则马上启动(但激活时此次发送邮件会失败)。

也就是如果服务器休眠了的话用户第一次评论是提醒不了的。

参考了Valine-Admin官网找到了解决办法。

首先在环境变量增加服务器地址,就是你的后台服务器地址

下面是你的服务器地址,可以自定义

同样登录后台

找到定时任务

然后点击创建任务,上面是我创建好的

选择self_wake函数,然后运行时间使用cron表达式

0 0/30 7-23 ? 表示每天6点到11点 每30分钟叫醒服务器一次

这样就完美的解决了服务器休眠的问题

那如果用户不在时间范围内发留言了怎么办?我们也可以创建一个捡漏的定时任务

创建捡漏定时任务

然后运行函数选择resend_mails,同样使用cron表达式

0 0 8 ?

表示每八个小时进行捡漏一次,这样如果有留言遗漏的话就能即使的提醒。

WakeLeanCloud

这个项目主要是用来解决LeanCloud通过定时任务唤醒机器时被流控的问题。

如何使用

  1. Fork此项目
  2. 添加一个名为GITHUB_TOKEN的Token,并为赋予repoadmin:repo_hookworkflow的权限
  3. 添加名为SITE的Secrets,内容为自己管理后台地址。多个请用英文逗号分隔

详细教程请参考优雅解决LeanCloud流控问题

让hexo支持pwa

pwa中文叫渐进式网页应用,pwa网站可以直接添加网址站到桌面,就相当于在系统中直接安装了一个app,打开的效果也和app差不多,加载速度也很快,部分功能可以直接离线使用。Google的Workbox标准,目前来看需要Chrome支持

  • hexo-pwa 很久没更新,看到资料都是支持4.x版本hexo。
  • hexo-offline 亲自验证,支持最新5.x的hexo。

安装hexo-offline

npm install hexo-offline --save

关于这个插件的详细使用方法可以看下面这里

https://github.com/JLHwung/hexo-offline

配置hexo-offline

之后我们在站点根目录_config.yml如下配置

# offline config passed to sw-precache.
service_worker:
  maximumFileSizeToCacheInBytes: 5242880
  staticFileGlobs:
  - /**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff,woff2}
  - /lib/**/*.js
  - /lib/**/*.css
  - /images/*
  - /js/src/**/*.js
  stripPrefix: public
  verbose: true
  runtimeCaching:
    - urlPattern: /*
      handler: cacheFirst
      options:
        origin: cdn.bootcss.com

注意哦不是主题的_config.yml文件

之后生成manifest.json文件,可以在这个网站在线生成。

填入相关的参数,如下

Tips: 一定需要一个512x512的icon!

之后点击generate.zip 把配置都下载过来

把manifest.json和images文件夹直接复制到hexo下source文件夹中,最后我们编辑主题,在head里添加

<link rel="manifest" href="/manifest.json">

如果使用的是hexo next主题,在

themes/next/layout/_partials/head/head.swig

如果使用的是hexo matery主题,在

themes/matery/layout/_partial/head.ejs

这个文件中添加上面这句话即可,最后直接重新生成站点,部署即可

验证和使用

需要https访问,看到这个齿轮

F12 sources

然后在浏览器地址栏可以看到应用标志

Tips: offline 需要https才能正常使用

地址栏

点击打开,会看到如下结果,试一下?

离线博客

valine 的使用与升级到1.4

一、valine启用

1、主要流程

valine和miniValine使用基本类似。

(1)去 Leancloud注册。

注意事项:

节点选择:华东节点、华北节点、国际版。

如果你的域名没有备案,建议选择国际版。 因为华东或华北节点在安装评论系统之后访问要求域名备案。

(2)在“设置“,”应用 Keys”,找到你的appidappkey,配置到主题中valine配置的地方,启用valine

(3)在“设置“,”安全中心”,”Web 安全域名”,添加自己的域名。

(4)在“设置“,”安全中心”,”服务开关”,数据存储要打开。

(5)在“存储“,”用量统计”,”HTTP状态码”,启用,方便后续报错查错误码。

(6)重新编译部署hexo clean & hexo g & hexo d

2、遇到问题

搞这个东西采坑不少,有些坑都是自己不小心造成的。我在网上查了,交流群里也咨询请教了,没有人能解决这个问题,毕竟这个坑是自己造成的。

常见Code 403问题:

Code 403: 访问被api域名白名单拒绝,请检查你的安全域名设置.

网上多数的说法是在web安全域名中添加自己的域名。可是如果添加之后还是这个问题呢?

其实一般不会有这个问题,我有这个问题是我改了权限造成了。

官方给的解释:

应用在控制台中的相关服务选项未打开,如 Class 关闭了权限,或是 User 缺失了 session 信息等情况下,云端会统一地返回 403 错误码及不同的错误信息,代表当前请求因权限不够而被拒。例如:

信息 - Forbidden to read/write by class permissions
含义 - 操作被禁止,因为 Class 表没有打开「读」或者「写」的权限。进入 控制台 > 存储,点击相应的 Class,从右侧选择 其他 下拉菜单,进入 权限管理 来调整。

信息 - The user cannot be altered by a client without the session.
含义 - 用户没有登录,无法修改用户信息。

解决:

(1)首次使用,添加一条评论,一般添加之后就会好了。

(2)后续使用,403,请检查comment表的add_fields/create/find权限开放。

(3)如果还是不行将_use表的add_fields/create/find权限开放。

(4)如果还是不行,到“存储“,”用量统计”,”HTTP状态码”处,检查你的错误码,然后去LeanCloud的错误找应用的错误码,排查原因吧。

二、valine升级

1、引入1.4版的js文件

(1)修改主题配置文件

js:
  valine: https://unpkg.com/valine/dist/Valine.min.js #/libs/valine/Valine.min.js 

(2)将文件放你自己的仓库

下载我的 Valine.min.js 文件,直接替换你主题目录 /source/libs/valine/ 下的 Valine.min.js 文件。

注意,如果你担心替换有问题,可以先备份一下你自己的 Valine.min.js 文件。

2、增加valine的配置:

1.4的版本有些属性调整了,主题下的_config.ymlvaline属性如下:

valine:
  enable: true
  appId: iTxfqh5e9IaRfiiVOTbIWoKa-XXXXXX
  appKey: C5s5xGFErD1EtXXXXXXXX
  verify: true  # 是否启用防垃圾验证
  notify: true  # 是否开启邮件提醒(https://valine.js.org/notify.html)
  visitor: true
  avatar: monsterid  # 头像样式(https://valine.js.org/avatar.html) 
  pageSize: 10
  placeholder: 'ヾノ≧∀≦)o来啊,快活啊!' # Comment Box placeholder
  background: /medias/comment_bg.png #背景图
  count: true
  enableQQ: 970175021
  recordIP: true
  requiredFields: 
    - nick
    - mail
  guest_info: 
    - nick
    - mail
    - link
  master: 
    - 123abc508165c8eba9a77f872xxxx046  # md5加密后的博主邮箱
  metaPlaceholder:  # 输入框的背景文字
    nick: 昵称/QQ号(必填)
    mail: 邮箱(必填)
    link: 网址(https://)
  lang: zh-CN
  tagMeta: # The String Array of Words to show Flag.[Just Only xCss Style mode]
    - 博主
    - 小伙伴
    - 访客
  friends: # The MD5 String Array of friends Email to show friends Flag.[Just Only xCss Style mode]
    - c08508165c8eba9a77f8c2853xxxx09e
    - 901345d4c91ddfd8db0f175bbcfff0c8
    - 1512958e18378c98b498d5effe3e76ff

复制代码注意缩进对齐,不对齐可能会报错,请自行检查对齐。

3、修改valine.ejs

Matery 主题使用的ejs模板预编译,如果你使用了pug或者swig等其他的模板语言,请修改成对应语言语法即可。

原始的valine.ejs

new Valine({
        el: '#vcomments',
        appId: '<%- theme.valine.appId %>',
        appKey: '<%- theme.valine.appKey %>',
        notify: '<%- theme.valine.notify %>' === 'true',
        verify: '<%- theme.valine.verify %>' === 'true',
        visitor: '<%- theme.valine.visitor %>' === 'true',
        avatar: '<%- theme.valine.avatar %>',
        pageSize: '<%- theme.valine.pageSize %>',
        lang: '<% if (config.language == "zh-CN") {  %>zh-cn<% } else { %>en<% } %>',
        placeholder: '<%= theme.valine.placeholder %>'
    });

升级后的valine.ejs

let metaPlaceholder = <%-  JSON.stringify(theme.valine.metaPlaceholder) %> ;
//这里要换行
new Valine({
        el: '#vcomments',
        appId: '<%- theme.valine.appId %>',
        appKey: '<%- theme.valine.appKey %>',
        notify: '<%- theme.valine.notify %>' === 'true',
        verify: '<%- theme.valine.verify %>' === 'true',
        visitor: '<%- theme.valine.visitor %>' === 'true',
        avatar: '<%- theme.valine.avatar %>',
        pageSize: '<%- theme.valine.pageSize %>',
        lang: '<%- theme.valine.lang %>',
        placeholder: '<%= theme.valine.placeholder %>',
        meta: <%- '["' + theme.valine.guest_info.join('", "') + '"]' %>,
        recordIP: '<%- theme.valine.recordIP %>' === 'true',
        enableQQ: '<%- theme.valine.avatar %>',
        requiredFields: <%- '["' + theme.valine.master.join('", "') + '"]' %>,
        master: <%- '["' + theme.valine.master.join('", "') + '"]' %>,
        friends: <%- '["' + theme.valine.friends.join('", "') + '"]' %>,
        tagMeta: <%- '["' + theme.valine.tagMeta.join('", "') + '"]' %>,
        metaPlaceholder: metaPlaceholder,

    });

如果需要验证昵称和邮箱可以加上以下代码:

document.body.addEventListener('click', function(e) {
    if (e.target.classList.contains('vsubmit')) {
        const email = document.querySelector('input[type=email]');
        const nick = document.querySelector('input[name=nick]');
        const reg = /^[A-Za-z0-9_-\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
        if (!email.value || !nick.value || !reg.test(email.value)) {
            const str = `<div class="valert txt-center"><div class="vtext">请填写正确的昵称和邮箱!</div></div>`;
            const vmark = document.querySelector('.vmark');
            vmark.innerHTML = str;
            vmark.style.display = 'block';

            e.stopPropagation();

            setTimeout(function() {
                vmark.style.display = 'none';
                vmark.innerHTML = '';
            }, 2500);
        }
    }
    }, true);

说明:代码非原创,JS正则验证本身也不难。

好了可以部署之后自己测试一下。

顺便说一下,填写昵称邮箱和网址的地方如果折行了就按我的样式改一下就好:

valine.ejs 是上面对着改一下就好了:

.v[data-class="v"] .vwrap .vheader .vinput {
  width: 32%;
  border-bottom: 1px dashed #dedede;
}

新建文章自动打开本地Markdown编辑器

写新文章时,需要控制台执行hexo new “文章名字”生成一篇新文章,但需要手动打开,挺麻烦,我们可以设置在生成之后自动打开。

注意,node 和Marddownb编辑器需要在同一个主机环境下面脚本才能运行。所有使用docker的,远程ssh的都不能用这个。

在站点根目录下新建scripts目录,然后在新建auto_open.js,在文件填入一下内容

var spawn = require('child_process').exec;

// Hexo 2.x 用户复制这段
//hexo.on('new', function(path){
  //spawn('start  "markdown编辑器绝对路径.exe" ' + path);
//});

// Hexo 3 用户复制这段
hexo.on('new', function(data){
  spawn('start  "D:\Program Files\Typora\Typora.exe" ' + data.path);
});

其中”D:\Program Files\Typora\Typora.exe”是我本地编辑器的路径,只需要改为你本地编辑器的路径即可,然后在执行hexo cl && hexo g -d,部署到GitHub即可,以后在新建文章就会自动打开编辑器。

常见问题

通过hexo g -d部署时报Error: Spawn failed错误:

这是由于 git 本地记录的提交版本号与 github 上不一致导致的,通过git reset --hard commitCode即可解决。

  • 检查本地最近提交记录,获取最后一次提交记录的更新时间及标识,如280a7fdd46fcfd7d34e652aec15523dcd247fac8
cd .deploy_git
cat .git/logs/HEAD
  • 获取 github pages 服务所关联分支的最近一次提交记录,获取更新时间及标识。地址一般为:https://github.com/用户名/仓库名/commits/分支名,如https://github.com/lxl80/blog/commits/gh-pages
  • 如果发现提交最新的提交时间/标识不一致,通过以下命令即可解决:
git reset --hard f085038efdf79546c09641d37b2a2429c1ae8e60 #github上最新的提交标识

fsevents报错

npm ERR! code EBADPLATFORM npm ERR! notsup Unsupported platform for
fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current:
{"os":"win32","arch":"x64"}) npm ERR! notsup Valid OS:    darwin npm
ERR! notsup Valid Arch:  any npm ERR! notsup Actual OS:   win32 npm
ERR! notsup Actual Arch: x64

解决方法:修改package.json

"optionalDependencies": {
  "fsevents": "^2.3.2"
},

关于百度无法爬取GitHub内容解决方案

  • 使用coding搭建一个可以被百度爬取到的代码托管平台
  • 使用vps搭建一个hexo 镜像访问,专门针对搜索引擎。

Tips: 博主用了第二种方法,2个域名,前端域名用dnspod,采用cloudflare parter cname接入。dnspos有选路选择,针对搜索引擎进入vps搭建的blog,对于其它线路到cloudflare parter 加速过的github pages cname。后端域名用cloudflare parter 以及免费版cloudflare管理。

既然百度无法爬取GitHub,那么我们只需要找个可以被百度爬取到的代码托管平台即可(并且还提供pages服务),基本只有国内的平台了:GiteeCoding!Gitee自定义域名要花钱(九十多,都可以买服务器了),而Coding是可以免费自定义域名的。这里推介大家使用企业版的Coding,因为企业版的Coding仓库服务器是在香港的,而普通版的服务器是在新加坡。地理原因,理论上企业版的更快一些!

  1. 将博客同时部署到两个仓库:GitHub和Coding

    deploy:
    - type: git
      repository: git@github.com:xxx/xxx.github.io.git
      branch: master
    
    - type: git
      repository: git@e.coding.net:xxx/xxx.git
      branch: master
  2. 在域名那里,配置两个解析

    线路类型作用:如果该值填“国内”,国内的IP就会去访问此项对应的记录值地址

    同理,如果该值填写“国外”,国外的IP就会去访问“国外”对应的记录值地址

    1. 线路类型百度或者国内,记录值为Coding仓库的地址
    2. 线路类型默认或者国外,记录值为GitHub仓库地址

  3. 这样来自百度的spider就会去爬国内Coding的地址,而两个仓库的内容又都是一样的,如果请求IP来自国外,它又会去访问国外的GitHub,这样还有利于外国华侨和那些科学上网的用户访问,一石二鸟!(我真他妈天才!)

  4. 如果你只用Coding仓库,那就不需要这么麻烦了

  5. 测试百度Spider能不能爬你的域名

    1. 在任意目录下执行以下命令(将“你的域名”换成你的域名)

      curl -A "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" -o example.html 你的域名
    2. 执行完命令,在该目录下会生成一个文件:example.html,打开它,如果显示

      • Moved Permanently,说明301,被重定向了

      • Found,也就是爬到了

      • 如果打开是你的首页,说明爬取到的内容就是你的首页HTML内容。

      • 如果显示:

        说明域名是解析到GitHub的,403Forbidden访问禁止。

busuanzi不蒜子计数显示异常,一闪就没

  1. 原因可能有两种live2d看板娘和busuanzi不蒜子计数冲突

  2. busuanzi不蒜子网络访问异常。

  1. 不在leancloud安全名单

  2. 不是正常域名访问

  3. 各种网络访问错误等等

近日安装了live2d看板娘插件,github项目地址,安装后却意外发现busuanzi不蒜子计数失效了,在页面中不显示,但强制刷新后出现,再刷新又消失。经排查,未发现问题,但事实是网站源码出现了变化。

正常时

<div id="busuanzi_container_page_pv" class="info-break-policy" style="display: inline;">
    <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
    <span id="busuanzi_value_page_pv">433</span>

异常时

<div id="busuanzi_container_page_pv" class="info-break-policy" style="display: none;">
    <i class="far fa-eye fa-fw"></i>阅读次数:&nbsp;&nbsp;
    <span id="busuanzi_value_page_pv">434</span>

对比发现出现了多余的style="display: none;
经过搜索主题源码,发现这个文件themes\matery\source\libs\others\busuanzi.pure.mini.js控制显示。

可以直接下载下面这个地址的js替换,来自个人blog的js busuanzi.pure.mini.js,直接下载这个js替换即可。下面源码经过了展开美化,原始文件是压缩去空格版本的。
注意: 这是一种破坏性修复,没有解决根本问题,临时修复方案。

var bszCaller, bszTag;
! function () {
    var c, d, e, a = !1,
        b = [];
    ready = function (c) {
        return a || "interactive" === document.readyState || "complete" === document.readyState ? c.call(document) :
            b.push(function () {
                return c.call(this)
            }), this
    }, d = function () {
        for (var a = 0, c = b.length; c > a; a++) b[a].apply(document);
        b = []
    }, e = function () {
        a || (a = !0, d.call(window), document.removeEventListener ? document.removeEventListener(
            "DOMContentLoaded", e, !1) : document.attachEvent && (document.detachEvent("onreadystatechange",
            e), window == window.top && (clearInterval(c), c = null)))
    }, document.addEventListener ? document.addEventListener("DOMContentLoaded", e, !1) : document.attachEvent && (
        document.attachEvent("onreadystatechange", function () {
            /loaded|complete/.test(document.readyState) && e()
        }), window == window.top && (c = setInterval(function () {
            try {
                a || document.documentElement.doScroll("left")
            } catch (b) {
                return
            }
            e()
        }, 5)))
}(), bszCaller = {
    fetch: function (a, b) {
        var c = "BusuanziCallback_" + Math.floor(1099511627776 * Math.random());
        window[c] = this.evalCall(b), a = a.replace("=BusuanziCallback", "=" + c), scriptTag = document.createElement(
                "SCRIPT"), scriptTag.type = "text/javascript", scriptTag.defer = !0, scriptTag.src = a,
            document.getElementsByTagName("HEAD")[0].appendChild(scriptTag)
    },
    evalCall: function (a) {
        return function (b) {
            ready(function () {
                try {
                    a(b), scriptTag.parentElement.removeChild(scriptTag)
                } catch (c) {
                    bszTag.hides()
                }
            })
        }
    }
}, bszCaller.fetch("//busuanzi.ibruce.info/busuanzi?jsonpCallback=BusuanziCallback", function (a) {
    bszTag.texts(a), bszTag.shows()
}), bszTag = {
    bszs: ["site_pv", "page_pv", "site_uv"],
    texts: function (a) {
        this.bszs.map(function (b) {
            var c = document.getElementById("busuanzi_value_" + b);
            c && (c.innerHTML = a[b])
        })
    },
    hides: function () {
        this.bszs.map(function (a) {
            var b = document.getElementById("busuanzi_container_" + a);
            b && (b.style.display = "")
        })
    },
    shows: function () {
        this.bszs.map(function (a) {
            var b = document.getElementById("busuanzi_container_" + a);
            b && (b.style.display = "inline")
        })
    }
};

替换的人请操作其实就是把其中的b.style.display="none"none去掉。

不蒜子 (busuanzi) 文章计数出错问题

出现这个原因,和 Chrome 85 版本 Referrer Policy 更改有关。什么是 Referrer,简单理解,就是请求 Web 服务器时,可以在 HTTP Request 的请求头 (header) 中加上当前页面的 URL,例如我们在浏览某个博客页面,需要加载一些图片,从服务器请求这些图片时,referrer 就是当前的博客页面 URL。从这里也可以看出,referrer 可能会暴露请求来源的某些信息或者隐私,有一定的隐私或安全风险。之前版本的 Chrome 浏览器,如果网站没有指定自己的 Referrer Policy,那么 Chrome 默认 policy 是 no-referrer-when-downgrade,在 Chrome 85 版本中,为了保护用户的隐私,默认的 Referrer Policy 则变成了 strict-origin-when-cross-origin。

  • no-referrer-when-downgrade: 当两个网站的 http 协议安全等级相当,或者目的网站安全协议等级高于当前网站(HTTP –> HTTP, HTTPS –> HTTPS, HTTP –> HTTPS), referer 将会包含源网站的域名,路径,查询字符串;如果目的网站安全协议等级低于源网站 (HTTPS –> HTTP),将不会发送这些信息。
  • strict-origin-when-cross-origin: 只有当做同一域名请求时 (源网址和目标网址是同一域名),才发送域名,路径和请求字符串,当两个网站安全协议相当时,发送源网站的域名(没有具体路径信息和查询字符串),如果目标网站安全协议等级低于源网站,不发送 header 信息。

不蒜子统计博客文章访问量就是通过 referer 来计算的,通过上面的分析,如果 Referrer Policy 是 strict-origin-when-cross-origin,不蒜子接收到的只有博客的域名,没有文章的具体路径,所以具体某个文章的 PV 统计会出现错误。

修复方法:

在主题文件夹下/layout/_partial/head.ejs中添加

<meta name="referrer" content="no-referrer-when-downgrade">

如何多个域名映射同一个github pages

可能由于某种原因,换了一个域名,之前又有一些被搜索引擎收录,但是又不想让原来的链接失效,就需要让两个域名都映射到github pages中。本文介绍几种当前可能的方法。欢迎提出更多有效方法。

直接映射有什么问题?

你可能会想,两个域名都映射到github pages不就可以了?然而事实并非如此。首先当前github 的CNAME中只支持一个域名。因此CNAME文件中只能有一个域名,而如果在域名映射中将两个域名都映射到username.github.io,那么其中有一个会出现404错误。

前提

以下方法的前提是你已经明白如何为自己的github pages添加自定义域名。

需要注意什么?
  • 需要给各大网站提交新的域名网址,重新被收录
  • 域名变换前面网站的内容结构不能变,否则重定向也没有意义
  • 当前单纯的域名没有办法进行备案
  • 注意修改配置文件里的主域名为新的域名
  • 由于更换了新的域名,导致原来leancloud统计的访问数据需要重新计算,也就是网站访问量被清零了,leancloud也需要更新域名
  • 新的com域名可申请免费的SSL证书,保证https可访问,而不会提示不安全
  • 301重定向会将旧地址的权重转义到新地址上
  • 百度收录速度较慢
方法一:域名托管平台重定向

有的域名服务商提供重定向功能,以阿里云为例,在域名映射添加记录的时候,可以选择显性URL或隐性URL。但是自己在尝试这种方法的时候,会提示我URL备案异常。可能是由于这个时候已经用新的域名映射了博客地址,但是新的域名实际上是没有备案的。更无奈的是,目前貌似没有办法单独对域名进行备案。因此本人放弃了该方法。

如果你的博客也是部署在github上的,那么这种方法就不用尝试了,如果你的博客是部署在自己的服务器上的,那么网上都很多方法,这里就不介绍了。

方法二:部署两个仓库

我们注意到,除了github pages,还有coding.net可用。它与github类似。原来的域名映射到这个地址就可以了。而在部署hexo的时候,是可以添加两个仓库地址的:

deploy:
- type: git
  repository: git@github.com:username/username.github.io.git
  branch: master
- type: git
  repository: git@git.coding.net:username/username.git
  branch: coding-pages

这两个仓库内容唯一的差别就是域名不一样,即CNAME中的记录值不一样。这样当访问两个不同的域名的时候,是访问不同的两个平台仓库。但是原来域名的权重不会转到新的域名中去。

方法三:新增项目重定向

假如你已经有username.github.io项目,新建一个名为blog(名字自定义)的项目,在项目的setting中,开启github pages服务,并且将旧的域名映射到username.github.io。

实际上,github pages并不是只能有一个,例如,你新创建的仓库访问地址为:username.github.io/blog。
由于旧的域名映射会导致404错误,那么在我们的新项目中增加一个404.html,在页面中进行跳转即可:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
 <script language="javascript">
var domain = "换成你自己的新域名";
var src = window.location.href;
var prtc = src.substring(0, src.indexOf(':'));
var target = src.substring(src.indexOf('/', src.indexOf(':') + 3));
window.location.href = prtc + "://" + domain + target;
location.href=prtc + "://" + domain + target;
</script>
<body>
 <h1></h1>
</body>
</html>

另外,需要利用google的地址更改功能,使得旧网址的权重往新网址转移。
找到search console中的地址更改工具(设置按钮中找到)。

除了增加404页面外,还需要增加CNAME文件,里面的内容是你原先的域名。

参照


文章作者: 夜法之书
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 夜法之书 !
评论
  目录