【博客搭建】3.7w字吐血分享hexo史上最全教程!超多魔改!三分钟让博客从init到低调奢华

整体效果

还在用看板娘、知乎风登录背景、飘带装饰你的hexo博客吗?本篇将带来不一样的博客美化!🤞并详细教你从hexo init到奢华博客!

整体效果可以看我的博客:unnamedtat的技术博客,这篇文章也是整理自我的四篇博文,有不清楚的也可以去找一下🥰🥰欢迎大家一起交流技术!
我的博客

点击上方目录方便跳转想看的部分!

基础工作准备

字数实在太多了,请走公众号👉三分钟快速搭建个性化博客。包含git配置、hexo安装、新博客的建立,十分详细。

完成博客搭建和主题选取后,开始我们的魔改之路吧!

个人配置文件

yourblog/_config.yml文件夹下,配置你的博客的基本信息。

# Site
title: A Small World of unnamedtat
subtitle: 'unnamedtat的技术博客'
description: 'Hello, world where we connect!'
keywords: GIS生态文献阅读; 算法分享; Web前端; Python; R
author: unnamedtat
language: zh-CN
  # - zh-CN
  # - en
timezone: ''

个人配置next/_config.yml文件

hexo主题选择

\themes\next\_config下,大约39行的位置,选择你喜欢的主题,有四种内置的主题可供我们选择,后续的美化就在此主题的基础上进行。

# Schemes
# scheme: Muse
#scheme: Mist
scheme: Pisces
#scheme: Gemini

# Dark Mode
darkmode: false

目前官方已经支持darkmode,但这里设置darkmode: true只能激活夜间模式,无法动态切换,因此博主在下面会给出其他的引入方式。

网站图标

favicon:
  small: /images/favicon-16x16-next.png
  medium: /images/favicon-32x32-next.png
  apple_touch_icon: /images/apple-touch-icon-next.png
  safari_pinned_tab: /images/logo.svg
  #android_manifest: /manifest.json

在这里可以设置你的网站图标,不用改名字直接替换对文件即可。

开启版权声明

下面则是版权声明的设置,你可以设置在侧边栏和每个post的底部开启,language不设置的话自动跟随网页的整体设置。

# Creative Commons 4.0 International License.
# See: https://creativecommons.org/about/cclicenses/
creative_commons:
  # Available values: by | by-nc | by-nc-nd | by-nc-sa | by-nd | by-sa | cc-zero
  license: by-nc-sa
  # Available values: big | small
  size: small
  sidebar: true
  post: true
  # You can set a language value if you prefer a translated version of CC license, e.g. deed.zh
  # CC licenses are available in 39 languages, you can find the specific and correct abbreviation you need on https://creativecommons.org
  language:

想要修改版权声明的文字可直接在source /languages/en.yml中修改。
文件位置

菜单栏、侧边栏、网站链接设置

在往下是网站的链接设置,想要哪一页取消注释即可,我这里开启了home、tags、archives、guestbooks。

可以在font awesome上面找你喜欢的图标作为链接的图标,默认是这样的,选中后修改对应like的fa-archive的文字即可.

图标
要使用外部链接,以 http:// or https://开头。

menu:
  home: / || fa fa-home
  #about: /about/ || fa fa-user
  tags: /tags/ || fa fa-tags
  # categories: /categories/ || fa fa-th
  archives: /archives/ || fa fa-archive
  #schedule: /schedule/ || fa fa-calendar
  # sitemap: /sitemap.xml || fa fa-sitemap
  # commonweal: /404/ || fa fa-heartbeat
  guestbook: /guestbook/ || fa fa-book
  
# Enable / Disable menu icons / item badges.
menu_settings:
  icons: true
  badges: true

在下面几行,你可以仔细微调侧标栏的位置、宽度等设置。

sidebar:
  # Sidebar Position.
  position: left
  #position: right

  # Manual define the sidebar width. If commented, will be default for:
  # Muse | Mist: 320
  # Pisces | Gemini: 240
  #width: 300

  # Sidebar Display (only for Muse | Mist), available values:
  #  - post    expand on posts automatically. Default.
  #  - always  expand for all pages automatically.
  #  - hide    expand only when click on the sidebar toggle icon.
  #  - remove  totally remove sidebar including sidebar toggle.
  display: post
  # Sidebar padding in pixels.
  padding: 18
  # Sidebar offset from top menubar in pixels (only for Pisces | Gemini).
  offset: 12

在大概184行的位置,还可以调整侧栏的目录。

toc:
  enable: true
  # Automatically add list number to toc.
  number: true
  # If true, all words will placed on next lines if header width longer then sidebar width.
  wrap: false
  # If true, all level of TOC in a post will be displayed, rather than the activated part of it.
  expand_all: true
  # Maximum heading depth of generated toc.
  max_depth: 6

头像设置、社交外链

在这里,你可以设置你头像的图床的外部链接/本地图像文件。
头像这里推荐可以上传到gravatar上,用邮箱登录唯一标识,很方便,也有国内镜像。

# Sidebar Avatar
avatar:
  # Replace the default image and set the url here.
  url: 你头像的url
  # If true, the avatar will be dispalyed in circle.
  rounded: false
  # If true, the avatar will be rotated with the cursor.
  rotated: false

rounded:是否圆形
rotated:hover是否旋转

在下面设置社交网站等的外链。

social:
  # GitHub:ttps://github.com/yourname  || fab fa-github
  #E-Mail: mailto:yourname@gmail.com || fa fa-envelope
  #Weibo: https://weibo.com/yourname || fab fa-weibo
  #Twitter: https://twitter.com/yourname || fab fa-twitter
  #FB Page: https://www.facebook.com/yourname || fab fa-facebook
  #StackOverflow: https://stackoverflow.com/yourname || fab fa-stack-overflow
  #YouTube: https://youtube.com/yourname || fab fa-youtube
  #Instagram: https://instagram.com/yourname || fab fa-instagram
  #Skype: skype:yourname?call|chat || fab fa-skype
 # RSS: ???/rss.xml || fa fa-rss

效果

博文设置(摘要、阅读更多、字数统计等)

直接搜索# Post Settings就可以看到了。

# Use `description` in front-matter to specify post excerpt.
excerpt_description: false
#是否首页只显示摘要
# Read more button
# If true, the read more button will be displayed in excerpt section.
read_more_btn: true
#阅读更多
# Post meta display settings
post_meta:
  item_text: true
  created_at: true
  updated_at:
    enable: true
    another_day: true
  categories: true
