Hexo系列

HexoRSS分类订阅

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

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

用户交互沟通

等等
下雪
樱花
冒泡
色彩美观
颜色渐变
valine统计
busuanziStatistics
各个主流平台
sharejs
CSS选择通知消息
弹出消息定制
tidio
crisp
垃圾消息过滤
email通知
留言管理系统
留言系统
OneSignal
webpush
tg电报
微信
短信
email通知
email订阅
RSS订阅
DarkMode
动画效果
界面美化
ppt
pdf
音乐
视频
相册
SEO
高质量文章
在《hexo博客网络优化篇》
访问统计
分享系统
看板娘系统
在线对话系统
评论系统
通知
订阅
美化
内容
访问速度

添加博客看板娘

方法如下:

安装插件:

bash
npm install --save hexo-helper-live2d

安装喜欢的模型:

bash
$ 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换成模型名字,如我使用的模型:

bash
$ npm install live2d-widget-model-shizuku

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

使用本地模型方式:

yaml
## 添加动画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

使用网络模型方式:

yaml
# 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

见右下角

Live2D看板娘
Live2D看板娘

更强大的看板娘

live2d-widget 原作者教程

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

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

live2d看板娘
live2d看板娘

live2d-widget效果图
live2d-widget效果图

依赖 Font Awesome

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

使用 Usage

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

后端 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触发提示文字框,可以用来做菜单,按钮的导航提示,终于是个合格的看板娘了!

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

看板娘触发文字提示
看板娘触发文字提示

添加夜间模式切换

  • 下面这个还远未完善,只是基本可用,不少细节地方CSS需要完善
  • 已经由博主上传到官方 develop 分支了

设置基础样式

参考其他优秀产品的黑夜模式,得出共性:

  • 那就是黑夜模式的背景一般不会是纯黑(#000);而是淡黑色,字体也不是纯白(#fff)而浅白色
  • 图片亮度降低

下面就开始贴代码了

themes>hexo-theme-matery>source>css>matery.css 中加上下面的代码

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

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

/* 背景颜色变黑色 */
body.DarkMode,
body.DarkMode .v[data-class='v'] .vcount,
body.DarkMode #rewardModal .modal-content,
body.DarkMode .modal,
body.DarkMode header .side-nav,
body.DarkMode header .side-nav .menu-list .m-nav-show {
    background-color: #12121c;
}

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

body.DarkMode img,
body.DarkMode strong {
    filter: brightness(0.7);
}

/*toc目录滤镜*/
body.DarkMode .toc-widget {
    filter: invert(0.8);
}

body.DarkMode .toc-widget .toc-list-item {
    color: #000
}

/* Skill bar text color */
body.DarkMode .skillbar .skill-bar-percent {
    color: #000;
}

切换按钮

完成了背景、字体、图片的样式,就需要黑夜白天切换按钮了

themes>hexo-theme-matery>layout>_widget 中创建一个新的文件 day-night.ejs,在新建的文件中加入下面的代码

ejs
<!-- 白天和黑夜主题 -->
<div class="sum-moon-box">
  <a class="btn-floating btn-large waves-effect waves-light" onclick="switchNightMode()" title="切换主题" >
    <i id="sum-moon-icon" class="fas fa-sun" style="width:48px; height:48px; font-size: 28px;"></i>
  </a>
</div>

<script>
  function switchNightMode() {
    $('<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"></div></div>').appendTo($('body')),
      setTimeout(function () {
        $('body').hasClass('DarkMode') 
        ? ($('body').removeClass('DarkMode'), localStorage.setItem('isDark', '0'), $('#sum-moon-icon').removeClass("fa-sun").addClass('fa-moon')) 
        : ($('body').addClass('DarkMode'), localStorage.setItem('isDark', '1'), $('#sum-moon-icon').addClass("fa-sun").removeClass('fa-moon')),
          
        setTimeout(function () {
          $('.Cuteen_DarkSky').fadeOut(1e3, function () {
            $(this).remove()
          })
        }, 2e3)
      })
  }
</script>

再在 themes>hexo-theme-matery>layout>layout.ejs 文件中引用一下

需要在 body 标签内部插入下面代码

ejs
<%- partial('_widget/day-night.ejs') %>

按钮样式

完成上面操作以后,就需要添加按钮样式和切换动画了,同样是在 themes>hexo-theme-matery>source>css>matery.css

css
/* 黑夜模式动画 */
.Cuteen_DarkSky,
.Cuteen_DarkSky:before {
    content: '';
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: 8888;
}

.Cuteen_DarkSky {
    background: linear-gradient(#feb8b0, #fef9db);
}

.Cuteen_DarkSky:before {
    transition: 2s ease all;
    opacity: 0;
    background: linear-gradient(#4c3f6d, #6c62bb, #93b1ed);
}

.DarkMode .Cuteen_DarkSky:before {
    opacity: 1;
}

.Cuteen_DarkPlanet {
    z-index: 9999;
    position: fixed;
    left: -50%;
    top: -50%;
    width: 200%;
    height: 200%;
    -webkit-animation: CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1);
    animation: CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1);
    transform-origin: center bottom;
}

@-webkit-keyframes CuteenPlanetMove {
    0% {
        transform: rotate(0);
    }
    to {
        transform: rotate(360deg);
    }
}

@keyframes CuteenPlanetMove {
    0% {
        transform: rotate(0);
    }
    to {
        transform: rotate(360deg);
    }
}

.Cuteen_DarkPlanet:after {
    position: absolute;
    left: 35%;
    top: 40%;
    width: 9.375rem;
    height: 9.375rem;
    border-radius: 50%;
    content: '';
    background: linear-gradient(#fefefe, #fffbe8);
}

/*黑夜模式按钮*/
.sum-moon-box {
    width: 48px;
    height: 48px;
    text-align: center;
    border-radius: 50%;
    position: fixed;
    right: 15px;
    bottom: 195px;
    margin-bottom: 0;
    z-index: 900;
}

.sum-moon-box .btn-floating {
    width: 48px;
    height: 48px;
}

.sum-moon-box i {
    font-size: 1.8rem;
    line-height: 48px !important;
}

定时提示切换黑夜模式

themes>hexo-theme-matery>source>js>matery.js 中添加下列代码

javascript
//黑夜模式提醒开启功能
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-bellaria-hidden="true"></i>晚上使用黑夜模式阅读能够减轻视觉疲劳。</span>'
        M.toast({ html: toastHTML })
    }
}, 2000)

黑夜模式持久化

themes>hexo-theme-matery>layout>layout.ejs 中添加下列代码(最好插入在 <%- partial('_partial/day-night.ejs') %> 下面)

javascript
/* 模式判断 */
<script>
    /* 模式判断 */
    if (localStorage.getItem('isDark') === '1') {
        document.body.classList.add('DarkMode');
        $('#sum-moon-icon').addClass("fa-sun").removeClass('fa-moon')
    } else {
        document.body.classList.remove('DarkMode');
        $('#sum-moon-icon').removeleClass("fa-sun").addClass('fa-moon')
    }
</script>

完成以上操作就完成了基本的黑夜模式了。

黑夜白天切换的动态背景

下面这是黑夜白天切换的动态背景,在你新建的 day-night.ejs 文件中加入下列代码

markup
<div class="stars-con">
  <div id="stars"></div>
  <div id="stars2"></div>
  <div id="stars3"></div>  
</div>

themes>hexo-theme-matery>source>css>matery.css 中加上下面的代码

