加载中...

基于Hexo的matery主题搭建博客个性定制篇5


Hexo系列 HexoRSS分类订阅

[三万字教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程

  • markdown 各种其它语法插件
  • latex公式支持
  • mermaid图表
  • plant uml图表
  • URL卡片
  • bilibili卡片
  • github卡片
  • 豆瓣卡片
  • 插入音乐和视频
  • 插入脑图

多种主题美化

修改主题颜色

配色包括导航栏,底部栏,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 { 
	/* 动态切换背景颜色. */ 
}

背景樱花飘落效果

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/[email protected]/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
#安装下载动画人物库, 动画人物有很多, 可以网上查询资料, 下面推荐几种.
npm install --save live2d-widget-model-shizuku #课桌女孩
npm install --save live2d-widget-model-hibiki  #御姐
npm install --save live2d-widget-model-wanko   #狗狗
npm install --save live2d-widget-model-haruto  #海军服女孩
npm install --save live2d-widget-model-miku    #萝莉

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

$ npm install live2d-widget-model-shizuku

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

使用本地模型方式:

## 添加动画live2d模块  npm install --save hexo-helper-live2d
## 下载动画人物库 npm install live2d-widget-model-z16 -D
live2d:
  enable: true
  scriptFrom: local # 默认
  pluginRootPath: live2dw/ # 插件在站点上的根目录(相对路径)
  pluginJsPath: lib/ # 脚本文件相对与插件根目录路径
  pluginModelPath: assets/ # 模型文件相对与插件根目录路径
  tagMode: false # 标签模式, 是否仅替换 live2d tag标签而非插入到所有页面中
  debug: false # 调试, 是否在控制台输出日志
  model:
    use: live2d-widget-model-miku
  display:
    position: right #动画位置
    width: 150
    height: 190
    # 位置配置,这个在左侧边栏位置很居中
    hOffset: 50  # 调节水平位置
    vOffset: -5  # 调节垂直位置
  mobile:
    show: false # 是否在移动设备上显示
    scale: 0.5 # 移动设备上的缩放
  react:
    opacityDefault: 0.7
    opacityOnHover: 0.8

使用网络模型方式:

# 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/[email protected]/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-[email protected]/assets/wanko.model.json # Your custom url
  display:
    position: left
    width: 300
    height: 400
    hOffset: 50
    vOffset: 10
  mobile:
    show: false

见右下角

Live2D看板娘

更强大的看板娘

live2d-widget 原作者教程

支持换装,模型切换,对话框,拍照,小游戏,眼神跟随,触摸对话,音频等。

可以自建api,自定义各种模型,各种对话等。

live2d看板娘

live2d-widget效果图

依赖 Font Awesome

请在 <head> 中加入。在Matery中自带,这一步跳过。

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css">

使用 Usage

将这一行代码加入 <head><body>,即可展现出效果:

<script src="https://cdn.jsdelivr.net/gh/17lai/[email protected]/autoload.js"></script>

后端 API

initWidget 方法接受名为 apiPathcdnPath 的参数,两者设置其中一项即可。其中 apiPath 为后端 API 的 URL,可以自行搭建,并增加模型(需要修改的内容比较多,此处不再赘述)。而 cdnPath 则是通过 jsDelivr 这样的 CDN 服务加载资源,更加稳定。

目录结构 Files

  • waifu-tips.js 包含了按钮和对话框的逻辑;
  • waifu-tips.json 中定义了触发条件(selector,CSS 选择器)和触发时显示的文字(text);
  • waifu.css 是看板娘的样式表。

使用 waifu-tips.json 自定义 selector触发提示文字框,可以用来做菜单,按钮的导航提示,终于是个合格的看板娘了!

  • 对所有菜单,常用按钮做了基本文字提示。鼠标去到处戳一下,看看触发提示!😄
  • 这是一个不小的工程,难度不高,趣味性很强。

看板娘触发文字提示

添加夜间模式切换

  • 下面这个还远未完善,只是基本可用,很多显示细节还需要调整。

  • 博主业余钻研ccs教程,慢慢修改完善中。

在主题目录下的/layout/layout.ejs文件添加夜间模式切换按钮:

<!-- 切换夜间/白天模式按钮 -->
<a onclick="switchNightMode()" id="sma"> <i class="fa fa-moon-o" id="nightMode" aria-hidden="true"></i> </a>

在主题目录下的/source/js/matery.js文件添加js代码:

// 深色模式按钮设置
if (localStorage.getItem('dark') === '1') {
    document.body.classList.add('dark');
} else if (new Date().getHours() >= 22 || new Date().getHours() < 7) {
    /*定时开启暗色模式<默认晚22点至早6点默认开启>*/
    // document.body.classList.add('dark');
    // $("#nightMode").removeClass("fa-moon-o").addClass("fa-lightbulb");
} else if (matchMedia('(prefers-color-scheme: dark)').matches) {
    document.body.classList.add('dark');
}

// 深色模式设置
function switchNightMode() {
    var body = document.body;
    if (body.classList.contains('dark')) {
        document.body.classList.remove('dark');
        localStorage.setItem('dark', '0');
        $('#nightMode').removeClass("fa-lightbulb").addClass("fa-moon-o");
        return;
    } else {
        document.body.classList.add('dark');
        localStorage.setItem('dark', '1');
        $('#nightMode').removeClass("fa-moon-o").addClass("fa-lightbulb");
        return;
    }
}

/*提醒开启夜间模式功能*/
setTimeout(
    function () {
        if ((new Date().getHours() >= 19 || new Date().getHours() < 7) && !$('body').hasClass('DarkMode')) {
            let toastHTML = '<span style="color:#97b8b2;border-radius: 10px;>'
                + '<i class="fa fa-bell" aria-hidden="true"></i>晚上使用深色模式阅读更好哦。(゚▽゚)/</span>'
            M.toast({html: toastHTML})
        }
    }, 2200);

在主题目录下的/source/css/matery.css文件添加夜间模式切换的样式:

/******夜间模式切换样式 start*******/
/* 深色模式按钮设置 */
#sma {
    background: #000;
    width: 38px;
    height: 38px;
    display: block;
    position: fixed;
    border-radius: 50%;
    right: 15px;
    bottom: 170px;
    padding-top: 15px;
    margin-bottom: 0;
    z-index: 998;
    cursor: pointer;
}