#在每篇博文前显示的内容
# Post wordcount display settings
# Dependencies: https://github.com/next-theme/hexo-word-counter
symbols_count_time:
  separated_meta: false
  item_text_total: false
#字数统计
# Use icon instead of the symbol # to indicate the tag at the bottom of the post
tag_icon: false

其中使用symbols_count_time需要安装hexo-word-counter

npm i hexo-word-counter --save

打赏

reward:
  #wechatpay: /images/wechatpay.png
  #alipay: /images/alipay.png
  #paypal: /images/paypal.png
  #bitcoin: /images/bitcoin.png

取消设置,在对应的文件夹加入图片。

返回顶部按钮、阅读进度条、gitbanner

line:383,全部设置enable为true

back2top:
  enable: true
  # Back to top in sidebar.
  sidebar: false
  # Scroll percent label in b2t button.
  scrollpercent: false

# Reading progress bar
reading_progress:
  enable: true
  # Available values: left | right
  start_at: left
  # Available values: top | bottom
  position: top
  reversed: false
  color: "rgba(236,94,135,1)"
  height: 3px

github_banner启用则是在右上角显示你的GitHub跳转方式。

github_banner:
  enable: false
  permalink: https://github.com/yourname

自定义字体

设置font: enable: true,host改为https://fonts.loli.net的镜像,然后即可在https://fonts.googleapis.com挑选一款你喜欢的字体啦!

font:
  enable: true

  # Uri of fonts host, e.g. https://fonts.googleapis.com (Default).
  host: https://fonts.loli.net

  # Font options:
  # `external: true` will load this font family from `host` above.
  # `family: Times New Roman`. Without any quotes.
  # `size: x.x`. Use `em` as unit. Default: 1 (16px)

  # Global font settings used for all elements inside <body>.
  global:
    external: true
    family: 
    size:

配置搜索功能

你可以安装插件配置搜索功能,也可以启用local search,其可以帮助搜索引擎检索你的内容,使用Algolia Search需要安装插件,并配置密钥。
建议使用第二种。
npm i hexo-generator-searchdb --save
然后配置

# Algolia Search
# For more information: https://www.algolia.com
algolia_search:
  enable: false
  hits:
    per_page: 10

# Local Search
# Dependencies: https://github.com/next-theme/hexo-generator-searchdb
local_search:
  enable: true
  # If auto, trigger search by changing input.
  # If manual, trigger search by pressing enter key or search button.
  trigger: auto
  # Show top n results per article, show all results by setting to -1
  top_n_per_article: 1
  # Unescape html strings to the readable one.
  unescape: false
  # Preload the search data when the page loads.
  preload: false

在这里插入图片描述

界面美化(darkmode-next插件、动态背景、点击特效等)

先在本节挑选一款你的动态背景吧!

知乎风格动态背景

像这样的同款知乎风格动态背景线条浮动的效果🤔,只需要引入一个文件即可做到🥰。
知乎风格动态背景

  1. 将目录更改为 Hexo 目录。必须有 scaffolds 、 source 、 themes 等目录:
$ cd hexo
$ ls
scaffolds  source  themes  _config.yml  package.json
  1. 创建 footer.swig
    在 hexo/source/_data 目录中创建名为 footer.swig 的文件(如果 _data 目录不存在,则创建该文件)。编辑该文件并添加以下内容,可以修改其内容:
<script color="0,0,255" opacity="0.5" zIndex="-1" count="99" src="https://cdn.jsdelivr.net/npm/canvas-nest.js@1/dist/canvas-nest.js"></script>
  1. 在 NexT _config.yml 中,取消 custom_file_path 部分下的 footer 注释。
custom_file_path:
  #head: source/_data/head.swig
  #header: source/_data/header.swig
  #sidebar: source/_data/sidebar.swig
  #postMeta: source/_data/post-meta.swig
  #postBodyEnd: source/_data/post-body-end.swig
  footer: source/_data/footer.swig
  #bodyEnd: source/_data/body-end.swig
  #variable: source/_data/variables.styl
  #mixin: source/_data/mixins.styl
  #style: source/_data/styles.styl

添加网格地球、飞鸟等动态主题背景

这样丰富多彩的动态背景,其实开箱即用,只需要插入几行代码即可。
在这里插入图片描述

用到:vantajs

根据官网说明,在 themes\next\layout中引入对应源码,做好修改,注意div的样式设置为 width: 100vw;height: 100vh;若想使背景透明,设置 backgroundAlpha:0.00即可.
例如鸟群效果:
鸟群

<script src="three.r134.min.js"></script>
<script src="vanta.birds.min.js"></script>
<script>
VANTA.BIRDS({
  el: "#your-element-selector",
  mouseControls: true,
  touchControls: true,
  gyroControls: false,
  minHeight: 200.00,
  minWidth: 200.00,
  scale: 1.00,
  scaleMobile: 1.00
})
</script>

添加自定义夜间模式

你可以选择darkmode插件,也可以选择直接引入darkmodeJS,以实现自定义的夜间模式切换按控件,并实现更高的自定义、配合动态主题。

我个人建议直接引入darkmodeJS,这样可以实现切换按钮的自定义和网站背景的配合等。

这里的options中,mixcolor最好为transparent,不然darkmodeJS会直接根据颜色的差值为你的网站制定夜间模式,丑+简陋,不过省事儿~看个人选择啦。

  <script src="https://cdn.jsdelivr.net/npm/darkmode-js@1.5.7/lib/darkmode-js.min.js"></script>
  <script>
  const options = {
  bottom: '64px', // default: '32px'
  right: 'unset', // default: '32px'
  left: '32px', // default: 'unset'
  time: '0.5s', // default: '0.3s'
  mixColor: '#transparent', // default: '#fff'
  backgroundColor: '#transparent',  // default: '#fff'
  buttonColorDark: '#100f2c',  // default: '#100f2c'
  buttonColorLight: '#fff', // default: '#fff'
  saveInCookies: true, // default: true,
  label: '🌓', // default: ''
  autoMatchOsTheme: true // default: true
  }
  const darkmode = new Darkmode(options);
  darkmode.showWidget();
  </script>

更高级的,可以配合动态背景和自定义按钮,可例如下面这样的示例,通过界面上一个checkbox元素实现切换:
layout文件中

  <div id="background" style="z-index: -2;position: fixed;top: 0;left: 0;width: 100vw;height: 100vh;"></div>
  <script src="three.r134.min.js"></script>