css
/*黑夜模式背景*/
body.DarkMode {
    background: linear-gradient(#15151b, #1b1b2e, #231832) !important;
}

@keyframes animStar {
    from {
        transform: translateY(0)
    }
    to {
        transform: translateY(-2000px)
    }
}

body.DarkMode .stars-con {
    position: fixed;
    height: 100vh;
    width: 100vw;
    overflow: hidden;
    z-index: -111;
    background: linear-gradient(#15151b, #1b1b2e, #231832);
}

body.DarkMode #stars {
    width: 1px;
    height: 1px;
    background: 0 0;
    box-shadow: 1804px 1265px #fff, 365px 332px #fff, 86px 1888px #fff, 1888px 484px #fff, 199px 1489px #fff, 1459px 1010px #fff, 807px 388px #fff, 855px 558px #fff, 83px 1095px #fff, 1418px 377px #fff, 677px 886px #fff, 862px 1709px #fff, 1058px 1085px #fff, 50px 1772px #fff, 1941px 1544px #fff, 377px 900px #fff, 184px 712px #fff, 1797px 1928px #fff, 507px 1861px #fff, 1849px 19px #fff, 1399px 200px #fff, 972px 497px #fff, 795px 1109px #fff, 746px 970px #fff, 1524px 972px #fff, 1631px 389px #fff, 1026px 1016px #fff, 1295px 862px #fff, 1258px 1876px #fff, 791px 189px #fff, 1519px 45px #fff, 592px 1405px #fff, 620px 130px #fff, 1044px 1171px #fff, 37px 1578px #fff, 1589px 86px #fff, 1024px 528px #fff, 1613px 568px #fff, 912px 1175px #fff, 1177px 133px #fff, 67px 1641px #fff, 1168px 357px #fff, 310px 1873px #fff, 1187px 573px #fff, 308px 1839px #fff, 565px 24px #fff, 1691px 1555px #fff, 1384px 1551px #fff, 179px 861px #fff, 1850px 1966px #fff, 1169px 1979px #fff, 1182px 1522px #fff, 616px 751px #fff, 1083px 908px #fff, 684px 766px #fff, 67px 955px #fff, 1813px 1714px #fff, 1256px 1413px #fff, 332px 803px #fff, 1670px 1921px #fff, 362px 211px #fff, 1513px 423px #fff, 1304px 1145px #fff, 1292px 1168px #fff, 611px 802px #fff, 1297px 575px #fff, 540px 1289px #fff, 1551px 1678px #fff, 1545px 237px #fff, 423px 138px #fff, 1088px 28px #fff, 642px 1637px #fff, 429px 1293px #fff, 1276px 1900px #fff, 1168px 1696px #fff, 847px 837px #fff, 151px 1395px #fff, 1490px 75px #fff, 1588px 131px #fff, 1739px 1358px #fff, 709px 624px #fff, 343px 502px #fff, 1342px 1690px #fff, 175px 1722px #fff, 964px 1299px #fff, 892px 1326px #fff, 519px 1142px #fff, 1014px 193px #fff, 1181px 360px #fff, 325px 139px #fff, 482px 1199px #fff, 613px 8px #fff, 1976px 1125px #fff, 346px 60px #fff, 1565px 818px #fff, 268px 1590px #fff, 213px 1666px #fff, 800px 464px #fff, 974px 1825px #fff, 1066px 23px #fff, 1995px 1499px #fff, 666px 1130px #fff, 1074px 1710px #fff, 1636px 1483px #fff, 1379px 1509px #fff, 1221px 887px #fff, 1857px 964px #fff, 1046px 993px #fff, 1875px 643px #fff, 1504px 1607px #fff, 1065px 641px #fff, 1095px 752px #fff, 566px 1737px #fff, 1972px 1778px #fff, 146px 1517px #fff, 1923px 588px #fff, 557px 881px #fff, 1885px 1950px #fff, 1739px 1598px #fff, 1048px 501px #fff, 1316px 705px #fff, 1900px 1697px #fff, 1187px 917px #fff, 1688px 1025px #fff, 648px 1634px #fff, 1002px 572px #fff, 603px 1995px #fff, 215px 693px #fff, 688px 1374px #fff, 1389px 1166px #fff, 1310px 1140px #fff, 245px 587px #fff, 845px 63px #fff, 296px 1646px #fff, 792px 350px #fff, 756px 1493px #fff, 1553px 1079px #fff, 850px 66px #fff, 963px 1904px #fff, 81px 207px #fff, 1776px 1634px #fff, 1759px 521px #fff, 1761px 1536px #fff, 601px 1485px #fff, 898px 153px #fff, 48px 648px #fff, 1644px 1109px #fff, 1974px 60px #fff, 1278px 653px #fff, 616px 432px #fff, 1179px 1849px #fff, 739px 677px #fff, 808px 1850px #fff, 1104px 827px #fff, 984px 888px #fff, 1027px 44px #fff, 1462px 1105px #fff, 902px 1486px #fff, 769px 441px #fff, 431px 1195px #fff, 4px 764px #fff, 562px 7px #fff, 952px 1744px #fff, 822px 971px #fff, 1016px 1804px #fff, 1429px 1161px #fff, 328px 1568px #fff, 101px 746px #fff, 649px 1484px #fff, 1903px 569px #fff, 733px 871px #fff, 1554px 505px #fff, 1076px 642px #fff, 609px 641px #fff, 996px 149px #fff, 1595px 758px #fff, 14px 1083px #fff, 261px 767px #fff, 1274px 1517px #fff, 1412px 215px #fff, 1651px 879px #fff, 284px 1633px #fff, 1439px 287px #fff, 1717px 270px #fff, 1107px 1063px #fff, 1521px 1831px #fff, 656px 1702px #fff, 25px 230px #fff, 1958px 1615px #fff, 646px 675px #fff, 1201px 343px #fff, 1918px 1064px #fff, 1932px 609px #fff, 1203px 900px #fff, 10px 575px #fff, 1582px 1828px #fff, 1184px 462px #fff, 1px 1619px #fff, 1440px 1071px #fff, 1844px 1913px #fff, 376px 1054px #fff, 1883px 1236px #fff, 571px 493px #fff, 354px 1701px #fff, 747px 60px #fff, 11px 1142px #fff, 1136px 1891px #fff, 1682px 473px #fff, 1537px 1520px #fff, 902px 836px #fff, 1313px 395px #fff, 534px 341px #fff, 230px 1614px #fff, 14px 1387px #fff, 1296px 1765px #fff, 1064px 1270px #fff, 761px 975px #fff, 1855px 335px #fff, 198px 110px #fff, 1660px 598px #fff, 1022px 933px #fff, 518px 356px #fff, 19px 865px #fff, 471px 830px #fff, 758px 358px #fff, 541px 1652px #fff, 320px 926px #fff, 425px 1826px #fff, 659px 353px #fff, 708px 778px #fff, 862px 641px #fff, 475px 1362px #fff, 1326px 1449px #fff, 446px 802px #fff, 391px 1169px #fff, 496px 39px #fff, 1534px 934px #fff, 1822px 1809px #fff, 1454px 237px #fff, 187px 1555px #fff, 1069px 1977px #fff, 1880px 1508px #fff, 279px 418px #fff, 1938px 1980px #fff, 1304px 530px #fff, 1763px 187px #fff, 1945px 1642px #fff, 311px 1490px #fff, 770px 1598px #fff, 263px 330px #fff, 1733px 1771px #fff, 978px 34px #fff, 325px 1776px #fff, 873px 1460px #fff, 365px 33px #fff, 913px 1999px #fff, 667px 1021px #fff, 27px 572px #fff, 950px 1858px #fff, 448px 1205px #fff, 1302px 1138px #fff, 1269px 932px #fff, 480px 132px #fff, 770px 1871px #fff, 952px 654px #fff, 623px 90px #fff, 419px 1683px #fff, 930px 794px #fff, 1327px 1651px #fff, 769px 1536px #fff, 895px 90px #fff, 599px 1268px #fff, 1645px 919px #fff, 1672px 1080px #fff, 1637px 1259px #fff, 243px 1182px #fff, 1509px 457px #fff, 1374px 1469px #fff, 751px 137px #fff, 1097px 1008px #fff, 1979px 1381px #fff, 981px 1825px #fff, 928px 1930px #fff, 632px 422px #fff, 812px 341px #fff, 1077px 1832px #fff, 203px 1452px #fff, 664px 1531px #fff, 1203px 57px #fff, 1654px 1203px #fff, 491px 174px #fff, 1507px 735px #fff, 964px 896px #fff, 52px 1718px #fff, 1435px 26px #fff, 753px 635px #fff, 890px 1847px #fff, 42px 1353px #fff, 717px 72px #fff, 1845px 1212px #fff, 344px 867px #fff, 418px 855px #fff, 899px 1124px #fff, 1798px 1582px #fff, 1774px 760px #fff, 908px 1567px #fff, 1647px 1210px #fff, 299px 82px #fff, 1179px 1317px #fff, 938px 1580px #fff, 82px 921px #fff, 657px 1596px #fff, 892px 1264px #fff, 1161px 819px #fff, 607px 1447px #fff, 605px 679px #fff, 1642px 595px #fff, 1963px 525px #fff, 1656px 1591px #fff, 1467px 1743px #fff, 167px 1420px #fff, 471px 492px #fff, 1077px 932px #fff, 774px 1282px #fff, 799px 701px #fff, 400px 258px #fff, 235px 1937px #fff, 894px 562px #fff, 1277px 907px #fff, 435px 1360px #fff, 507px 1253px #fff, 1022px 833px #fff, 351px 773px #fff, 1126px 1969px #fff, 1382px 1620px #fff, 411px 59px #fff, 187px 906px #fff, 644px 1364px #fff, 1721px 1451px #fff, 1879px 1390px #fff, 1396px 318px #fff, 1002px 891px #fff, 1930px 1454px #fff, 1952px 496px #fff, 1308px 1325px #fff, 343px 475px #fff, 285px 373px #fff, 1329px 1591px #fff, 901px 1875px #fff, 966px 254px #fff, 1624px 1577px #fff, 371px 589px #fff, 1918px 1494px #fff, 841px 589px #fff, 873px 1657px #fff, 970px 1697px #fff, 1354px 975px #fff, 807px 1099px #fff, 384px 1608px #fff, 1600px 1739px #fff, 110px 1310px #fff, 687px 1611px #fff, 324px 394px #fff, 1267px 224px #fff, 1122px 1919px #fff, 1753px 578px #fff, 611px 479px #fff, 1494px 475px #fff, 1595px 368px #fff, 304px 1379px #fff, 1663px 87px #fff, 1789px 1471px #fff, 941px 1861px #fff, 287px 657px #fff, 1882px 217px #fff, 1766px 1960px #fff, 144px 966px #fff, 872px 943px #fff, 1705px 1909px #fff, 1318px 1173px #fff, 1856px 1549px #fff, 1722px 1482px #fff, 196px 594px #fff, 355px 1182px #fff, 1242px 112px #fff, 226px 344px #fff, 674px 895px #fff, 210px 2px #fff, 1224px 488px #fff, 220px 617px #fff, 1857px 1348px #fff, 426px 1026px #fff, 1370px 720px #fff, 109px 440px #fff, 1940px 1575px #fff, 978px 1443px #fff, 308px 614px #fff, 1392px 1351px #fff, 635px 1231px #fff, 1132px 616px #fff, 756px 342px #fff, 1968px 765px #fff, 1020px 1877px #fff, 1998px 1325px #fff, 1296px 1303px #fff, 1817px 223px #fff, 1184px 907px #fff, 546px 845px #fff, 51px 705px #fff, 1421px 735px #fff, 1255px 700px #fff, 249px 1908px #fff, 1701px 351px #fff, 173px 1658px #fff, 1088px 1476px #fff, 1930px 1787px #fff, 689px 1312px #fff, 615px 1006px #fff, 1870px 1229px #fff, 1900px 546px #fff, 1416px 141px #fff, 1983px 945px #fff, 1104px 1351px #fff, 426px 701px #fff, 431px 1597px #fff, 893px 456px #fff, 1976px 1914px #fff, 1538px 673px #fff, 916px 1386px #fff, 304px 138px #fff, 1038px 681px #fff, 1349px 1740px #fff, 1231px 552px #fff, 35px 1435px #fff, 588px 652px #fff, 793px 575px #fff, 542px 926px #fff, 1252px 25px #fff, 831px 332px #fff, 718px 283px #fff, 1327px 1952px #fff, 1019px 704px #fff, 888px 1117px #fff, 1107px 1378px #fff, 532px 505px #fff, 1070px 552px #fff, 346px 645px #fff, 63px 1783px #fff, 775px 879px #fff, 165px 160px #fff, 788px 1225px #fff, 1562px 1520px #fff, 56px 1522px #fff, 439px 498px #fff, 1988px 1521px #fff, 254px 1363px #fff, 1162px 816px #fff, 219px 386px #fff, 1789px 1315px #fff, 1090px 1415px #fff, 1361px 315px #fff, 825px 1306px #fff, 92px 548px #fff, 1501px 1946px #fff, 350px 1735px #fff, 459px 1533px #fff, 1417px 931px #fff, 1849px 174px #fff, 220px 1084px #fff, 1357px 209px #fff, 1974px 358px #fff, 90px 808px #fff, 1247px 765px #fff, 1878px 725px #fff, 1415px 87px #fff, 1253px 943px #fff, 1455px 1919px #fff, 1321px 337px #fff, 1210px 1600px #fff, 1855px 1575px #fff, 325px 936px #fff, 1118px 892px #fff, 703px 294px #fff, 89px 891px #fff, 239px 1548px #fff, 280px 262px #fff, 1401px 555px #fff, 1092px 1638px #fff, 673px 1207px #fff, 1469px 1358px #fff, 1253px 1986px #fff, 1249px 1040px #fff, 253px 484px #fff, 1163px 775px #fff, 426px 162px #fff, 721px 1761px #fff, 369px 510px #fff, 702px 1599px #fff, 1883px 483px #fff, 680px 1604px #fff, 870px 1599px #fff, 976px 1808px #fff, 916px 477px #fff, 1223px 1636px #fff, 506px 993px #fff, 898px 1284px #fff, 1013px 290px #fff, 1189px 78px #fff, 25px 588px #fff, 960px 861px #fff, 28px 526px #fff, 959px 681px #fff, 1426px 1329px #fff, 294px 557px #fff, 1907px 1320px #fff, 1289px 1627px #fff, 124px 451px #fff, 967px 653px #fff, 892px 1460px #fff, 537px 1385px #fff, 197px 1954px #fff, 1543px 302px #fff, 747px 1953px #fff, 995px 1630px #fff, 1423px 1221px #fff, 1075px 983px #fff, 1556px 1739px #fff, 1068px 1425px #fff, 81px 550px #fff, 1668px 523px #fff, 1158px 438px #fff, 401px 1795px #fff, 537px 1072px #fff, 1px 326px #fff, 249px 118px #fff, 832px 1544px #fff, 240px 153px #fff, 651px 1077px #fff, 1656px 542px #fff, 1102px 606px #fff, 1583px 788px #fff, 1205px 1842px #fff, 1657px 1793px #fff, 1848px 1464px #fff, 1285px 1395px #fff, 662px 1227px #fff, 1790px 134px #fff, 577px 263px #fff, 383px 702px #fff, 1728px 1953px #fff, 417px 57px #fff, 1390px 574px #fff, 1024px 287px #fff, 1969px 753px #fff, 1239px 1036px #fff, 1063px 1313px #fff, 1784px 1519px #fff, 1665px 682px #fff, 806px 1437px #fff, 394px 917px #fff, 904px 666px #fff, 801px 1280px #fff, 1392px 1930px #fff, 1611px 1386px #fff, 1809px 1507px #fff, 1720px 1300px #fff, 1721px 1287px #fff, 969px 240px #fff, 3px 1070px #fff, 1198px 538px #fff, 1416px 1001px #fff, 1665px 1265px #fff, 1010px 1275px #fff, 772px 978px #fff, 1980px 980px #fff, 1283px 1573px #fff, 444px 516px #fff, 875px 737px #fff, 258px 716px #fff, 1698px 758px #fff, 644px 238px #fff, 19px 876px #fff, 355px 1327px #fff, 1602px 1846px #fff, 548px 534px #fff, 1498px 1473px #fff, 1389px 1136px #fff, 174px 771px #fff, 955px 1931px #fff, 403px 371px #fff, 1502px 794px #fff, 117px 876px #fff, 536px 778px #fff, 67px 393px #fff, 119px 1918px #fff, 1912px 1663px #fff, 1141px 245px #fff, 1105px 130px #fff, 1218px 1608px #fff, 662px 1502px #fff, 1907px 927px #fff, 521px 109px #fff, 1885px 362px #fff, 1785px 1935px #fff, 781px 427px #fff, 1446px 1991px #fff, 164px 1539px #fff, 1807px 1795px #fff, 1922px 890px #fff, 1245px 933px #fff, 446px 450px #fff, 1743px 79px #fff, 1959px 310px #fff, 1348px 749px #fff, 1954px 128px #fff, 1980px 1030px #fff, 1850px 302px #fff, 1074px 922px #fff, 174px 403px #fff, 1579px 733px #fff, 653px 1958px #fff, 1511px 1943px #fff, 1037px 741px #fff, 602px 1384px #fff, 103px 402px #fff, 1722px 1417px #fff, 1732px 1916px #fff, 1743px 1803px #fff, 381px 721px #fff, 964px 1700px #fff, 1070px 341px #fff, 1376px 1258px #fff, 1884px 570px #fff, 940px 280px #fff, 1484px 1658px #fff, 1806px 1875px #fff, 1054px 917px #fff, 1672px 103px #fff, 783px 574px #fff, 98px 347px #fff, 555px 1136px #fff, 1403px 1237px #fff, 1203px 339px #fff, 572px 35px #fff, 932px 1783px #fff, 1527px 1850px #fff, 1959px 1109px #fff, 892px 623px #fff, 211px 1388px #fff, 1581px 1806px #fff, 868px 1053px #fff, 1243px 1997px #fff, 1004px 522px #fff, 1241px 1707px #fff, 376px 282px #fff, 537px 878px #fff, 1948px 979px #fff, 532px 688px #fff, 273px 958px #fff, 581px 927px #fff, 1060px 887px #fff, 486px 1467px #fff, 1122px 1834px #fff, 1650px 1763px #fff, 532px 302px #fff, 314px 1111px #fff, 1888px 683px #fff, 1856px 1040px #fff, 1780px 1338px #fff, 24px 1564px #fff, 1096px 1808px #fff, 1202px 1968px #fff, 214px 992px #fff, 728px 515px #fff, 247px 278px #fff, 1670px 45px #fff, 442px 1579px #fff, 1143px 30px #fff, 612px 72px #fff, 1177px 1303px #fff, 1898px 1255px #fff, 378px 1667px #fff, 326px 1929px #fff, 1257px 766px #fff, 1363px 1170px #fff, 1090px 1667px #fff, 711px 293px #fff, 249px 1406px #fff, 1589px 565px #fff, 1451px 29px #fff, 1171px 1459px #fff, 1294px 1214px #fff, 342px 942px #fff, 1945px 353px #fff, 741px 1185px #fff, 894px 1453px #fff, 593px 1584px #fff, 518px 630px #fff, 393px 756px #fff, 34px 608px #fff;
    animation: animStar 50s linear infinite;
}

body.DarkMode #stars:after {
    content: " ";
    position: absolute;
    top: 2000px;
    width: 1px;
    height: 1px;
    background: 0 0;
    box-shadow: 1804px 1265px #fff, 365px 332px #fff, 86px 1888px #fff, 1888px 484px #fff, 199px 1489px #fff, 1459px 1010px #fff, 807px 388px #fff, 855px 558px #fff, 83px 1095px #fff, 1418px 377px #fff, 677px 886px #fff, 862px 1709px #fff, 1058px 1085px #fff, 50px 1772px #fff, 1941px 1544px #fff, 377px 900px #fff, 184px 712px #fff, 1797px 1928px #fff, 507px 1861px #fff, 1849px 19px #fff, 1399px 200px #fff, 972px 497px #fff, 795px 1109px #fff, 746px 970px #fff, 1524px 972px #fff, 1631px 389px #fff, 1026px 1016px #fff, 1295px 862px #fff, 1258px 1876px #fff, 791px 189px #fff, 1519px 45px #fff, 592px 1405px #fff, 620px 130px #fff, 1044px 1171px #fff, 37px 1578px #fff, 1589px 86px #fff, 1024px 528px #fff, 1613px 568px #fff, 912px 1175px #fff, 1177px 133px #fff, 67px 1641px #fff, 1168px 357px #fff, 310px 1873px #fff, 1187px 573px #fff, 308px 1839px #fff, 565px 24px #fff, 1691px 1555px #fff, 1384px 1551px #fff, 179px 861px #fff, 1850px 1966px #fff, 1169px 1979px #fff, 1182px 1522px #fff, 616px 751px #fff, 1083px 908px #fff, 684px 766px #fff, 67px 955px #fff, 1813px 1714px #fff, 1256px 1413px #fff, 332px 803px #fff, 1670px 1921px #fff, 362px 211px #fff, 1513px 423px #fff, 1304px 1145px #fff, 1292px 1168px #fff, 611px 802px #fff, 1297px 575px #fff, 540px 1289px #fff, 1551px 1678px #fff, 1545px 237px #fff, 423px 138px #fff, 1088px 28px #fff, 642px 1637px #fff, 429px 1293px #fff, 1276px 1900px #fff, 1168px 1696px #fff, 847px 837px #fff, 151px 1395px #fff, 1490px 75px #fff, 1588px 131px #fff, 1739px 1358px #fff, 709px 624px #fff, 343px 502px #fff, 1342px 1690px #fff, 175px 1722px #fff, 964px 1299px #fff, 892px 1326px #fff, 519px 1142px #fff, 1014px 193px #fff, 1181px 360px #fff, 325px 139px #fff, 482px 1199px #fff, 613px 8px #fff, 1976px 1125px #fff, 346px 60px #fff, 1565px 818px #fff, 268px 1590px #fff, 213px 1666px #fff, 800px 464px #fff, 974px 1825px #fff, 1066px 23px #fff, 1995px 1499px #fff, 666px 1130px #fff, 1074px 1710px #fff, 1636px 1483px #fff, 1379px 1509px #fff, 1221px 887px #fff, 1857px 964px #fff, 1046px 993px #fff, 1875px 643px #fff, 1504px 1607px #fff, 1065px 641px #fff, 1095px 752px #fff, 566px 1737px #fff, 1972px 1778px #fff, 146px 1517px #fff, 1923px 588px #fff, 557px 881px #fff, 1885px 1950px #fff, 1739px 1598px #fff, 1048px 501px #fff, 1316px 705px #fff, 1900px 1697px #fff, 1187px 917px #fff, 1688px 1025px #fff, 648px 1634px #fff, 1002px 572px #fff, 603px 1995px #fff, 215px 693px #fff, 688px 1374px #fff, 1389px 1166px #fff, 1310px 1140px #fff, 245px 587px #fff, 845px 63px #fff, 296px 1646px #fff, 792px 350px #fff, 756px 1493px #fff, 1553px 1079px #fff, 850px 66px #fff, 963px 1904px #fff, 81px 207px #fff, 1776px 1634px #fff, 1759px 521px #fff, 1761px 1536px #fff, 601px 1485px #fff, 898px 153px #fff, 48px 648px #fff, 1644px 1109px #fff, 1974px 60px #fff, 1278px 653px #fff, 616px 432px #fff, 1179px 1849px #fff, 739px 677px #fff, 808px 1850px #fff, 1104px 827px #fff, 984px 888px #fff, 1027px 44px #fff, 1462px 1105px #fff, 902px 1486px #fff, 769px 441px #fff, 431px 1195px #fff, 4px 764px #fff, 562px 7px #fff, 952px 1744px #fff, 822px 971px #fff, 1016px 1804px #fff, 1429px 1161px #fff, 328px 1568px #fff, 101px 746px #fff, 649px 1484px #fff, 1903px 569px #fff, 733px 871px #fff, 1554px 505px #fff, 1076px 642px #fff, 609px 641px #fff, 996px 149px #fff, 1595px 758px #fff, 14px 1083px #fff, 261px 767px #fff, 1274px 1517px #fff, 1412px 215px #fff, 1651px 879px #fff, 284px 1633px #fff, 1439px 287px #fff, 1717px 270px #fff, 1107px 1063px #fff, 1521px 1831px #fff, 656px 1702px #fff, 25px 230px #fff, 1958px 1615px #fff, 646px 675px #fff, 1201px 343px #fff, 1918px 1064px #fff, 1932px 609px #fff, 1203px 900px #fff, 10px 575px #fff, 1582px 1828px #fff, 1184px 462px #fff, 1px 1619px #fff, 1440px 1071px #fff, 1844px 1913px #fff, 376px 1054px #fff, 1883px 1236px #fff, 571px 493px #fff, 354px 1701px #fff, 747px 60px #fff, 11px 1142px #fff, 1136px 1891px #fff, 1682px 473px #fff, 1537px 1520px #fff, 902px 836px #fff, 1313px 395px #fff, 534px 341px #fff, 230px 1614px #fff, 14px 1387px #fff, 1296px 1765px #fff, 1064px 1270px #fff, 761px 975px #fff, 1855px 335px #fff, 198px 110px #fff, 1660px 598px #fff, 1022px 933px #fff, 518px 356px #fff, 19px 865px #fff, 471px 830px #fff, 758px 358px #fff, 541px 1652px #fff, 320px 926px #fff, 425px 1826px #fff, 659px 353px #fff, 708px 778px #fff, 862px 641px #fff, 475px 1362px #fff, 1326px 1449px #fff, 446px 802px #fff, 391px 1169px #fff, 496px 39px #fff, 1534px 934px #fff, 1822px 1809px #fff, 1454px 237px #fff, 187px 1555px #fff, 1069px 1977px #fff, 1880px 1508px #fff, 279px 418px #fff, 1938px 1980px #fff, 1304px 530px #fff, 1763px 187px #fff, 1945px 1642px #fff, 311px 1490px #fff, 770px 1598px #fff, 263px 330px #fff, 1733px 1771px #fff, 978px 34px #fff, 325px 1776px #fff, 873px 1460px #fff, 365px 33px #fff, 913px 1999px #fff, 667px 1021px #fff, 27px 572px #fff, 950px 1858px #fff, 448px 1205px #fff, 1302px 1138px #fff, 1269px 932px #fff, 480px 132px #fff, 770px 1871px #fff, 952px 654px #fff, 623px 90px #fff, 419px 1683px #fff, 930px 794px #fff, 1327px 1651px #fff, 769px 1536px #fff, 895px 90px #fff, 599px 1268px #fff, 1645px 919px #fff, 1672px 1080px #fff, 1637px 1259px #fff, 243px 1182px #fff, 1509px 457px #fff, 1374px 1469px #fff, 751px 137px #fff, 1097px 1008px #fff, 1979px 1381px #fff, 981px 1825px #fff, 928px 1930px #fff, 632px 422px #fff, 812px 341px #fff, 1077px 1832px #fff, 203px 1452px #fff, 664px 1531px #fff, 1203px 57px #fff, 1654px 1203px #fff, 491px 174px #fff, 1507px 735px #fff, 964px 896px #fff, 52px 1718px #fff, 1435px 26px #fff, 753px 635px #fff, 890px 1847px #fff, 42px 1353px #fff, 717px 72px #fff, 1845px 1212px #fff, 344px 867px #fff, 418px 855px #fff, 899px 1124px #fff, 1798px 1582px #fff, 1774px 760px #fff, 908px 1567px #fff, 1647px 1210px #fff, 299px 82px #fff, 1179px 1317px #fff, 938px 1580px #fff, 82px 921px #fff, 657px 1596px #fff, 892px 1264px #fff, 1161px 819px #fff, 607px 1447px #fff, 605px 679px #fff, 1642px 595px #fff, 1963px 525px #fff, 1656px 1591px #fff, 1467px 1743px #fff, 167px 1420px #fff, 471px 492px #fff, 1077px 932px #fff, 774px 1282px #fff, 799px 701px #fff, 400px 258px #fff, 235px 1937px #fff, 894px 562px #fff, 1277px 907px #fff, 435px 1360px #fff, 507px 1253px #fff, 1022px 833px #fff, 351px 773px #fff, 1126px 1969px #fff, 1382px 1620px #fff, 411px 59px #fff, 187px 906px #fff, 644px 1364px #fff, 1721px 1451px #fff, 1879px 1390px #fff, 1396px 318px #fff, 1002px 891px #fff, 1930px 1454px #fff, 1952px 496px #fff, 1308px 1325px #fff, 343px 475px #fff, 285px 373px #fff, 1329px 1591px #fff, 901px 1875px #fff, 966px 254px #fff, 1624px 1577px #fff, 371px 589px #fff, 1918px 1494px #fff, 841px 589px #fff, 873px 1657px #fff, 970px 1697px #fff, 1354px 975px #fff, 807px 1099px #fff, 384px 1608px #fff, 1600px 1739px #fff, 110px 1310px #fff, 687px 1611px #fff, 324px 394px #fff, 1267px 224px #fff, 1122px 1919px #fff, 1753px 578px #fff, 611px 479px #fff, 1494px 475px #fff, 1595px 368px #fff, 304px 1379px #fff, 1663px 87px #fff, 1789px 1471px #fff, 941px 1861px #fff, 287px 657px #fff, 1882px 217px #fff, 1766px 1960px #fff, 144px 966px #fff, 872px 943px #fff, 1705px 1909px #fff, 1318px 1173px #fff, 1856px 1549px #fff, 1722px 1482px #fff, 196px 594px #fff, 355px 1182px #fff, 1242px 112px #fff, 226px 344px #fff, 674px 895px #fff, 210px 2px #fff, 1224px 488px #fff, 220px 617px #fff, 1857px 1348px #fff, 426px 1026px #fff, 1370px 720px #fff, 109px 440px #fff, 1940px 1575px #fff, 978px 1443px #fff, 308px 614px #fff, 1392px 1351px #fff, 635px 1231px #fff, 1132px 616px #fff, 756px 342px #fff, 1968px 765px #fff, 1020px 1877px #fff, 1998px 1325px #fff, 1296px 1303px #fff, 1817px 223px #fff, 1184px 907px #fff, 546px 845px #fff, 51px 705px #fff, 1421px 735px #fff, 1255px 700px #fff, 249px 1908px #fff, 1701px 351px #fff, 173px 1658px #fff, 1088px 1476px #fff, 1930px 1787px #fff, 689px 1312px #fff, 615px 1006px #fff, 1870px 1229px #fff, 1900px 546px #fff, 1416px 141px #fff, 1983px 945px #fff, 1104px 1351px #fff, 426px 701px #fff, 431px 1597px #fff, 893px 456px #fff, 1976px 1914px #fff, 1538px 673px #fff, 916px 1386px #fff, 304px 138px #fff, 1038px 681px #fff, 1349px 1740px #fff, 1231px 552px #fff, 35px 1435px #fff, 588px 652px #fff, 793px 575px #fff, 542px 926px #fff, 1252px 25px #fff, 831px 332px #fff, 718px 283px #fff, 1327px 1952px #fff, 1019px 704px #fff, 888px 1117px #fff, 1107px 1378px #fff, 532px 505px #fff, 1070px 552px #fff, 346px 645px #fff, 63px 1783px #fff, 775px 879px #fff, 165px 160px #fff, 788px 1225px #fff, 1562px 1520px #fff, 56px 1522px #fff, 439px 498px #fff, 1988px 1521px #fff, 254px 1363px #fff, 1162px 816px #fff, 219px 386px #fff, 1789px 1315px #fff, 1090px 1415px #fff, 1361px 315px #fff, 825px 1306px #fff, 92px 548px #fff, 1501px 1946px #fff, 350px 1735px #fff, 459px 1533px #fff, 1417px 931px #fff, 1849px 174px #fff, 220px 1084px #fff, 1357px 209px #fff, 1974px 358px #fff, 90px 808px #fff, 1247px 765px #fff, 1878px 725px #fff, 1415px 87px #fff, 1253px 943px #fff, 1455px 1919px #fff, 1321px 337px #fff, 1210px 1600px #fff, 1855px 1575px #fff, 325px 936px #fff, 1118px 892px #fff, 703px 294px #fff, 89px 891px #fff, 239px 1548px #fff, 280px 262px #fff, 1401px 555px #fff, 1092px 1638px #fff, 673px 1207px #fff, 1469px 1358px #fff, 1253px 1986px #fff, 1249px 1040px #fff, 253px 484px #fff, 1163px 775px #fff, 426px 162px #fff, 721px 1761px #fff, 369px 510px #fff, 702px 1599px #fff, 1883px 483px #fff, 680px 1604px #fff, 870px 1599px #fff, 976px 1808px #fff, 916px 477px #fff, 1223px 1636px #fff, 506px 993px #fff, 898px 1284px #fff, 1013px 290px #fff, 1189px 78px #fff, 25px 588px #fff, 960px 861px #fff, 28px 526px #fff, 959px 681px #fff, 1426px 1329px #fff, 294px 557px #fff, 1907px 1320px #fff, 1289px 1627px #fff, 124px 451px #fff, 967px 653px #fff, 892px 1460px #fff, 537px 1385px #fff, 197px 1954px #fff, 1543px 302px #fff, 747px 1953px #fff, 995px 1630px #fff, 1423px 1221px #fff, 1075px 983px #fff, 1556px 1739px #fff, 1068px 1425px #fff, 81px 550px #fff, 1668px 523px #fff, 1158px 438px #fff, 401px 1795px #fff, 537px 1072px #fff, 1px 326px #fff, 249px 118px #fff, 832px 1544px #fff, 240px 153px #fff, 651px 1077px #fff, 1656px 542px #fff, 1102px 606px #fff, 1583px 788px #fff, 1205px 1842px #fff, 1657px 1793px #fff, 1848px 1464px #fff, 1285px 1395px #fff, 662px 1227px #fff, 1790px 134px #fff, 577px 263px #fff, 383px 702px #fff, 1728px 1953px #fff, 417px 57px #fff, 1390px 574px #fff, 1024px 287px #fff, 1969px 753px #fff, 1239px 1036px #fff, 1063px 1313px #fff, 1784px 1519px #fff, 1665px 682px #fff, 806px 1437px #fff, 394px 917px #fff, 904px 666px #fff, 801px 1280px #fff, 1392px 1930px #fff, 1611px 1386px #fff, 1809px 1507px #fff, 1720px 1300px #fff, 1721px 1287px #fff, 969px 240px #fff, 3px 1070px #fff, 1198px 538px #fff, 1416px 1001px #fff, 1665px 1265px #fff, 1010px 1275px #fff, 772px 978px #fff, 1980px 980px #fff, 1283px 1573px #fff, 444px 516px #fff, 875px 737px #fff, 258px 716px #fff, 1698px 758px #fff, 644px 238px #fff, 19px 876px #fff, 355px 1327px #fff, 1602px 1846px #fff, 548px 534px #fff, 1498px 1473px #fff, 1389px 1136px #fff, 174px 771px #fff, 955px 1931px #fff, 403px 371px #fff, 1502px 794px #fff, 117px 876px #fff, 536px 778px #fff, 67px 393px #fff, 119px 1918px #fff, 1912px 1663px #fff, 1141px 245px #fff, 1105px 130px #fff, 1218px 1608px #fff, 662px 1502px #fff, 1907px 927px #fff, 521px 109px #fff, 1885px 362px #fff, 1785px 1935px #fff, 781px 427px #fff, 1446px 1991px #fff, 164px 1539px #fff, 1807px 1795px #fff, 1922px 890px #fff, 1245px 933px #fff, 446px 450px #fff, 1743px 79px #fff, 1959px 310px #fff, 1348px 749px #fff, 1954px 128px #fff, 1980px 1030px #fff, 1850px 302px #fff, 1074px 922px #fff, 174px 403px #fff, 1579px 733px #fff, 653px 1958px #fff, 1511px 1943px #fff, 1037px 741px #fff, 602px 1384px #fff, 103px 402px #fff, 1722px 1417px #fff, 1732px 1916px #fff, 1743px 1803px #fff, 381px 721px #fff, 964px 1700px #fff, 1070px 341px #fff, 1376px 1258px #fff, 1884px 570px #fff, 940px 280px #fff, 1484px 1658px #fff, 1806px 1875px #fff, 1054px 917px #fff, 1672px 103px #fff, 783px 574px #fff, 98px 347px #fff, 555px 1136px #fff, 1403px 1237px #fff, 1203px 339px #fff, 572px 35px #fff, 932px 1783px #fff, 1527px 1850px #fff, 1959px 1109px #fff, 892px 623px #fff, 211px 1388px #fff, 1581px 1806px #fff, 868px 1053px #fff, 1243px 1997px #fff, 1004px 522px #fff, 1241px 1707px #fff, 376px 282px #fff, 537px 878px #fff, 1948px 979px #fff, 532px 688px #fff, 273px 958px #fff, 581px 927px #fff, 1060px 887px #fff, 486px 1467px #fff, 1122px 1834px #fff, 1650px 1763px #fff, 532px 302px #fff, 314px 1111px #fff, 1888px 683px #fff, 1856px 1040px #fff, 1780px 1338px #fff, 24px 1564px #fff, 1096px 1808px #fff, 1202px 1968px #fff, 214px 992px #fff, 728px 515px #fff, 247px 278px #fff, 1670px 45px #fff, 442px 1579px #fff, 1143px 30px #fff, 612px 72px #fff, 1177px 1303px #fff, 1898px 1255px #fff, 378px 1667px #fff, 326px 1929px #fff, 1257px 766px #fff, 1363px 1170px #fff, 1090px 1667px #fff, 711px 293px #fff, 249px 1406px #fff, 1589px 565px #fff, 1451px 29px #fff, 1171px 1459px #fff, 1294px 1214px #fff, 342px 942px #fff, 1945px 353px #fff, 741px 1185px #fff, 894px 1453px #fff, 593px 1584px #fff, 518px 630px #fff, 393px 756px #fff, 34px 608px #fff;
}