#sma .fa-moon-o {
    position: absolute;
    right: 8px;
    bottom: 8px;
    font-size: 1.48rem !important;
}

#sma .fa-lightbulb {
    position: absolute;
    right: 13px;
    bottom: 8px;
    font-size: 1.5rem !important;
}

.fa-moon-o:before {
    content: "\f186";
}

.fa-comments:before {
    content: "\f086";
}

/* 深色模式设置 */ /* 字体颜色变灰白色 */
body.dark .fas,
body.dark .title,
body.dark .row .text,
body.dark article .article-content .summary,
body.dark .card .card-image .card-title,
body.dark .fa-moon-o:before,
body.dark .fa-lightbulb:before,
body.dark article .article-tags .chip,
body.dark .chip-container .tag-title,
body.dark div.jqcloud a,
body.dark .friends-container .tag-title,
body.dark .frind-ship .title h1,
body.dark .card .card-content p,
body.dark .v[data-class=v] .vcount,
body.dark .v[data-class=v] .vcount .vnum,
body.dark pre code,
body.dark h1,
body.dark h2,
body.dark h3, body.dark h4,
body.dark h5,
body.dark h6, body.dark li,
body.dark p,
body.dark header .side-nav .mobile-head .logo-name,
body.dark header .side-nav .mobile-head .logo-desc,
body.dark header .side-nav .menu-list a,
body.dark .bg-cover .post-title,
body.dark a {
    color: rgba(255, 255, 255, 0.6);
}

/* 背景颜色变灰色 */
body.dark .card,
body.dark .block-with-text:after {
    background-color: #282c34;
}