<script src="vanta.birds.min.js"></script>
<label class="daynight">
    <input type="checkbox">
    <div></div>
      <script type="text/javascript" src="/js/daynight.js"></script>

/js/daynight.js

const globe = VANTA.GLOBE({
    el: "#background",
    mouseControls: true,
    touchControls: true,
    gyroControls: false,
    minHeight: 200.00,
    minWidth: 200.00,
    scale: 1.00,
    scaleMobile: 1.00,
    color: 0xc00021,
    color2: 0x810000,
    size: 1,
    backgroundAlpha: 0.00
    })  
  function changeColor() {
    if (darkmode.isActivated()){
    globe.setOptions({
    color: 0xef8232,
    color2: 0xffbbbb,
    })}
    else {
    globe.setOptions({
    color: 0xc00021,
    color2: 0x810000,
    })}}  
  const darkmode =  new Darkmode({
  mixColor: 'transparent', // default: '#fff'
  backgroundColor: 'transparent',  // default: '#fff'
  });
  if(window.matchMedia('(prefers-color-scheme: dark)').matches && !darkmode.isActivated()) darkmode.toggle();
  const checkbox = document.querySelector('.daynight input');
  if (darkmode.isActivated())checkbox.checked = true;
  else checkbox.checked = false;
  changeColor();

  checkbox.addEventListener('change', function() {
    darkmode.toggle();
    changeColor();
  });

彩带

设置:

canvas_ribbon:
  enable: true
  size: 300 # The width of the ribbon
  alpha: 0.6 # The transparency of the ribbon
  zIndex: -1 # The display level of the ribbon

size :功能区的大小,默认: 90 。
alpha :线条的不透明度 (0 ~ 1),默认: 0.6 。
zIndex :默认: -1 。

添加点击爱心效果

在这个文件中插入:
在这里插入图片描述

<script type="text/javascript" src="/js/heart.js"></script>

对应的/js/heart.js文件:

! function(e, t, a) {
    function n() {
        var cssStyles = ".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}";
        c(cssStyles), o(), r()
    }

    function r() {
        for (var e = 0; e < d.length; e++) d[e].alpha <= 0 ? (t.body.removeChild(d[e].el), d.splice(e, 1)) : (d[e].y--, d[e].scale += .004, d[e].alpha -= .013, d[e].el.style.cssText = "left:" + d[e].x + "px;top:" + d[e].y + "px;opacity:" + d[e].alpha + ";transform:scale(" + d[e].scale + "," + d[e].scale + ") rotate(45deg);background:" + d[e].color + ";z-index:99999");
        requestAnimationFrame(r)
    }

    function o() {
        var t = "function" == typeof e.onclick && e.onclick;
        e.onclick = function(e) {
            t && t(), i(e)
        }
    }

    function i(e) {
        // 生成正常大小的爱心
        var a = t.createElement("div");
        a.className = "heart";
        d.push({
            el: a,
            x: e.clientX ,
            y: e.clientY ,
            scale: 1,
            alpha: 1,
            color: s()
        });
        t.body.appendChild(a);
    
        // 环绕生成多个小爱心
        for (var j = 0; j < 5; j++) { // 生成16个小爱心
            var angle = (j / 5) * Math.PI; // 计算角度
            var radius = 20; // 半径
            var x = e.clientX + radius * Math.cos(angle); // 计算x坐标
            var y = e.clientY - radius * Math.sin(angle); // 计算y坐标
    
            var b = t.createElement("div");
            b.className = "heart tiny";
            d.push({
                el: b,
                x: x,
                y: y,
                scale: 0.5,
                alpha: 1,
                color: s()
            });
            t.body.appendChild(b);
        }
    }
    function c(e) {
        var a = t.createElement("style");
        a.type = "text/css";
        try {
            a.appendChild(t.createTextNode(e))
        } catch (t) {
            a.styleSheet.cssText = e
        }
        t.getElementsByTagName("head")[0].appendChild(a)
    }

    function s() {
        var colors = [
            "rgba(236,94,135,1)", // 浅红
            "rgba(241,144,102,1)", // 橘黄
            "rgba(245,194,79,1)", // 浅黄
            "rgba(106,170,100,1)", // 浅绿        
            "rgba(159,122,234,1)" // 浅紫
        ];
        return colors[Math.floor(Math.random() * colors.length)];
    }
    var d = [];
    e.requestAnimationFrame = function() {
        return e.requestAnimationFrame || e.webkitRequestAnimationFrame || e.mozRequestAnimationFrame || e.oRequestAnimationFrame || e.msRequestAnimationFrame || function(e) {
            setTimeout(e, 1e3 / 60)
        }
    }(), n()
}(window, document);

添加点击烟花效果

在布局中引入(animatejs库已经引入过了):

     <canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 41; pointer-events: none;" ></canvas> 
    <script type="text/javascript" src="/js/firework.js"></script>   