body.DarkMode #stars2 {
    width: 2px;
    height: 2px;
    background: 0 0;
    box-shadow: 114px 658px #fff, 236px 768px #fff, 1130px 1503px #fff, 486px 592px #fff, 1353px 1407px #fff, 1583px 1741px #fff, 450px 1479px #fff, 1845px 327px #fff, 1520px 361px #fff, 580px 1699px #fff, 1277px 1233px #fff, 1697px 943px #fff, 568px 1135px #fff, 1273px 263px #fff, 788px 126px #fff, 1834px 1911px #fff, 1147px 1652px #fff, 651px 567px #fff, 79px 1897px #fff, 1590px 666px #fff, 1362px 566px #fff, 275px 367px #fff, 556px 479px #fff, 1063px 476px #fff, 1337px 1119px #fff, 1780px 1109px #fff, 1323px 1655px #fff, 1740px 1165px #fff, 525px 60px #fff, 1513px 1484px #fff, 708px 280px #fff, 429px 475px #fff, 563px 1360px #fff, 1580px 697px #fff, 1702px 1164px #fff, 1649px 1952px #fff, 1580px 1812px #fff, 70px 1190px #fff, 1100px 98px #fff, 1232px 1896px #fff, 851px 1047px #fff, 851px 30px #fff, 596px 1486px #fff, 666px 526px #fff, 1855px 1342px #fff, 80px 531px #fff, 248px 1804px #fff, 1990px 263px #fff, 1796px 1640px #fff, 1502px 862px #fff, 1780px 488px #fff, 1881px 1191px #fff, 1063px 876px #fff, 1614px 1073px #fff, 1414px 666px #fff, 1865px 289px #fff, 687px 352px #fff, 1329px 1312px #fff, 279px 136px #fff, 475px 756px #fff, 1177px 435px #fff, 1264px 921px #fff, 467px 1496px #fff, 391px 1359px #fff, 666px 1083px #fff, 1526px 1251px #fff, 594px 564px #fff, 991px 525px #fff, 1511px 875px #fff, 1935px 1049px #fff, 1471px 1430px #fff, 959px 604px #fff, 1685px 72px #fff, 1505px 1876px #fff, 509px 1627px #fff, 1065px 978px #fff, 1860px 884px #fff, 1038px 464px #fff, 1051px 106px #fff, 1056px 728px #fff, 1953px 45px #fff, 1483px 638px #fff, 559px 845px #fff, 1184px 922px #fff, 1320px 1117px #fff, 1572px 747px #fff, 1971px 43px #fff, 665px 13px #fff, 1457px 1153px #fff, 848px 154px #fff, 1039px 1837px #fff, 878px 795px #fff, 1286px 1705px #fff, 1946px 1143px #fff, 1114px 1166px #fff, 1747px 874px #fff, 1894px 636px #fff, 1316px 541px #fff, 1953px 1620px #fff, 1446px 1773px #fff, 974px 833px #fff, 1814px 1211px #fff, 102px 335px #fff, 327px 1868px #fff, 348px 548px #fff, 353px 1540px #fff, 1212px 1872px #fff, 1968px 129px #fff, 1531px 644px #fff, 1939px 559px #fff, 1397px 1876px #fff, 1446px 1446px #fff, 1721px 603px #fff, 924px 1171px #fff, 1086px 1954px #fff, 1798px 310px #fff, 21px 1595px #fff, 1462px 1948px #fff, 149px 1752px #fff, 804px 318px #fff, 1262px 636px #fff, 1051px 100px #fff, 392px 560px #fff, 654px 1236px #fff, 1889px 1159px #fff, 498px 394px #fff, 522px 1889px #fff, 1198px 579px #fff, 1437px 1866px #fff, 1049px 1064px #fff, 286px 921px #fff, 993px 1790px #fff, 1557px 1997px #fff, 1525px 532px #fff, 481px 1561px #fff, 790px 683px #fff, 141px 17px #fff, 1202px 28px #fff, 518px 1927px #fff, 90px 1677px #fff, 1258px 370px #fff, 1379px 1536px #fff, 607px 474px #fff, 163px 139px #fff, 1025px 1359px #fff, 815px 845px #fff, 231px 1212px #fff, 192px 806px #fff, 313px 1946px #fff, 1132px 1808px #fff, 624px 767px #fff, 379px 722px #fff, 733px 1847px #fff, 628px 1517px #fff, 1559px 929px #fff, 234px 397px #fff, 1230px 1231px #fff, 849px 726px #fff, 1148px 786px #fff, 546px 1533px #fff, 477px 822px #fff, 1325px 480px #fff, 972px 383px #fff, 334px 958px #fff, 1032px 664px #fff, 1781px 40px #fff, 38px 1335px #fff, 1634px 1691px #fff, 1061px 680px #fff, 1319px 304px #fff, 82px 1776px #fff, 1302px 509px #fff, 1231px 746px #fff, 1264px 1509px #fff, 980px 495px #fff, 1153px 1381px #fff, 1981px 1918px #fff, 70px 113px #fff, 390px 736px #fff, 1882px 1925px #fff, 1380px 1326px #fff, 257px 1681px #fff, 860px 998px #fff, 518px 1136px #fff, 168px 905px #fff, 500px 1882px #fff, 1012px 1572px #fff, 349px 1916px #fff, 905px 1339px #fff, 1940px 1803px #fff, 23px 1159px #fff, 9px 1559px #fff, 1658px 776px #fff, 820px 1361px #fff, 171px 983px #fff, 580px 1902px #fff, 1268px 263px #fff, 1734px 994px #fff, 1872px 29px #fff, 1475px 435px #fff;
    animation: animStar 100s linear infinite;
}