/* 背景颜色变黑色 */
body.dark,
body.dark .v[data-class=v] .vcount,
body.dark #rewardModal .modal-content,
body.dark .modal,
body.dark header .side-nav,
body.dark header .side-nav .menu-list .m-nav-show {
    background-color: #12121c;
   /**因为我的背景图导致部分页面无法全部切换成深色背景, 需要取消背景图片**/
    background-image: url(#); 
}

/* 改变透明度 */
body.dark .aplayer {
    background: #2f3742 !important;
}

body.dark img, body.dark strong {
    filter: brightness(.7);
}
/******夜间模式切换样式 end*******/

Tag标签外挂使用方法

Tag标签外挂使用方法

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

图片懒加载

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

  • Don't worry about lazyload SEO problem, because Google supports it already.

那么,赶快用起来吧!

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

npm install hexo-lazyload-image --save
#或者使用yarn
yarn add hexo-lazyload-image

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

lazyload:
  enable: true  # 是否开启图片懒加载
  onlypost: false  # 是否只对文章的图片做懒加载
  loadingImg: # eg ./images/loading.gif
  isSPA: false # optional. For performance considering, isSPA is added. If your theme is a SPA page, please set it as true
  preloadRatio: 3 # optional, default is 1

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

存在问题:

查看大图,发现全部为 loading 加载图,原因是因为懒加载插件与 lightgallery 插件冲突,解决办法如下:

修改主题文件下的 matery.js,在 108 行左右添加以下代码:

$(document).find('img[data-original]').each(function(){
        $(this).parent().attr("href", $(this).attr("data-original"));
});

specify no-lazy for specify image

we can also disable the lazy process if specify a attribute on img tag in both markdown or html

<img no-lazy src="abc.png" />

外链跳转插件

使用 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 了。
  • libs/fancybox/jquery.fancybox.css

    https://blog.17lai.site/libs/fancybox/jquery.fancybox.css

  • libs/justifiedGallery/justifiedGallery.min.css:

    https://blog.17lai.site/libs/justifiedGallery/justifiedGallery.min.css

  • matery/source/js/crypto-js.js:

    https://blog.17lai.site/js/crypto-js.js

  • matery/source/js/gallery-encrypt.js:

    https://blog.17lai.site/js/gallery-encrypt.js

  • libs/fancybox/fancybox.js:

    https://blog.17lai.site/libs/fancybox/fancybox.js

  • libs/justifiedGallery/justifiedGallery.min.js:

    https://blog.17lai.site/libs/justifiedGallery/justifiedGallery.min.js

添加相册 json 配置文件

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

[
    {
      "name": "2020",
      "cover": "/medias_webp/images/01.webp",
      "description": "我的图床",
      "photos": [
        "/medias_webp/images/01.webp",
        "/medias_webp/images/02.webp",
        "/medias_webp/images/03.webp"
      ]
    },
    {
      "name": "2021",
      "cover": "/medias_webp/featureimages/1.webp",
      "description": "featureimages 图片展示",
      "photos": [
        "/medias_webp/featureimages/1.webp",
        "/medias_webp/featureimages/2.webp",
        "/medias_webp/featureimages/3.webp",
        "/medias_webp/featureimages/4.webp",
      ]
    },
    {
      "name": "2022",
      "cover": "/medias_webp/banner/0.webp",
      "description": "banner 图片展示",
      "photos": [
        "/medias_webp/banner/0.webp",
        "/medias_webp/banner/1.webp",
        "/medias_webp/banner/2.webp",
      ]
    }
]

字段含义:

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

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

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

2021/index.md2022/index.md文件内容和上面一样,只是title修改不同而已

galleries 目录结构

galleries
├── 2020
│   └── index.md
├── 2021
│   └── index.md
├── 2022
│   └── index.md
├── index.md

查看效果

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

hexo clean && hexo g && hexo s

我的效果

新增折叠功能

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

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

安装插件

npm install hexo-sliding-spoiler --save

配置插件

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

plugin:
- hexo-sliding-spoiler

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

进一步完善美化

修改[email protected]@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博客支持通知功能

更新文章后,自动发消息给订阅用户的浏览器!

国外非常火的低成本客户召回方式,增加用户粘性。

Tips: 如果访问不了订阅服务器,就不可用这个通知功能了!

安装插件

插件的 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

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

推荐使用这个 HCLonely/Valine-Admin

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

img

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

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

img

接下来输入分支为master

img

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

环境变量

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

img

  • 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

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

img

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

然后看一下效果

img

还不错

自定义后台

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

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

img

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

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

更多设置

邮件通知模板

HCLonely/Valine-Admin 时使用这个

邮件通知演示

评论通知模板

<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%, 0.4);
                                        border-radius: 10px 10px 0 0;
                                    "
                                >
                                    您在<a style="text-decoration: none; color: #ffffff" href="<%=siteUrl%>"> <%=siteName%> </a>上的留言有新回复啦!
                                </p>
                            </div>
                            <div style="margin: 40px auto; width: 90%">
                                <p><%=pname%> 同学,您曾在文章上发表评论:</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;
                                    "
                                >
                                    <%-ptext%>
                                </div>
                                <p><%=name%> 给您的回复如下:</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;
                                    "
                                >
                                    <%-text%>
                                </div>
                                <p>
                                    您可以点击 <a style="text-decoration: none; color: #12addb" href="<%=url%>">查看回复的完整內容 </a>,欢迎再次光临
                                    <a style="text-decoration: none; color: #12addb" href="<%=siteUrl%>"> <%=siteName%> </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>