/js/firework.js文件:

  var canvasEl = document.querySelector('.fireworks');
  var ctx = canvasEl.getContext('2d');
  var numberOfParticules = 30;
  var pointerX = 0;
  var pointerY = 0;
  var tap = "mousedown";
  var colors = ["#fa5557", "#54b4f1", "#f3eed9", "#6f0000"];

  function setCanvasSize() {
    canvasEl.width = window.innerWidth * 2;
    canvasEl.height = window.innerHeight * 2;
    canvasEl.style.width = window.innerWidth + 'px';
    canvasEl.style.height = window.innerHeight + 'px';
    canvasEl.getContext('2d').scale(2, 2);
  }

  function updateCoords(e) {
    pointerX = e.clientX || e.touches[0].clientX;
    pointerY = e.clientY || e.touches[0].clientY;
  }

  function setParticuleDirection(p) {
    var angle = anime.random(0, 360) * Math.PI / 180;
    var value = anime.random(50, 180);
    var radius = [-1, 1][anime.random(0, 1)] * value;
    return {
      x: p.x + radius * Math.cos(angle),
      y: p.y + radius * Math.sin(angle)
    }
  }

  function createParticule(x,y) {
    var p = {};
    p.x = x;
    p.y = y;
    p.color = colors[anime.random(0, colors.length - 1)];
    p.radius = anime.random(16, 32);
    p.endPos = setParticuleDirection(p);
    p.draw = function() {
      ctx.beginPath();
      ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, true);
      ctx.fillStyle = p.color;
      ctx.fill();
    }
    return p;
  }

  function createCircle(x,y) {
    var p = {};
    p.x = x;
    p.y = y;
    p.color = "#F00";
    p.radius = 0.1;
    p.alpha = .5;
    p.lineWidth = 6;
    p.draw = function() {
      ctx.globalAlpha = p.alpha;
      ctx.beginPath();
      ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, true);
      ctx.lineWidth = p.lineWidth;
      ctx.strokeStyle = p.color;
      ctx.stroke();
      ctx.globalAlpha = 1;
    }
    return p;
  }

  function renderParticule(anim) {
    for (var i = 0; i < anim.animatables.length; i++) {
      anim.animatables[i].target.draw();
    }
  }

  function animateParticules(x, y) {
    var circle = createCircle(x, y);
    var particules = [];
    for (var i = 0; i < numberOfParticules; i++) {
      particules.push(createParticule(x, y));
    }
    anime.timeline().add({
      targets: particules,
      x: function(p) { return p.endPos.x; },
      y: function(p) { return p.endPos.y; },
      radius: 0.1,
      duration: anime.random(1200, 1800),
      easing: 'easeOutExpo',
      update: renderParticule,
    })
      .add({
      targets: circle,
      radius: anime.random(80, 160),
      lineWidth: 0,
      alpha: {
        value: 0,
        easing: 'linear',
        duration: anime.random(600, 800),  
      },
      duration: anime.random(1200, 1800),
      easing: 'easeOutExpo',
      update: renderParticule,
    },  0);
  }

  var render = anime({
    duration: Infinity,
    update: function() {
      ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
    }
  });

  document.addEventListener(
      tap,
      function (e) {
          "sidebar" !== e.target.id &&
          "toggle-sidebar" !== e.target.id &&
          "A" !== e.target.nodeName &&
          "IMG" !== e.target.nodeName &&
          (render.play(), updateCoords(e), animateParticules(pointerX, pointerY));
      },
      !1
    )

  setCanvasSize();
  window.addEventListener('resize', setCanvasSize, false);

为你写好的stylus样式

取消source\_data\styles.styl的注释,并在对应的文件中填入,以下效果可以在我的博客看噢a small world of unnamedtat。看css👀都要瞎了,求个三连吧!:

//基础darkmode样式
.darkmode--activated 
  --body-bg-color: #282828;
  --content-bg-color: #333;
  --card-bg-color: #555;
  // --text-color: #ccc;
  --blockquote-color: #bbb;
  --link-color: #ccc;
  --link-hover-color: #eee;
  --brand-color: #ddd;
  --brand-hover-color: #ddd;
  --table-row-odd-bg-color: #282828;
  --table-row-hover-bg-color: #363636;
  --menu-item-bg-color: #555;
  --btn-default-bg: #222;
  --btn-default-color: #ccc;
  --btn-default-border-color: #555;
  --btn-default-hover-bg: #666;
  --btn-default-hover-color: #ccc;
  --btn-default-hover-border-color: #666;
  --highlight-background: #282b2e;
  --highlight-foreground: #a9b7c6;
  --highlight-gutter-background: #34393d;
  --highlight-gutter-foreground: #9ca9b6;
  img 
    opacity: 0.75;
  img:hover 
    opacity: 0.9;
  code 
    color: #fb9325;
    background: rgb(111, 111, 111,0.5);
  // 自定义样式
  .post-body, .post-title,.post-content,.article-nav-caption,.site-author-name 
    color: #ffffff;
  strong
    color: #000000;
    background-color: #fb9325;
  .post-body a
    color: #ccc;				
  /* 基于hljs魔改的darkmode代码块样式*/
  //字符串
  .hljs-string
    color: #ce9178;
  //数值
  .hljs-number,
  .hljs-params
    color: #00c9ac
  //关键字、函数名等
  .hljs-keyword,
  .hljs-function
  .hljs-title, 
  .hljs-function_
    color: #dcdcaa; 
  //标签名
  .hljs-tag,
  .hljs-name
    color: #8e8e8e; 
  //注释
  .hljs-comment 
    color: #7f9f7f; 
  //属性名
  .hljs-attr,
  .hljs-attribute
    color: #569cd6; 
  //进度条
  .reading-progress-bar
    background: #fb9325;
  .hljs-selector-class
    color: #dfad87; 
  .hljs-selector-pseudo
    color: #ffeacf;
  // 选中状态
  ::selection
    background: #5f6368;
    color: #eee;
  .posts-expand  .post-eof 
    border: 1px double #eee;
  //评论区
  .data-waline
    color: #373737;
  .wl-panel
    background: #404040;
  .comments * 
    color: #fff;
  .wl-addr,.wl-browser,.wl-os
    color: #fff!important;
    background-color: transparent!important; 
    border: 1px solid #fff!important;
  .wl-input:focus,
  .wl-editor:focus,
  .wl-nick:focus 
    background-color: rgba(120, 120, 120, 0.1)!important; 
    color: #ffffff; 
    outline: none; 
  .back-to-top
    background: #fb9325;
  .note
    opacity : 0.5;
  .note p
    color: #000000;
    opacity: 1;
  .search-header
    background: rgba(0, 0, 0, 0.2);
  .search-input
    color: #ffffff;
  .search-popup
    z-index:1000;
    background: rgba(0, 0, 0, 0.2);
  .post-copyright *
    color: #ffffff;
  .post-copyright strong 
    background-color: transparent;
// 修复图片无法剧中的bug
img, .darkmode-ignore 
  display: flex !important;
.beian img 
  display: inline-block !important;
// 整个主体的透明度
@media (max-width: 767px) 
  .main-inner 
    opacity: 0.9;
// 顶栏
.site-brand-container
  background: #3d3d3d;
.site-title
  font-weight: bold;
  // letter-spacing: 0.1em;
//文章标题颜色
.post-title-link, .post-title
    font-weight: bold;
//文字颜色
.post-body
    color: #000;
//链接颜色
.post-body  a
    color: #484848;
    font-weight: bold;				
/* 基于hljs魔改的代码块样式*/
.highlight
  color: #000000; 
//字符串
.hljs-string 
  color: #866900;
//数值
.hljs-number,
.hljs-params
  color: #72801c; 
//关键字、函数名等
.hljs-keyword,
.hljs-function
.hljs-title, 
.hljs-function_
  color: #d73a49; 
  font-weight: bold; 
//标签名
.hljs-tag,
.hljs-name
  color: #007b2e; 
  font-weight: bold; 
//注释
.hljs-comment 
  color: #430100; 
  font-style: italic; 