body.DarkMode #stars2:after {
    content: " ";
    position: absolute;
    top: 2000px;
    width: 2px;
    height: 2px;
    background: 0 0;
    box-shadow: 114px 658px #fff, 236px 768px #fff, 1130px 1503px #fff, 486px 592px #fff, 1353px 1407px #fff, 1583px 1741px #fff, 450px 1479px #fff, 1845px 327px #fff, 1520px 361px #fff, 580px 1699px #fff, 1277px 1233px #fff, 1697px 943px #fff, 568px 1135px #fff, 1273px 263px #fff, 788px 126px #fff, 1834px 1911px #fff, 1147px 1652px #fff, 651px 567px #fff, 79px 1897px #fff, 1590px 666px #fff, 1362px 566px #fff, 275px 367px #fff, 556px 479px #fff, 1063px 476px #fff, 1337px 1119px #fff, 1780px 1109px #fff, 1323px 1655px #fff, 1740px 1165px #fff, 525px 60px #fff, 1513px 1484px #fff, 708px 280px #fff, 429px 475px #fff, 563px 1360px #fff, 1580px 697px #fff, 1702px 1164px #fff, 1649px 1952px #fff, 1580px 1812px #fff, 70px 1190px #fff, 1100px 98px #fff, 1232px 1896px #fff, 851px 1047px #fff, 851px 30px #fff, 596px 1486px #fff, 666px 526px #fff, 1855px 1342px #fff, 80px 531px #fff, 248px 1804px #fff, 1990px 263px #fff, 1796px 1640px #fff, 1502px 862px #fff, 1780px 488px #fff, 1881px 1191px #fff, 1063px 876px #fff, 1614px 1073px #fff, 1414px 666px #fff, 1865px 289px #fff, 687px 352px #fff, 1329px 1312px #fff, 279px 136px #fff, 475px 756px #fff, 1177px 435px #fff, 1264px 921px #fff, 467px 1496px #fff, 391px 1359px #fff, 666px 1083px #fff, 1526px 1251px #fff, 594px 564px #fff, 991px 525px #fff, 1511px 875px #fff, 1935px 1049px #fff, 1471px 1430px #fff, 959px 604px #fff, 1685px 72px #fff, 1505px 1876px #fff, 509px 1627px #fff, 1065px 978px #fff, 1860px 884px #fff, 1038px 464px #fff, 1051px 106px #fff, 1056px 728px #fff, 1953px 45px #fff, 1483px 638px #fff, 559px 845px #fff, 1184px 922px #fff, 1320px 1117px #fff, 1572px 747px #fff, 1971px 43px #fff, 665px 13px #fff, 1457px 1153px #fff, 848px 154px #fff, 1039px 1837px #fff, 878px 795px #fff, 1286px 1705px #fff, 1946px 1143px #fff, 1114px 1166px #fff, 1747px 874px #fff, 1894px 636px #fff, 1316px 541px #fff, 1953px 1620px #fff, 1446px 1773px #fff, 974px 833px #fff, 1814px 1211px #fff, 102px 335px #fff, 327px 1868px #fff, 348px 548px #fff, 353px 1540px #fff, 1212px 1872px #fff, 1968px 129px #fff, 1531px 644px #fff, 1939px 559px #fff, 1397px 1876px #fff, 1446px 1446px #fff, 1721px 603px #fff, 924px 1171px #fff, 1086px 1954px #fff, 1798px 310px #fff, 21px 1595px #fff, 1462px 1948px #fff, 149px 1752px #fff, 804px 318px #fff, 1262px 636px #fff, 1051px 100px #fff, 392px 560px #fff, 654px 1236px #fff, 1889px 1159px #fff, 498px 394px #fff, 522px 1889px #fff, 1198px 579px #fff, 1437px 1866px #fff, 1049px 1064px #fff, 286px 921px #fff, 993px 1790px #fff, 1557px 1997px #fff, 1525px 532px #fff, 481px 1561px #fff, 790px 683px #fff, 141px 17px #fff, 1202px 28px #fff, 518px 1927px #fff, 90px 1677px #fff, 1258px 370px #fff, 1379px 1536px #fff, 607px 474px #fff, 163px 139px #fff, 1025px 1359px #fff, 815px 845px #fff, 231px 1212px #fff, 192px 806px #fff, 313px 1946px #fff, 1132px 1808px #fff, 624px 767px #fff, 379px 722px #fff, 733px 1847px #fff, 628px 1517px #fff, 1559px 929px #fff, 234px 397px #fff, 1230px 1231px #fff, 849px 726px #fff, 1148px 786px #fff, 546px 1533px #fff, 477px 822px #fff, 1325px 480px #fff, 972px 383px #fff, 334px 958px #fff, 1032px 664px #fff, 1781px 40px #fff, 38px 1335px #fff, 1634px 1691px #fff, 1061px 680px #fff, 1319px 304px #fff, 82px 1776px #fff, 1302px 509px #fff, 1231px 746px #fff, 1264px 1509px #fff, 980px 495px #fff, 1153px 1381px #fff, 1981px 1918px #fff, 70px 113px #fff, 390px 736px #fff, 1882px 1925px #fff, 1380px 1326px #fff, 257px 1681px #fff, 860px 998px #fff, 518px 1136px #fff, 168px 905px #fff, 500px 1882px #fff, 1012px 1572px #fff, 349px 1916px #fff, 905px 1339px #fff, 1940px 1803px #fff, 23px 1159px #fff, 9px 1559px #fff, 1658px 776px #fff, 820px 1361px #fff, 171px 983px #fff, 580px 1902px #fff, 1268px 263px #fff, 1734px 994px #fff, 1872px 29px #fff, 1475px 435px #fff;
}