博主回复通知模板

<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%, 0.4);
                                        border-radius: 10px 10px 0 0;
                                    "
                                >
                                    您的<a style="text-decoration: none; color: #ffffff" href="<%=siteUrl%>"> <%=siteName%> </a>上有新的评论啦!
                                </p>
                            </div>
                            <div style="margin: 40px auto; width: 90%">
                                <p><%=name%> 发表评论:</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;
                                    "
                                >
                                    <%-text%>
                                </div>
                                <p><a style="text-decoration: none; color: #12addb" href="<%=url%>" target="_blank">[查看评论]</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>

使用 DesertsP/Valine-Admin 时使用下面配置

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

环境变量示例说明
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

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地址、浏览器信息等,但仅在云引擎后台使用这些数据,确保隐私和安全。

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

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

手动配置邮件服务器

  • 自定义邮件服务器地址和端口信息,删除SMTP_SERVICE环境变量,新增以下变量:
变量示例说明
SMTP_HOSTsmtp.qq.com[可选]SMTP_SERVICE留空时,自定义SMTP服务器地址
SMTP_PORT465[可选]SMTP_SERVICE留空时,自定义SMTP端口
SMTP_SECUREtrue[可选]使用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>

@邮件通知效果:

您在[ ${SITE_NAME}](https://blog.17lai.site/posts/40300608/${SITE_URL})上的留言有新回复啦!

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

${PARENT_COMMENT}

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

${COMMENT}

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

@邮件通知模板代码:

<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}${SITE_URL}上的文章有了新的评论!
**${NICK}** 同学,发表评论说:
${COMMENT}
您可以点击查看回复的完整內容${POST_URL}#comments)。
<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官网找到了解决办法。

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

img

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

同样登录后台

找到定时任务

img

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

img

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

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

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

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

img

创建捡漏定时任务

然后运行函数选择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][email protected][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 “文章名字”生成一篇新文章,但需要手动打开,挺麻烦,我们可以设置在生成之后自动打开

在站点根目录下新建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即可,以后在新建文章就会自动打开编辑器.

系列教程

全部文章RSS订阅

Hexo系列 HexoRSS分类订阅

[三万字教程]基于Hexo的matery主题搭建博客并深度优化完全一站式教程

  • markdown 各种其它语法插件
  • latex公式支持
  • mermaid图表
  • plant uml图表
  • URL卡片
  • bilibili卡片
  • github卡片
  • 豆瓣卡片
  • 插入音乐和视频
  • 插入脑图

笔记系列 Note分类RSS订阅

经历了很长时间,使用了各种各样的方案,最终选择了一种相对完美的方式。docker私有部署运行的joplin,使用markdown语法,github作为图床,picgo作为图像自动上传后端,pypora作为MD编辑器,Snipaste作为截图工具。后备gitlab ee selfhost备份,自建图床VPS多线负载均衡。cloudflare partner cdn加速,jsdelivr加速。

  • pigo图床搭建与配置
  • Joplin教程
  • Snipaste截图工具
  • Typora 作为Markdown编辑器最强
  • Joplin和使用
  • Joplin同步与备份
  • Joplin导入与导出
  • Joplin安装使用,调用外部编辑器,网盘同步等等
  • Joplin简明教程
  • markdown语法简明教程
  • 教你用各种插件打造一个强大的笔记工具。
  • 如何部署自己私有的为知笔记。
  • 其实博主更推荐私有部署joplin

Gitbook使用系列 Gitbook分类RSS订阅

Gitlab 使用系列 Gitlab RSS 分类订阅


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

阅读全文

基于Hexo的matery主题搭建博客常见问题篇6
基于Hexo的matery主题搭建博客常见问题篇6 基于Hexo的matery主题搭建博客常见问题篇6
在建立,使用hexo构建博客的时候遇到的各种各样问题,在这里记录,留念,方便后来者少踩几个坑,O(∩_∩)O
2022-03-27
下一篇 

阅读全文

基于Hexo的matery主题搭建博客增强部署篇4
基于Hexo的matery主题搭建博客增强部署篇4 基于Hexo的matery主题搭建博客增强部署篇4
如果你想自动化部署怎么办?同时部署到多个空间怎么办?如何多种方法同时使用,多线路负载均衡访问了?本篇文章帮助你一一实现!
2022-03-27
  目录