//属性名
.hljs-attr,
.hljs-attribute
  color: #be6f24; 
  font-weight: bold;
.hljs-selector-class
  color: #4d0c00; 
.hljs-selector-pseudo
  color: #bd5925;
::selection 
  background: #000000;
  color: #eee;
.posts-expand .post-eof 
    width: 80%;
    height: 0px;
    background: none;
    border: 1px double #868686;
    text-align: center;
// 去掉顶部黑线
.headband 
  background-color: transparent;
:root 
  --waline-theme-color: #ff6347!important; 
  --waline-active-color: #fb9325!important; 
//返回顶部按钮
.back-to-top
  border-radius: 15%;
.search-header
  background-color: rgba(238, 238, 238, 0.2);
.search-popup
  backdrop-filter: blur(15px);
  background-color: #f5f5f584
  box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);
//下一篇上一篇导航栏
.article-nav-caption 
  font-weight: bold;
.darkmode-toggle
  user-select: none
  -webkit-tap-highlight-color: transparent;

最后是一个好用的颜色生成网站:ColorSpace,生成了好看的颜色填进去就行了🥰🥹🥹

异步加载动态背景、darkmodeJS统一

网上目前有很多教程,外部脚本加载都放在布局文件里面,实际上hexo并不会异步加载,堵塞主进程。而我们如果不想过多地动模板文件(因为hexo和主题更新换代很快,需要考虑到迁移问题),就可以通过自己脚本里面promise异步加载的方式,提高网页的加载速度。

例如,我的网站需要加载darkmodeJS一个自己写好的toggle按钮和一个动态背景,并且需要调用一些第三方库。因此我们在promise加载脚本完成之后再执行需要的操作。

function loadScript(src) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = src;
    script.onload = resolve;
    script.onerror = reject;
    document.head.appendChild(script);
  });
}
Promise.all([
  loadScript('https://cdnjs.cloudflare.com/ajax/libs/Darkmode.js/1.5.7/darkmode-js.min.js'),
  loadScript('https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js'),
]).then(() => {
  return loadScript('https://cdnjs.cloudflare.com/ajax/libs/vanta/0.5.24/vanta.globe.min.js')
})
  .then(() => {
    const globe = VANTA.GLOBE({
    el: '#background',
    mouseControls: true,
    touchControls: true,
    gyroControls: false,
    minHeight: 200.00,
    minWidth: 200.00,
    scale: 1.00,
    scaleMobile: 1.00,
    color: 0xeff6347,
    color2: 0xefb9325,
    size: 1,
    backgroundAlpha: 0.00
    })  
  const backgroundElement = document.querySelector('#background');
  backgroundElement.style.opcaity = 1;
  function changeColor() {
    if (darkmode.isActivated()){
    globe.setOptions({
    color: 0xfb9325,
    color2: 0xffffff,
    })}
    else {
    globe.setOptions({
    color: 0xeff6347,
    color2: 0xefb9325,
    })}}  
  const darkmode =  new Darkmode({
  mixColor: 'transparent', // default: '#fff'
  backgroundColor: 'transparent',  // default: '#fff'
  });
  if(window.matchMedia('(prefers-color-scheme: dark)').matches && !darkmode.isActivated()) darkmode.toggle();
  const checkbox = document.querySelector('.daynight input');
  if (darkmode.isActivated())checkbox.checked = true;
  else checkbox.checked = false;
  changeColor();

  checkbox.addEventListener('change', function() {
    darkmode.toggle();
    changeColor();
  });

  })
  .catch(err => console.error('Failed to load scripts', err));

  document.addEventListener('DOMContentLoaded', function() {
    const daynightDiv = document.querySelector('.daynight');
    daynightDiv.style.opacity = 1;
  });

这样我们只用在模板文件里面引入对于的div元素和该脚本即可。

你可能已经注意到了,在这两个元素的加载事件还额外添加了 style.opacity = 1。这是因为博主观察到hexo的各个元素在加载完成时都不是直接出现的,而是有一个渐变。我们自己的元素直接直愣愣地出现,给人感觉很突兀。因此,我们可以在自定义的 styles.styl文件中添加对于自定义元素的默认隐藏和渐变出现效果:

#background,.daynight
  opacity: 0;
  transition: opacity 0.5s ease-in;

而在 onload事件中,添加 style.opacity = 1;这样其出现就会带有过渡效果了。

或者使用 animateJS库(已经引入过),像这样,也是一样的效果!

backgroundElement.classList.add('animated');  
backgroundElement.classList.add('fadeIn');

进阶:网站部署及评论系统

点击waline部署,部署一个你自己的waline评论系统。

把waline后端和你的blogs项目都扔到vercel上部署,取得Leancloud凭证,配置好 vercel-settings-environment variables

想要让你的网站能够在拆哪直连,首先你要拥有一个域名,国内域名要备案就没写出来了:

然后在blog项目的 vercel-settings-domains配置一级域名 xxx.com cname解析,再配置好 www.xxx.com的重定向。

这里vercel会自动recommend这个方案,按照它上面的方式配置就好了,注意域名解析的时候的 address/value 值要写 cname-china.vercel-dns.com,以避免dns污染!

与之相对的把二级域名 waline.xxx.com解析到后端评论系统,address/value值同上。

最后的效果要是这样的。

效果

其他改善访问速度的方法:

以下是参考教程:

网站收录和推送

你需要安装hexo-generator-searchdbhexo-generator-sitemaphexo-generator-baidu-sitemap等插件。

关于permalink设置

安装hexo-abbrlink插件,生成唯一的永久链接。
npm install hexo-abbrlink --save
修改 config.yml 文件中的永久链接:
permalink: posts/:abbrlink/
设置:

# abbrlink config
abbrlink:
  alg: crc32      #support crc16(default) and crc32
  rep: hex        #support dec(default) and hex
  drafts: false   #(true)Process draft,(false)Do not process draft. false(default) 
  # Generate categories from directory-tree
  # depth: the max_depth of directory-tree you want to generate, should > 0
  auto_category:
     enable: true  #true(default)
     depth:        #3(default)
     over_write: false 
  auto_title: false #enable auto title, it can auto fill the title by path
  auto_date: false #enable auto date, it can auto fill the date by time today
  force: false #enable force mode,in this mode, the plugin will ignore the cache, and calc the abbrlink for every post even it already had abbrlink. This only updates abbrlink rather than other front variables.# abbrlink config