body.DarkMode #stars3 {
    width: 3px;
    height: 3px;
    background: 0 0;
    box-shadow: 519px 875px #fff, 1497px 751px #fff, 1256px 88px #fff, 1168px 1791px #fff, 1884px 109px #fff, 1465px 451px #fff, 450px 370px #fff, 1560px 703px #fff, 1788px 1997px #fff, 1047px 963px #fff, 1281px 119px #fff, 439px 96px #fff, 164px 1956px #fff, 1360px 930px #fff, 1387px 347px #fff, 1073px 1970px #fff, 1296px 284px #fff, 25px 1602px #fff, 455px 944px #fff, 1177px 738px #fff, 633px 1142px #fff, 1730px 1079px #fff, 1283px 1606px #fff, 674px 1186px #fff, 513px 166px #fff, 1077px 636px #fff, 1811px 580px #fff, 971px 1789px #fff, 694px 1756px #fff, 703px 1138px #fff, 1290px 942px #fff, 351px 1509px #fff, 1904px 790px #fff, 68px 819px #fff, 1097px 362px #fff, 1035px 331px #fff, 180px 940px #fff, 1776px 1229px #fff, 1487px 781px #fff, 1131px 1765px #fff, 1684px 536px #fff, 939px 367px #fff, 1102px 1481px #fff, 741px 887px #fff, 167px 1132px #fff, 1756px 529px #fff, 608px 758px #fff, 541px 1025px #fff, 1976px 505px #fff, 1349px 1257px #fff, 815px 1388px #fff, 505px 1351px #fff, 33px 1945px #fff, 861px 1695px #fff, 678px 1360px #fff, 1615px 727px #fff, 1138px 726px #fff, 30px 293px #fff, 1624px 1044px #fff, 683px 1242px #fff, 1781px 1758px #fff, 906px 1328px #fff, 1066px 1764px #fff, 1568px 664px #fff, 1027px 1876px #fff, 775px 1099px #fff, 1605px 208px #fff, 730px 837px #fff, 1475px 1482px #fff, 871px 1759px #fff, 1240px 15px #fff, 1987px 705px #fff, 302px 1049px #fff, 475px 1015px #fff, 1843px 1296px #fff, 493px 631px #fff, 1613px 164px #fff, 1863px 156px #fff, 1479px 423px #fff, 202px 1499px #fff, 886px 969px #fff, 904px 930px #fff, 1853px 535px #fff, 726px 914px #fff, 435px 1205px #fff, 1732px 1824px #fff, 1212px 667px #fff, 499px 31px #fff, 552px 594px #fff, 1715px 1814px #fff, 775px 908px #fff, 1949px 921px #fff, 1267px 718px #fff, 1830px 1960px #fff, 338px 1325px #fff, 466px 1120px #fff, 140px 1675px #fff, 1919px 664px #fff, 1136px 771px #fff, 1888px 1302px #fff;
    animation: animStar 150s linear infinite;
}

body.DarkMode #stars3:after {
    content: " ";
    position: absolute;
    top: 2000px;
    width: 3px;
    height: 3px;
    background: 0 0;
    box-shadow: 519px 875px #fff, 1497px 751px #fff, 1256px 88px #fff, 1168px 1791px #fff, 1884px 109px #fff, 1465px 451px #fff, 450px 370px #fff, 1560px 703px #fff, 1788px 1997px #fff, 1047px 963px #fff, 1281px 119px #fff, 439px 96px #fff, 164px 1956px #fff, 1360px 930px #fff, 1387px 347px #fff, 1073px 1970px #fff, 1296px 284px #fff, 25px 1602px #fff, 455px 944px #fff, 1177px 738px #fff, 633px 1142px #fff, 1730px 1079px #fff, 1283px 1606px #fff, 674px 1186px #fff, 513px 166px #fff, 1077px 636px #fff, 1811px 580px #fff, 971px 1789px #fff, 694px 1756px #fff, 703px 1138px #fff, 1290px 942px #fff, 351px 1509px #fff, 1904px 790px #fff, 68px 819px #fff, 1097px 362px #fff, 1035px 331px #fff, 180px 940px #fff, 1776px 1229px #fff, 1487px 781px #fff, 1131px 1765px #fff, 1684px 536px #fff, 939px 367px #fff, 1102px 1481px #fff, 741px 887px #fff, 167px 1132px #fff, 1756px 529px #fff, 608px 758px #fff, 541px 1025px #fff, 1976px 505px #fff, 1349px 1257px #fff, 815px 1388px #fff, 505px 1351px #fff, 33px 1945px #fff, 861px 1695px #fff, 678px 1360px #fff, 1615px 727px #fff, 1138px 726px #fff, 30px 293px #fff, 1624px 1044px #fff, 683px 1242px #fff, 1781px 1758px #fff, 906px 1328px #fff, 1066px 1764px #fff, 1568px 664px #fff, 1027px 1876px #fff, 775px 1099px #fff, 1605px 208px #fff, 730px 837px #fff, 1475px 1482px #fff, 871px 1759px #fff, 1240px 15px #fff, 1987px 705px #fff, 302px 1049px #fff, 475px 1015px #fff, 1843px 1296px #fff, 493px 631px #fff, 1613px 164px #fff, 1863px 156px #fff, 1479px 423px #fff, 202px 1499px #fff, 886px 969px #fff, 904px 930px #fff, 1853px 535px #fff, 726px 914px #fff, 435px 1205px #fff, 1732px 1824px #fff, 1212px 667px #fff, 499px 31px #fff, 552px 594px #fff, 1715px 1814px #fff, 775px 908px #fff, 1949px 921px #fff, 1267px 718px #fff, 1830px 1960px #fff, 338px 1325px #fff, 466px 1120px #fff, 140px 1675px #fff, 1919px 664px #fff, 1136px 771px #fff, 1888px 1302px #fff;
}

这样黑夜模式算是真正完成了

Tag标签外挂使用方法

markdown
Tag标签外挂使用方法

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

屏蔽网页源码(单纯的屏蔽鼠标右键和键盘事件)

在 themes/matery/layout/layout.ejs 添加如下代码

javascript
<script type="text/javascript">
        window.onload = function(){
            //屏蔽键盘事件
            document.onkeydown = function (){
                var e = window.event || arguments[0];
                //F12
                if(e.keyCode == 123){
                    return false;
                //Ctrl+Shift+I
                }else if((e.ctrlKey) && (e.shiftKey) && (e.keyCode == 73)){
                    return false;
                //Shift+F10
                }else if((e.shiftKey) && (e.keyCode == 121)){
                    return false;
                //Ctrl+U
                }else if((e.ctrlKey) && (e.keyCode == 85)){
                    return false;
                }
            };
            //屏蔽鼠标右键
            document.oncontextmenu = function (){
                return false;
            }
        }
</script>

添加天气小插件

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

新增个人相册

这个功能,已经由博主上传到官方develop分支了

看下面配置使用方法就好,代码不用修改直接使用!

新建相册目录

执行下面的命令:

bash
hexo new page galleries

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

bash
type: "galleries"
layout: "galleries"

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

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

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

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

添加 ejs 文件和 css 文件

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

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 文件,添加以下代码:

javascript
<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 文件,添加以下代码:

javascript
<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

    </libs/fancybox/jquery.fancybox.css>

  • libs/justifiedGallery/justifiedGallery.min.css:

    </libs/justifiedGallery/justifiedGallery.min.css>

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

    </js/crypto-js.js>

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

    </js/gallery-encrypt.js>

  • libs/fancybox/fancybox.js:

    </libs/fancybox/fancybox.js>

  • libs/justifiedGallery/justifiedGallery.min.js:

    </libs/justifiedGallery/justifiedGallery.min.js>

添加相册 json 配置文件

站点目录 source/_data/ 下新建一个 galleries.json 的文件,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文件内容为:

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

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

galleries 目录结构

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

查看效果

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

bash
hexo clean && hexo g && hexo s

我的效果

支持RSS分类订阅

这个功能个人使用很久了,但是原作者插件不支持hexo6, Hexo 6 强制使用的时候,会影响很多基础功能。