abbrlink:
  alg: crc32      #support crc16(default) and crc32
  rep: hex        #support dec(default) and hex
  drafts: false   #(true)Process draft,(false)Do not process draft. false(default) 
  # Generate categories from directory-tree
  # depth: the max_depth of directory-tree you want to generate, should > 0
  auto_category:
     enable: true  #true(default)
     depth:        #3(default)
     over_write: false 
  auto_title: false #enable auto title, it can auto fill the title by path
  auto_date: false #enable auto date, it can auto fill the date by time today
  force: false #enable force mode,in this mode, the plugin will ignore the cache, and calc the abbrlink for every post even it already had abbrlink. This only updates abbrlink rather than other front variables.

post-body-end切换博文按钮

由于没找到next主题的切换博文功能,参考landscape主题的写了一个。

放在post-body-end.njk,在next主题里面config文件取消该路径的注释就可以了。🥰

{# 导航部分 #}
<nav id="article-nav">
  {# 上一篇文章链接 #}
  {% if post.prev %}
  <div id="article-nav-pre" class="article-nav-link-wrap">
    <span class="article-nav-caption">{{ __('precious') }} {{ __('symbol.colon') }}</span>
    <a class="article-nav-title" href="{{ url_for(post.prev.path) }}" >
      {% if post.prev.title %}
        {{ post.prev.title }}
      {% else %}
        (no title)
      {% endif %}
    </a>
  </div>
  {% endif %}
  {# 下一篇文章链接 #}
  {% if post.next %}
  <div id="article-nav-next" class="article-nav-link-wrap">
    <span class="article-nav-caption">{{ __('next') }}  {{ __('symbol.colon') }} </span>
    <a class="article-nav-title" href="{{ url_for(post.next.path) }}" >
      {% if post.next.title %}
        {{ post.next.title }}
      {% else %}
        (no title)
      {% endif %}
    </a>
  </div>
</nav>
  {% endif %}

#####然后在zh-CN.yml里面添加
precious: 上一篇
next: 下一篇

自定义404界面

hexo new page 404

然后设置

title:
date: 2024-03-31 19:50:15
permalink: /404.html
comments: false

以及文字,效果在这里。🥰

还可以引入别人写好的美观自定义404页面html,但是我喜欢简约就自己弄了一个啦。

在页面加入数码宠物

参考大佬源码,我进行了魔改: Digital Pet-luke lincoln

可以直接在要加入宠物的页面的md文档中添加,以免过多修改源码

或者自己定制对应页面模板/html.

<p style="text-align: center">或者来养一只小猫咪吧~</p>
<div class="wrapper">
 <div class="innerWrapper">
<svg viewBox="0 0 158.82 186.47"><g id="outline"><path id="main-tamago" d="M23.5,104.55l.88,14.21a55.29,55.29,0,0,0,4,17.52l5.16,12.64a55.37,55.37,0,0,0,12.88,19L50.68,172a55.08,55.08,0,0,0,18.61,11.78l11.36,4.33a55.39,55.39,0,0,0,19.65,3.61h5.25A55.3,55.3,0,0,0,121,189.45l7.79-2.27A55.37,55.37,0,0,0,146,178.72l3.91-2.87a55.31,55.31,0,0,0,13.41-14l5.37-8.11a55,55,0,0,0,6.78-14.38l4-13a55.35,55.35,0,0,0,2.22-11.55l.38-4.62a55,55,0,0,0-.34-12.23L180,85.52A56.06,56.06,0,0,0,177.42,75l-5.07-14.56a55.22,55.22,0,0,0-4.4-9.57L163.37,43A55.77,55.77,0,0,0,157,34.12l-5.61-6.34a55,55,0,0,0-12.53-10.53L133.5,14a55.51,55.51,0,0,0-10.07-4.84l-1.7-.62a55.31,55.31,0,0,0-18.81-3.3h0A55,55,0,0,0,86.61,7.67l-.42.13a55.32,55.32,0,0,0-13,5.93L67.68,17.2a55.08,55.08,0,0,0-11.05,9.08l-6.83,7.3a55.77,55.77,0,0,0-7.9,10.8L34.44,57.73A55.17,55.17,0,0,0,29,71.62L25,88.1A55.22,55.22,0,0,0,23.5,104.55Z" transform="translate(-23.4 -5.2)" style="fill:rgb(241, 195, 98)"/></g><g id="light"><path d="M138.18,42.31l-1.7,13.12,16.93,12.48-2.5,18.59,4.81,12.85a5.49,5.49,0,0,0,3.82,3.37h0a5.42,5.42,0,0,0,6.08-2.79l2-3.87a5.53,5.53,0,0,0,.59-2l1.23-14a5.58,5.58,0,0,0-.07-1.47l-2.5-13.5a5.57,5.57,0,0,0-.49-1.44l-4.92-9.84a5.36,5.36,0,0,0-.69-1.06l-9-10.75a5.4,5.4,0,0,0-1.36-1.16l-4-2.45A5.43,5.43,0,0,0,138.18,42.31Z" transform="translate(-23.4 -5.2)" style="fill:#fff;opacity:0.36"/></g><g id="darkshadowy"><path d="M76.27,9.36" transform="translate(-23.4 -5.2)" style="fill:none;stroke:red;stroke-miterlimit:10"/><g style="opacity:0.21"><path d="M73.22,13.73,67.68,17.2a55.08,55.08,0,0,0-11.05,9.08l-6.83,7.3a55.77,55.77,0,0,0-7.9,10.8L34.44,57.73A55.17,55.17,0,0,0,29,71.62L25,88.1a55.22,55.22,0,0,0-1.47,16.45l.88,14.21a55.29,55.29,0,0,0,4,17.52l5.16,12.64a55.37,55.37,0,0,0,12.88,19L50.68,172a55,55,0,0,0,13.23,9.39,5.21,5.21,0,0,0,.89-3.91c-.32-2.44.83-10.25-9.12-18.19-9.15-7.3-11.92-8.62-14.71-13.32-2.29-3.87-3-7.29-4.16-13.32a86.46,86.46,0,0,1-1.39-16.93A126.47,126.47,0,0,1,36,101c.37-3.78.77-6,4.16-22.2,3.14-15,3.39-16,4.16-18,1-2.51,3.41-7.22,8.33-16.65,2.73-5.23,3.79-7.09,5.55-9.43a58.59,58.59,0,0,1,8-8.6c3.88-3.43,4.39-3,6.38-5.27.76-.85,4.84-5.57,5.06-9.51C76.15,12,74.66,12.83,73.22,13.73Z" transform="translate(-23.4 -5.2)" style="fill:#150d00"/></g></g><g id="inner-outline"><polygon points="36.5 79.91 24.84 109.33 36.5 126.81 34 136.52 47.6 147.34 62.86 142.9 76.45 154 93.66 143.46 114.75 147.06 125.84 114.6 133.34 106 122.52 84.08 124.73 64.65 108.92 52.44 96.99 59.1 70.35 50.22 55.09 57.72 38.44 56.05 36.5 79.91" style="fill:#fdffdf"/></g></svg>

<canvas class="cnvs"></canvas>
<button id="callbutton"></button>
  </div>
</div>
<style>
.wrapper {
  width: 100%;
  height: 100%;
  margin-top: 8px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.innerWrapper {
  width: 200px;
  position: relative;
}
.innerWrapper svg {
  width: 200px;
}
.cnvs {
  width:80px;
  height:80px;
  background-color: rgba(60, 75, 60, 0.3);
  position: absolute;
  top: 80px;
  left: 60px;
  border-radius: 10px;
  box-shadow: 5px 4px 0px 1px rgba(40, 55, 40, 0.4) inset;
}
#callbutton {
  position: absolute;
  top: 194px;
  left: 85px;
  width: 38px;
  height: 38px;
  border-radius: 40%;
  background-color: #fdffdf;
}
#callbutton:focus {
  outline: 0;
}
#callbutton:active {
  background-color: #e0e2c9;
  box-shadow: -0.1px -0.5px 0px 2px #00000033;
}
</style>
<script>
const cvs = document.querySelector(".cnvs");
const size = 110;
cvs.width = size;
cvs.height = size;
const ctx = cvs.getContext("2d");
const pxSize = 2;
const sleepingCat = `
xx...xx........x
x.xxx.x........x
x.....x.......x.
x.x.x.xxxxx..x..
x.....x....xxx..
.x...x.....x....
..xxxx.....x....
....xxxxxxx.....
`;
const standingCatToLeft = `
xx...xx........x
x.xxx.x........x
x.....x.......x.
x.x.x.xxxxx..x..
x.....x....xxx..
.x...x.....x....
..xxxx.....x....
....xxxxxxx.....
.....x.x.xxx....
.....x.x.x.x....
`;
const standingCatToLeftPose2 = `
xx...xx........x
x.xxx.x........x
x.....x.......x.
x.x.x.xxxxx..x..
x.....x....xxx..
.x...x.....x....
..xxxx.....x....
....xxxxxxx.....
....x.x.xxx.....
...x..x.x..x....
`;
const sleepZSml = `
xx
.x.
.xx
`;
const sleepZMed = `
xxx.
..x.
.x..
.xxx
`;
const sleepZLarge = `
xxxx.
..x..
.x...
.xxxx
`;
let state = {
  type: "walk",
  x: 0
};
function drawArt(px, py, str, flip, col = "rgb(60, 75, 60)") {
  const lines = str.split("\n");
  for (let y = 0; y < lines.length; y++) {
    let chars = lines[y].split("");
    if (flip) chars.reverse();
    for (let x = 0; x < chars.length; x++) {
      if (chars[x] === "x") drawRect(x + px, y + py, col, true);
    }
  }
}
function drawRect(x, y, col = "black", fill = false) {
  if (fill) {
    ctx.fillStyle = col;
    ctx.fillRect(x * pxSize, y * pxSize, pxSize, pxSize);
    return;
  }
  ctx.strokeStyle = col;
  ctx.fillStyle = "";
  ctx.beginPath();
  ctx.lineWidth = "1";
  ctx.rect(x * pxSize, y * pxSize, pxSize, pxSize);
  ctx.stroke();
}
function clear() {
  ctx.clearRect(0, 0, size, size);
}
function drawGrid() {
  let gridRows = Math.floor(size / pxSize);
  for (let i = 0; i < gridRows; i++) {
    for (let j = 0; j < gridRows; j++) {
      drawRect(j * 2, i * 2, "blue", false);
    }
  }
}
function refresh() {
  clear();
  switch (state.type) {
    case "sleep":
      {
        sleepAnimation();
      }
      break;
    case "stand":
      {
        standAnimation();
      }
      break;
    case "walk":
      {
        walkAnimation();
      }
      break;
    default:
  }
}
function sleepAnimation() {
  if (state.t === undefined) state.t = 0;
  drawArt(20, 32, sleepingCat);
  if (state.t >= 1) drawArt(28, 27, sleepZSml);
  if (state.t >= 2) drawArt(32, 22, sleepZMed);
  if (state.t >= 3) drawArt(36, 18, sleepZLarge);
  state.t = (state.t + 1) % 4;
  // if (Math.random() < 0.1) {
  //   state = { type: "walk", x: 0 };
  // }
  setTimeout(refresh, 500);
}
function standAnimation() {
  if (state.t === undefined) state.t = 0;
  if (state.t < 4) drawArt(20 + state.x, 30, standingCatToLeft, true);
  else drawArt(20 + state.x, 30, standingCatToLeftPose2, true);
  state.t++;
  if (state.t > 8) state.t -= 8;
  state.x += 1;
  setTimeout(refresh, 50);
}
function walkAnimation() {
  if (state.t === undefined) state.t = 0;
  if (state.dir === undefined) state.dir = "left";
  const flip = state.dir === "right";
  if (state.t < 4) drawArt(20 + state.x, 30, standingCatToLeft, flip);
  else drawArt(20 + state.x, 30, standingCatToLeftPose2, flip);
  state.t++;
  if (state.t > 8) state.t -= 8;
  state.x += state.dir === "left" ? -1 : 1;
  if (state.dir === "left" && state.x < -10) state.dir = "right";
  if (state.dir === "right" && state.x > 10) state.dir = "left";
  // if (state.x === 0) {
  //   if (Math.random() < 0.5) state = { type: "sleep" };
  // }
  setTimeout(refresh, 100);
}
refresh();
var elem;
function easeInOut(t) {
  const sqt = t ** 2;
  return sqt / (2.0 * (sqt - t) + 1.0);
}
var elem;
callbutton=document.getElementById("callbutton")
callbutton.addEventListener("click", function(){
  if (!elem) elem = document.querySelector("#main-tamago");
  if (state.type === "sleep") {
    state = { type: "walk", x: 0 };
    elem.style.fill = 'rgb(241, 195, 98)';
    }
  else {
    state = { type: "sleep" };
    elem.style.fill = 'rgb(98, 144, 241)';
}
});
</script>

为你的站点添加阅读更多按钮

文章太长的话,html爬虫软件会爬不到内容~博主也是才知道这个教训,由此我们通过生成目录、使用阅读全文按钮的方式,仅在博客首页展示大纲方便阅读,有效减少网页首页内容!

使用阅读更多(摘要)
官方推荐使用这种方式,可以让你在觉得适合的地方终止。

<!-- more-->

这样首页也十分简洁了。
效果

添加目录

安装插件

生成目录需要hexo-renderer-markdown-it-plus插件,因此我们需要卸载掉原本用于渲染的hexo-renderer-marked插件,并安装hexo-renderer-markdown-it-plus,它支持很多插件拓展并支持目录生成。

npm un hexo-renderer-marked --save
npm i hexo-renderer-markdown-it-plus --save

_config中填入配置:

markdown_it_plus:
    highlight: true
    html: true
    xhtmlOut: true
    breaks: true
    langPrefix:
    linkify: true
    typographer:
    quotes: “”‘’
    plugins:
        - plugin:
            name: markdown-it-mark
            enable: false

然后在你想要插入目录的地方使用@[TOC]即可!

你同样可以在vscode里安装markdown all in one插件生成,道理是一样的。

这个插件支持很多功能,包括emoji渲染和katex渲染等,都挺不错的!

katex渲染

启用katex渲染需要在next\_config.yml中设置:

math:
  # Default (false) will load mathjax / katex script on demand.
  # That is it only render those page which has `mathjax: true` in front-matter.
  # If you set it to true, it will load mathjax / katex script EVERY PAGE.
  every_page: false

  mathjax:
    enable: false
    # Available values: none | ams | all
    tags: none

  katex:
    enable: true
    # See: https://github.com/KaTeX/KaTeX/tree/master/contrib/copy-tex
    copy_tex: false

Math Equations

在md中使用emoji,你需要对应的表情列表:emoji表情列表

首页标题跳转

但是这样就会产生一个问题,如果我们在首页同时用显示摘要(或部分文字)和插入阅读更多按钮,而md文档自动帮我们生成的TOC目录只会产生一个#锚点,并不会跳转到博文相对应的链接,然后读者就和一动不动的网页干瞪眼啊😅😂官方的helper我个人感觉弄起来非常麻烦,而且我们的md文档转到另一个平台又要重新忧虑插入目录的问题了~

因此博主的思路是,在静态文件生成后修改首页(包括index.htmlpage文件夹下的所有页面),利用lxml库解析home页的对应markdownIt-TOC类下的所有a标签的herf链接,同时找到markdownIt-TOC父节点的兄弟节点(就是那个postheader aherf),连接到一起,然后重新匹配,替换掉该部分(因为直接写入解析替换后的html会乱码,不敢动),hexo d生成后,拉取静态文件到本地,再重新push上去,这里还可以再对逻辑修改下减少下载上传量。

# updateIndexLink.py

from lxml import etree
import re
import os

def update_links(html_file):
    with open(html_file, 'r', encoding='utf-8') as f:
        html_content = f.read()
    # 解析HTML文件
    parser = etree.HTMLParser(encoding="utf-8")
    htmlelement = etree.parse(html_file, parser=parser)

    # 博文体
    index_elements = htmlelement.findall('.//div[@class="post-block"]')

    for index_elem in index_elements:
        # 查找 .markdownIt-TOC a 元素
        toc_links = index_elem.findall(".//ul[@class='markdownIt-TOC']//a")
        if toc_links is not None:
            # 查找 .header a 元素
            header_link = index_elem.find(".//header//a")
            if header_link is not None:
                for toc_link in toc_links:
                    old_href = toc_link.get('href')
                    text = toc_link.text
                    # 更新 .markdownIt-TOC a 元素的 href 属性
                    new_href = header_link.get('href') + old_href
                    # print(new_href)
                    # print(old_href)
                    html_content = re.sub(fr'<a href="{old_href}">{text}</a>', f'<a href="{new_href}">{text}</a>',html_content)

    # 将修改后的HTML内容写回文件
    with open(html_file, 'w', encoding='utf-8') as f:
        f.write(html_content)
if __name__ == '__main__':
    subdirs = os.listdir(os.path.join(os.getcwd(), "public", "page"))
    for subdir in subdirs:
        file_path = os.path.join(os.getcwd(), "public", "page", subdir, "index.html")
        if os.path.exists(file_path):
            update_links(file_path)
    update_links("public/index.html")

upaload.bat

CALL hexo cl

CALL hexo d

CALL conda activate 你的环境,我用的conda所以有这一步

python updateIndexLink.py

cd.. 

rem 避免同时上传下载

timeout /t 5

rem 你的存储库克隆方式
git clone git@github.com:yourname/repo.git

xcopy path-to-your-blog\public\index.html  path-to-your-clone-repo\index.html /y

xcopy path-to-your-blog\public\page path-to-your-clone-repo\page /s /e /y

cd path-to-your-repo

git add .

git commit -m "uploadTOC"

git push

cd..

cd path-to-your-blog

rem 可以/q静默删除

rd /s path-to-your-clone-repo

直接在命令行运行这个bat就可以了。

>upload

首页链接

开启mermaid

根据官方说明,在_config.yml中加入:

highlight:
  ...
  exclude_languages:
    - mermaid

并在next\_config.yml设置mermaid.enable=true
效果

hexo-optimize插件优化页面加载速度

下载插件npm install hexo-optimize --save,并在_config.yml设置:

filter_optimize:
  enable: true
  # static resource versioning
  versioning: false
  css:
    # minify all css files
    minify: true
    excludes:
    # use preload to load css elements dynamically
    delivery:
      - '@fortawesome/fontawesome-free'
      - 'fonts.loli.net'
    # make specific css content inline into the html page
    inlines:
      # support full path only
      - css/main.css
  js:
    # minify all js files
    minify: true
    excludes:
    # remove the comments in each of the js files
    remove_comments: false
  html:
    # minify all html files
    minify: true
    excludes:
  # set the priority of this plugin,
  # lower means it will be executed first, default of Hexo is 10
  priority: 8

开发中的 NODE_ENV 可以禁用此插件以增强 hexo generate

export NODE_ENV=development

作者展示的案例说是增强了7%,我一会试试😄

目前就写这么多吧,好累好累🥹🥹🥹🥹各位大佬们走过路过点个赞、收藏下🥹🥹🥹🥹吧!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值