这次测试Npm包发布,就拿这个插件练手了!

RSS订阅与文章分类订阅
RSS订阅与文章分类订阅

或者直接访问我的博客查看效果!

重要注意.需要安装 hexo-generator-taghexo-generator-category 插件用来生成 tag/category feeds.

安装

bash
npm install hexo-feed-new --save-dev

配置

yaml
feed:
    limit: 20
    order_by: "-date"
    tag_dir: "tag"
    category_dir: "category"
    rss:
        enable: true
        template: "themes/theme/layout/_alternate/rss.ejs"
        output: "rss.xml"
    atom:
        enable: true
        template: "themes/theme/layout/_alternate/atom.ejs"
        output: "atom.xml"
    jsonFeed:
        enable: true
        template: "themes/theme/layout/_alternate/json.ejs"
        output: "feed.json"
KeyRequiredDefault valueDescription
limitfalse0Post count that will be presented in the feed. Use 0 to publish all posts to the feed.
order_byfalse-dateSorting order for the posts.
tag_dirfalsetagDirectory name to publish all tag-related feeds. Set false to avoid generating feeds by tag. For more information see below.
category_dirfalsecategoryDirectory name to publish all category-related feeds. Set false to avoid generating feeds by category. For more information see below.
rss.enablefalsetrueEnable/disable RSS feed generating.
rss.templatefalsePath to custom template for the RSS feed.
rss.outputfalserss.xmlOutput filename for RSS feed.
atom.enablefalsetrueEnable/disable ATOM feed generating.
atom.templatefalsePath to custom template for the ATOM feed.
atom.outputfalseatom.xmlOutput filename for ATOM feed.
jsonFeed.enablefalsetrueEnable/disable JSON feed generating.
jsonFeed.templatefalsePath to custom template for the JSON feed.
jsonFeed.outputfalsefeed.jsonOutput filename for JSON feed.

添加feed

markup
<html>
  <head>

    <!-- ... -->

    <link rel="alternate" type="application/rss+xml" title="<%= config.title %>" href="<%= full_url_for(`/rss.xml}`) %>" />
    <link rel="alternate" type="application/atom+xml" title="<%= config.title %>" href="<%= full_url_for(`/atom.xml`) %>" />
    <link rel="alternate" type="application/json" title="<%= config.title %>" href="<%= full_url_for(`/feed.json`) %>" />
  </head>
  <body>

    <!-- ... -->

  </body>
</html>

豆瓣书单电影页面

1.首先在博客站点目录执行下面的命令安装豆瓣插件:

bash
npm install hexo-douban --save

2.紧接着在博客站点目录的配置文件_config.yml下,添加如下配置:

yaml
douban:
  user: 123456789  #这个需要修改为你个人的id
  builtin: true
  book:
      title: '我的书单'
      quote: '你必须要看的书籍'
  movie:
      title: '我的影单'
      quote: '那些年我们一起看过的电影'
timeout: 10000
  • user::你的豆瓣ID。打开豆瓣,登入账户,然后在右上角点击 ”个人主页“,这时候地址栏的URL大概是这样:https://www.douban.com/people/xxxxxx/ ,其中的”xxxxxx”就是你的个人ID了。
  • builtin:是否将生成页面的功能嵌入 hexo shexo g 中,默认是 false ,另一可选项为 true
  • title: 该页面的标题。
  • quote: 写在页面开头的一段话,支持html语法。
  • timeout: 爬取数据的超时时间,默认是 10000ms,如果在使用时发现报了超时的错(ETIMEOUT)可以把这个数据设置的大一点。 如果只想显示某一个页面(比如movie),那就把其他的配置项注释掉即可。

3.然后再主题配置文件_config.yml中添加关于此页面的菜单:(下面是我的配置)

yaml
媒体:
    icon: fas fa-list
    children:
      - name: 电影
        url: /movies
        icon: fas fa-film
      - name: 书单
        url: /books
        icon: fas fa-book

4.适配Matery主题:在 /themes/hexo-theme-matery/layout 文件夹下面创建一个名为 douban.ejs 的文件,并将下面的内容复制进去:

ejs
<%- partial('_partial/post-cover') %>
<style>
    .hexo-douban-picture img {
        width: 100%;
    }
</style>
<main class="content">
    <div id="contact" class="container chip-container">
        <div class="card">
            <div class="card-content" style="padding: 30px">
                <h1 style="margin: 10px 0 10px 0px;"><%= page.title %></h1>
                <%- page.content %>
            </div>
        </div>
        <div class="card">
            <div class="card-content" style="text-align: center">
              <h3 style="margin: 5px 0 5px 5px;">如果你有好的内容推荐,欢迎在下面留言!</h3>
            </div>
         </div>
        <div class="card">
            <% if (theme.gitalk && theme.gitalk.enable) { %>
            <%- partial('_partial/gitalk') %>
            <% } %>

            <% if (theme.gitment.enable) { %>
            <%- partial('_partial/gitment') %>
            <% } %>

            <% if (theme.disqus.enable) { %>
            <%- partial('_partial/disqus') %>
            <% } %>

            <% if (theme.livere && theme.livere.enable) { %>
            <%- partial('_partialvere') %>
            <% } %>

            <% if (theme.valine && theme.valine.enable) { %>
            <%- partial('_partialaline') %>
            <% } %>
        </div>
    </div>
</main>

5.然后在博客站点目录下的node_modules文件夹下找到hexo-douban/lib,文件夹下有三个js文件,分别为:books-generator.js 、games-generator.js 、movies-generator.js,用文本编辑器打开这三个文件,并将其文件内容末尾的代码修改为一下内容:

markdown
/* 原文件内容为 layout: [`page`, `post`] ,将其修改为下面的内容*/
layout: [`page`, `douban`]

6.最后就是使用并生成相应的页面,执行命令如下:

bash
hexo douban

需要注意的是,通常大家都喜欢用 hexo d 来作为 hexo deploy 命令的简化,但是当安装了 hexo douban 之后,就不能用 hexo d 了,因为 hexo doubanhexo deploy 的前缀都是 hexo d ,你以后执行的 hexo d 将不再是 Hexo 页面的生成,而是豆瓣页面的生成。

以下是可选的命令参数:

bash
-h, --help # 帮助页面
-b, --books # 只生成书单页面
-g, --games # 只生成游戏页面
-m, --movies # 只生成电影页面

当站点配置文件的builtin的值为true时,生成页面的功能会嵌入到hexo g和hexo s中,在进行部署生成操作,会自动生成相应的页面

新增折叠功能

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

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

安装插件

bash
npm install hexo-sliding-spoiler --save

配置插件

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

yaml
plugin:
- hexo-sliding-spoiler

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

进一步完善美化

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

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: "▼ ";
}

使用方法

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

实例

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

内容测试

{% endspoiler %}

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

内容测试

{% endspoiler %}

代码块全屏显示

最新发现引用的博客文章消失了,如实找到原来的git修改记录,提取出代码块全屏显示的方法给大家

原理简单,通过 JS 添加删除属性,使用 CSS 控制显示和动画效果

css
.code-area.code-block-fullscreen pre {
  overflow: auto;
  max-height: unset;
  overflow: auto;
  width: 100%;
  height: 100%;
  min-width: 100%;
}


/* code-block-fullscreen */
.code-block-fullscreen {
  position:fixed;
  top:-0.4em;
  left:0;
  width:100%;
  height:100%;
  min-width:100%;
  z-index: 999999;
  margin:0;
  animation: elastic 1s;
}
.code-block-fullscreen code {
  --widthA:100%;
  --widthB:calc(var(--widthA) - 30px);
  height:var(--widthB);
  min-height:99%;
  overflow-y:hidden;
  overflow-x:auto;
  height:auto;
}
.code-block-fullscreen-html-scroll {
  overflow: hidden;
}
.code-area.code-block-fullscreen i.code-expand,
.code-area.code-block-fullscreen .scroll-down-bar {
  display: none;
}
.code-show-expand {
  position: absolute;
  top: 4px;
  right: 53px;
  z-index: 1;
  filter: invert(50%);
  cursor: pointer;
  padding: 7px;
}
javascript
if (enableShowexpand) {
  var $code_show_expand = $('<i class="fas fa-expand code-show-expand"  title="全屏显示" aria-hidden="true"></i>');
  $pre.before($code_show_expand);
  $('.code-area .code-show-expand').on('click', function (e) {
    if (e.target !== this) return
    if ($(this).parent().hasClass('code-closed')) {
      $(this).siblings('pre').find('code').show();
      $(this).parent().removeClass('code-closed');
    }
    $(this).parent().toggleClass('code-block-fullscreen')
    $('html').toggleClass('code-block-fullscreen-html-scroll')
  });
}

TOC目录展开收缩的小箭头

效果展示

toc
toc

代码

javascript
$(function(){
    // 切换TOC目录展开收缩的相关操作.
  const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        let $itemHasChild = $(".toc-list-item:has(> .toc-list)");
        $itemHasChild.prepend("<i class='fa fa-caret-down'></i><i class='fa fa-caret-right'></i><span> </span>");
        let $iconToFold = $(".toc-list-item > .fa-caret-down");
        let $iconToExpand = $(".toc-list-item > .fa-caret-right");
        $iconToFold.addClass("hide");

        const targetNodes = document.getElementsByClassName("toc-list-item");
        const config = { attributes: true, childList: false, subtree: false };
        const callback = function(mutationsList, observer) {
          for(let mutation of mutationsList) {
            if (mutation.type === "attributes") {
              let target = $(mutation.target)
              if (target.hasClass("is-active-li")) {
                let $toFold = $(".toc-list-item > .fa-caret-down");
                let $toExpand = $(".toc-list-item > .fa-caret-right");
                $toFold.addClass("hide");
                $toExpand.removeClass("hide");
                target.children(".fa-caret-right").first().addClass("hide")
                target.children(".fa-caret-down").first().removeClass("hide")
                let parents = target.parents(".toc-list-item")
                for (p of parents) {
                  $(p).children(".fa-caret-right").first().addClass("hide")
                  $(p).children(".fa-caret-down").first().removeClass("hide")
                }
              }
            }
          }
        };
        const observer = new MutationObserver(callback);
        for (node of targetNodes) {
          observer.observe(node, config)
        }
  });

如何使用

我先简单介绍一下上面的代码。代码使用了 Jquery,以及font awesome,不过hexo的主题应该都有这些

代码的逻辑是,在网页加载完毕后,给TOC目录的分级菜单加入小箭头,并创建MutationObserver来监听属性变化,因为属性变化不是事件,所以并不能以事件监听的形式处理

那么这段代码该放到哪里呢?

代码是在网页加载完毕后执行的,那么和网页本身的代码无关,只和网页展示内容有关。你想要加在文章的TOC目录,总不能把这段代码放到分类页面去吧。

而hexo主题用的都是模板引擎,例如 ejs、swig。通常一个页面都会被拆分为 header,footer 等

所以只要加在任意一个,文章包含的模板即可,但是最好还是加在文章独属的模板

模板位于\layout\_partial 目录,下面讲解的是 ejs 怎么放,swig 可能也差不多

如果你不知道怎么找文章独属的模板

那就在目录下面一个一个添加呗,哪个有效了就行

方法很简单,直接把文件拉到底下,写一个新的 script 标签,把代码复制进去即可

markup
<script>
	复制代码过来
</script>

如果你能找到TOC或者文章独属的模板

操作方法和上面一样,区别是你的网站性能会提高。因为这段代码仅在需要加载的地方加载

更加推荐的是,加上模板引擎的判断逻辑

ejs
<% if (theme.toc.enable && theme.toc.showToggleBtn) { %>
代码
<% } %>

theme 对象是主题的配置文件_config.yml,toc 是其中的属性,enable 控制 toc 是否显示

让Hexo博客支持通知功能

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

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

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

安装插件

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

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

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

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

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

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

yaml
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即可。

修改前

javascript
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 })
    }
javascript
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标签里。

javascript
<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
img

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

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

img
img

接下来输入分支为master

img
img

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

环境变量

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

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

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

然后看一下效果

img
img

还不错

自定义后台

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

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

img
img

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

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

更多设置

邮件通知模板

HCLonely/Valine-Admin 时使用这个

邮件通知演示
邮件通知演示

评论通知模板

markup
<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>

博主回复通知模板

markup
<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见下文[可选]博主邮件通知内容模板

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

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

markup
<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

mail-blue-template

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

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

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

markup
<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 变量不再可用。

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

markup
<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前端添加一点额外的代码:

markup
<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>

@邮件通知效果:

ejs
您在[ ${SITE_NAME}](/posts/40300608/${SITE_URL})上的留言有新回复啦!

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

${PARENT_COMMENT}

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

${COMMENT}

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

@邮件通知模板代码:

markup
<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>

博主通知效果:

none
您在[${SITE_NAME}${SITE_URL}上的文章有了新的评论!
**${NICK}** 同学,发表评论说:
${COMMENT}
您可以点击查看回复的完整內容${POST_URL}#comments)。
markup
<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
img

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

img
img

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

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

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

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

img
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

none
npm install hexo-offline --save

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

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

配置hexo-offline

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

yaml
# 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里添加

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

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

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

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

javascript
themes/matery/layout/_partial/head.ejs

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

验证和使用

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

F12 sources
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问题:

txt
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)修改主题配置文件

yaml
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属性如下:

yaml
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

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

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,

    });

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

markup
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 是上面对着改一下就好了:

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

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

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

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

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

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

Linux , MacOS 等类UNIX系统用户,vim $hexo/scripts/openNewFile.js

javascript
var spawn = require('child_process').spawn;
// Hexo 3
hexo.on('new', function(data){
spawn('vim', [data.path], { stdio: 'inherit'  });
});

使用 VS Code 的任务(Tasks)便捷操作 Hexo

本文章要实现目标是通过配置任务,可以使用 Ctrl+Shift+B(“运行生成任务”的快捷键)自动完成 Hexo 的清理、生成、开启本地预览,并且可以使用 VS Code 的“终端”菜单下的“运行命令”完成上述的单个命令。

配置 Tasks

工作区的特定任务是从 Workspace.vscode 文件夹中的 tasks.json 文件配置。

新建 tasks.json

在 Hexo 工作区的 .vscode 文件夹下新建 tasks.json 文件。

配置单个 Hexo 命令

hexo generate 命令为例,在 tasks.json 粘贴下面的代码。

json

{
  "version": "2.0.0",
  "tasks": [
    {
      // 任务类型。
      "type": "shell",
      // 任务的用户界面中使用的标签;相当于变量名。
      "label": "local generate",
      // 实际执行的命令。
      "command": "hexo generate",
      // 定义如何在用户界面中处理任务输出,自行定义。
      "presentation": {
        // 命令面板。dedicated -> 如果任务已在命令面板中则重用此面板,否则新建面板。
        "panel": "dedicated",
        // 任务执行前是否清理命令面板。
        "clear": true
      },
      // 问题匹配器,为空则不匹配任何问题。
      "problemMatcher": []
    }
  ]
}

代码中的参数根据注释和名称自行理解,想要查看更多的参数信息或关于 Tasks 的信息可以访问官方文档

备注:上述任务中的 presentationproblemMatcher 是非必要的,但是实际使用时可以减少 VS Code 可能出现的询问次数。

配置多个 Hexo 命令

我们还需要按照上述增加其他命令,添加后的代码如下:

json

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "生成",
      "command": "hexo generate",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    // ----------
    // 新增代码
    {
      "type": "shell",
      "label": "清理",
      "command": "hexo clean",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    {
      "type": "shell",
      "label": "预览",
      "command": "hexo server",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    }
    // ----------
  ]
}

备注tasks 内的任务书写无顺序之分。

配置多个命令的顺序执行

代码如下:

json

{
  "version": "2.0.0",

  "tasks": [
    // ----------
    // 新增代码。
    {
      "label": "清理、生成并预览",
      // 执行顺序。sequence -> 顺序依次执行。
      "dependsOrder": "sequence",
      // 执行本任务前要执行的任务。在此处依次写入其他任务的标签(label)。
      "dependsOn": ["清理", "生成", "预览"],
      "problemMatcher": [],
      // 组。
      "group": {
        // 任务类型。
        "kind": "build",
        // 是否为默认任务。
        "isDefault": true
      }
    },
    // ----------
    {
      "type": "shell",
      "label": "清理",
      "command": "hexo clean",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    {
      "type": "shell",
      "label": "生成",
      "command": "hexo generate",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    {
      "type": "shell",
      "label": "预览",
      "command": "hexo server",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    }
  ]
}

其中本例内 group 的设置是为了将任务 local clear & server 设置为 VS Code “运行生成任务…”功能的默认任务,这样我们才能通过快捷键 Ctrl+Shift+B 执行此任务。

备注:新增的这个任务是一个自身不执行任何命令的任务。

执行 Tasks

完成上面的设置后,我们在编辑了 Hexo 的文章或其他内容后使用 Ctrl+Shift+B 快捷键就可以自动完成 Hexo 的清理、生成、开启本地预览。

如果想要执行上面配置的 3 个任务中的某一个,可以点击菜单栏“终端”下的“运行任务”来执行其中的任务。

运行任务
运行任务

如果最近任务里没有自己定义的任务,可以点击最下方的“显示所有任务…”来查看所有定义的任务。

疑问与解答

  1. 为什么要创建 4 个任务,而不是将最后任务的依赖设为前两个,这样就只会有 3 个任务(比如如下代码),这难道不是更简洁吗?

    json
    
    {
      "version": "2.0.0",
      "tasks": [
        {
          "type": "shell",
          "label": "清理",
          "command": "hexo clean",
          "presentation": {
            "panel": "dedicated",
            "clear": true
          },
          "problemMatcher": []
        },
        {
          "type": "shell",
          "label": "生成",
          "command": "hexo generate",
          "presentation": {
            "panel": "dedicated",
            "clear": true
          },
          "problemMatcher": []
        },
    
        // 最后一个任务执行前先执行其他两个
        {
          "type": "shell",
          "label": "预览",
          "command": "hexo server",
          "presentation": {
            "panel": "dedicated",
            "clear": true
          },
          "problemMatcher": [],
          "dependsOrder": "sequence",
          "dependsOn": ["清理", "生成"],
          "group": {
            "kind": "build",
            "isDefault": true
          }
        }
      ]
    }

    解答:这样设置会导致无法使用单一的命令 hexo server,因为调用 local server 这个任务总会调用其他两个。当然如果你不需要有单独执行命令 hexo server 的任务,那你这样写也可以。

  2. 只能通过 shell 类型的任务来完成本次的目标吗?
    :当然不是,你也可以使用 npm 等类型的任务来完成目标。

附录

你也可以参考上面的任务,自己添加 Hexo 的任务,比如一键部署等。

使用案例

json
{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "清理、生成并预览",
      "dependsOrder": "sequence",
      "dependsOn": ["清理", "生成", "预览"],
      "problemMatcher": [],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    },
    {
      "type": "shell",
      "label": "清理",
      "command": "hexo clean",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    {
      "type": "shell",
      "label": "生成",
      "command": "hexo generate",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    {
      "type": "shell",
      "label": "预览",
      "command": "hexo server",
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    {
      "type": "shell",
      "label": "新建文章",
      "command": "hexo",
      "args": ["new", "post", "${input:postName}"],
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    },
    {
      "type": "shell",
      "label": "新建草稿",
      "command": "hexo",
      "args": ["new", "draft", "${input:postName}"],
      "presentation": {
        "panel": "dedicated",
        "clear": true
      },
      "problemMatcher": []
    }
  ],
  "inputs": [
    {
      "type": "promptString",
      "id": "postName",
      "description": "文章名称"
    }
  ]
}

TODO List

准备做,但时间不确定的需求

自建 不蒜子 API

https://busuanzi.icodeq.com/

https://github.com/zkeq/Busuanzi_backend_self

访问速度优化

进行中

Search JS 优化

hexo-generator-searchdb

目标实例

CSS整理

进行中

插件内置修改

性能优化,外部插件内置修改

进行中

字体优化

字体体积比较大,是拖慢网页加载速度的重要因素。减少它的体积是重要的加速手段

Done!

  1. font forge
  2. hexo-fontawesome
  3. Customize-Font-Awesome
  4. 在线精简
    1. Fontello: http://fontello.com/
    2. IcoMoon: https://icomoon.io/app/#/select (How To)
    3. Fontastic: http://fontastic.me/

本教程还有其它五大部分,更多内容请见Hexo系列教程

系列教程

全部文章RSS订阅

Hexo系列

HexoRSS分类订阅

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

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

笔记系列

Note分类RSS订阅

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
  目录
  1. Hexo系列
  2. 用户交互沟通
  3. 添加博客看板娘
  4. 更强大的看板娘
  5. 添加夜间模式切换
  6. Tag标签外挂使用方法
  7. 屏蔽网页源码(单纯的屏蔽鼠标右键和键盘事件)
  8. 添加天气小插件
  9. 新增个人相册
  10. 支持RSS分类订阅
  11. 豆瓣书单电影页面
  12. 新增折叠功能
  13. 代码块全屏显示
  14. TOC目录展开收缩的小箭头
  15. 如何使用
  16. 让Hexo博客支持通知功能
  17. 客服聊天窗口
  18. 使用Valine-Admin管理评论和评论提醒
  19. 让hexo支持pwa
  20. valine 的使用与升级到1.4
  21. 新建文章自动打开本地Markdown编辑器
  22. 新建文章自动打开本地Vim编辑器
  23. 使用 VS Code 的任务(Tasks)便捷操作 Hexo
  24. TODO List
  25. 系列教程
支付宝扫码领红包