Hexo Configuration

Image

When post_asset_folder is true, each post created by bash will also create a folder with the same name. Then, we can put all the picture that will be used in the post in this folder and use relative path (just the picture's full name) to refer to it.

1
post_asset_folder: true

However, because of the update of hexo, some bugs in the original plugin used to show images on website, like hexo-simple-image or hexo-asset-image, occur, which lead the path of images to be wrongly interpreted. For example:

  • When using hexo-simple-image, the root path will be incorrectly interpreted as /.io/ (this depends on the url you set);

1

  • When using hexo-asset-image, we can not show the picture on website either.

To solve this problem, firstly, we need to uninstall hexo-simple-image.

1
npm uninstall hexo-simple-image --save

Secondly, we need to install hexo-asset-image.

1
npm install hexo-asset-image --save

Thirdly, we should change the content of /node_modules/hexo-asset-image/index.js to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'use strict';
var cheerio = require('cheerio');

// http://stackoverflow.com/questions/14480345/how-to-get-the-nth-occurrence-in-a-string
function getPosition(str, m, i) {
return str.split(m, i).join(m).length;
}

var version = String(hexo.version).split('.');
hexo.extend.filter.register('after_post_render', function(data){
var config = hexo.config;
if(config.post_asset_folder){
var link = data.permalink;
if(version.length > 0 && Number(version[0]) == 3)
var beginPos = getPosition(link, '/', 1) + 1;
else
var beginPos = getPosition(link, '/', 3) + 1;
// In hexo 3.1.1, the permalink of "about" page is like ".../about/index.html".
var endPos = link.lastIndexOf('/') + 1;
link = link.substring(beginPos, endPos);

var toprocess = ['excerpt', 'more', 'content'];
for(var i = 0; i < toprocess.length; i++){
var key = toprocess[i];

var $ = cheerio.load(data[key], {
ignoreWhitespace: false,
xmlMode: false,
lowerCaseTags: false,
decodeEntities: false
});

$('img').each(function(){
if ($(this).attr('src')){
// For windows style path, we replace '\' to '/'.
var src = $(this).attr('src').replace('\\', '/');
if(!/http[s]*.*|\/\/.*/.test(src) &&
!/^\s*\//.test(src)) {
// For "about" page, the first part of "src" can't be removed.
// In addition, to support multi-level local directory.
var linkArray = link.split('/').filter(function(elem){
return elem != '';
});
var srcArray = src.split('/').filter(function(elem){
return elem != '' && elem != '.';
});
if(srcArray.length > 1)
srcArray.shift();
src = srcArray.join('/');
$(this).attr('src', config.root + link + src);
console.info&&console.info("update link as:-->"+config.root + link + src);
}
}else{
console.info&&console.info("no src attr, skipped...");
console.info&&console.info($(this));
}
});
data[key] = $.html();
}
}
});

At last, add some configuration behind post_asset_folder which is true in /_config.yml.

1
2
3
marked:
prependRoot: true
postAsset: true

This will make hexo automatically extend the path of image to its absolute path.

Math formula

There are some bugs in plugin hexo-renderer-marked which lead the math formula to be wrongly interpreted.

The solution is to revise /node_modules/marked/lib/marked.cjs.

  • Change all the lines starting with escape: to:

    1
    escape: /^\\([`*\[\]()#$+\-.!_>])/,
  • Change all the lines starting with em: to:

    1
    em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,

Then, enable mathjax in /themes/next/_config.yml, that is, set enable in math to true.

At last, add mathjax: true in /scaffolds/post.md (the posts created before need you to add this manually).

However, there are still some bugs on the website.

  1. The plugin may take \\ as \, \; as ;. To solve this, we just need to add one \ before \;
  2. Two {{}} need a space to distinguish. (I do not know what this means...)

Tag cloud

2

tag cloud

Some problems:

  1. When using NexT, we should insert the code before back2top.sidebar;
  2. It is advisable to just download the package and put it in /node_modules. Then add "hexo-tag-cloud": "^2.1.*" to package.json.

Colorful tag

3

Create tag-color.swig in /themes/next/layout.

Add code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<script type="text/javascript">
var alltags = document.getElementsByClassName('tag-cloud-tags');
var tags = alltags[0].getElementsByTagName('a');
for (var i = tags.length - 1; i >= 0; i--) {
var r=Math.floor(Math.random()*75+130);
var g=Math.floor(Math.random()*75+100);
var b=Math.floor(Math.random()*75+80);
tags[i].style.background = "rgb("+r+","+g+","+b+")";
}
</script>

<style>
.tag-cloud-tags{
/*font-family: Helvetica, Tahoma, Arial;*/
font-family: Arial;
font-weight: 200;
text-align: center;
counter-reset: tags;
}
.tag-cloud-tags a{
box-shadow: 0 1px 3px #6f42c1, 0 1px 2px #d9534f;
padding: 2px 10px;
margin: 8px;
border-bottom: none;
border-radius: 20px;
}
.tag-cloud-tags a:before{
// content: "?"; When enable this,there will be 'content' before each tag
}

.tag-cloud-tags a:hover{
box-shadow: 0px 5px 15px 0px rgba(0,0,0,.4);
transform: scale(1.1);
/*box-shadow: 10px 10px 15px 2px rgba(0,0,0,.12), 0 0 6px 0 rgba(104, 104, 105, 0.1);*/
transition-duration: 0.15s;
}
</style>

Call this script: add {% include 'tag-color.swig' %} to the bottom of {%- if page.type === 'tags' %} in /themes/next/layout/page.swig, or, just add the script code (if add code, we do not need the tag-color.swig file).

This is actually a script code, so we can change the configuration by ourselves.

Colorful bottom tag

4

Add script code

1
2
3
4
5
6
7
8
9
10
11
12
<script type="text/javascript">
var tagsall=document.getElementsByClassName("post-tags")
for (var i = tagsall.length - 1; i >= 0; i--){
var tags=tagsall[i].getElementsByTagName("a");
for (var j = tags.length - 1; j >= 0; j--) {
var r=Math.floor(Math.random()*75+130);
var g=Math.floor(Math.random()*75+100);
var b=Math.floor(Math.random()*75+80);
tags[j].style.background = "rgb("+r+","+g+","+b+")";
}
}
</script>

to the bottom of <div class="post-tags"> in /themes/next/layout/post.swig or /themes/next/layout/_macro/post.swig.

Then we get colorful bottom tags.

Add

1
2
3
4
5
6
7
8
.posts-expand .post-tags a{
display: inline-block;
font-size: 0.8em;
padding: 0px 10px;
border-radius: 8px;
color: #fff;
border: 0px;
}

in /source/_data/styles.styl (if you do not have this file, just create one and enable style: source/_data/styles.styl in /themes/next/_config.yml).

Then we get bottom tags with border so that we can add color.

Read more and description

  1. Enable read_more_btn and excerpt_description in /themes/next/_config.yml;

  2. Add description: in /scaffolds/post.md;

  3. Add your excerpt behind description and <!-- more --> behind the metadata.

Blog background

Add

1
2
3
4
5
6
7
8
body { 
background-image: url(/images/bg.png); // the path of image in your blog
background-repeat: no-repeat;
background-attachment: fixed; // does not scroll with the page
background-position: 50% 50%; // center
background-size: 100% 100%;
color: #000; // color of body font
}

in styles.styl (if you do not have this file, just create one and enable style: source/_data/styles.styl in /themes/next/_config.yml).

Transparency of blog

Add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// transparency of the content of your post
.content-wrap {
opacity: 0.95;
}

// transparency of search
//.popup {
// opacity: 0.8;
//}

// submenu,post,comments,pagination
.main-inner > .sub-menu, .main-inner > .post-block, .main-inner > .tabs-comment,
.main-inner > .comments, .main-inner > .pagination {
background: rgba(255,255,255,0.85);
}

// side bar
.sidebar {
opacity: 0.85
}

// color and transparency of background of menu
.header-inner {
background: rgba(255,255,255,0.85);
}

// color of title (the default color is grey)
.posts-expand .post-title-link {
color: #000;
}

// color of data under title
.posts-expand .post-meta-container {
color: #000;
}

in styles.styl (if you do not have this file, just create one and enable style: source/_data/styles.styl in /themes/next/_config.yml).

Catalog

All the configurations of catalog are in toc: of /themes/next/_config.yml.

1
2
3
4
5
6
7
8
9
10
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: true
# 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

If we want to display the catalog selectively, we just need to edit /themes/next/layout/_macro/sidebar.swig:

change :

1
{%- set display_toc = page.toc.enable and display_toc %}

to:

1
{%- set display_toc = page.toc.enable and page.etoc and display_toc %}

Then, if we want to display calalog, we just need to add etoc: true in the metadata of the post (false if we do not want). It is recommended to add etoc: true in /scaffolds/post.md.

Rounded corners

5

Enable variable: source/_data/variables.styl in /themes/next/_config.yml. Create /source/_data/variables.styl and add code:

1
2
$border-radius-inner     = 20px 20px 20px 20px;
$border-radius = 20px;

However, there are still some bugs on the sidebar:

6

This is caused by the default body background which covers the rounded corners. To solve this, we just need to set $body-bg-color in /themes/next/source/css/_variables/Gemini.styl to transparent:

1
2
3
4
5
6
7
8
9
// Variables of Gemini scheme
// ==================================================

@import "Pisces.styl";

// Settings for some of the most global styles.
// --------------------------------------------------
// $body-bg-color = #eee;
$body-bg-color = transparent;

Background of menu

Configure /themes/next/source/css/_schemes/Pisces/_header.styl, add your favorite bg in background.

1
2
3
4
5
6
7
8
9
10
11
.site-brand-container {
// background: $black-deep;
background: url(/uploads/bluemoon.png)
// background: url(/uploads/space.png)
// background: url(/uploads/walkonmoon.png)
+tablet-mobile() {
box-shadow: 0 0 16px rgba(0, 0, 0, .5);
}
background-size: cover; // it is advisable to enable this
//background-size: 50% 100%;
}

If you do not like your logo on the menu, you can just disable it in your theme configuration file:

1
custom_logo: false

Top offset of post

7

Configure index.styl in the specific scheme folder you choose in /themes/next/source/css/_schemes:

1
2
3
4
5
6
.content-wrap {
background: initial;
box-shadow: initial;
padding: initial;
padding-top: 45px; // top offset of your post
}

Fork me on github

A github icon in the upper right corner:

8

  1. Find the icon you like on GitHub Corners or GitHub Ribbons;
  2. Copy the code to /themes/next/layout/_layout.swig and put it behind <div class="headband"></div>;
  3. Change the value of href to your gihub homepage, like:
1
<a href="https://github.com/zclzcl0223" class="github-corner" aria-label="View source on GitHub"><svg width="80" height="80" viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true"><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>

Dynamic background

9

Enable footer: source/_data/footer.swig in your theme configuration file. Create footer.swig under _data and add code:

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

You can modify color, opacity, zIndex and count as you like.

Picture viewer

There are two types of picture viewers in /themes/next/_config_yml, fancybox and mediumzoom. Choose the one you like and enable it.

For mediumzoom, I don't like its overlay. I wanna make it slightly more transparent. Therefore, I download its package from:

1
https://www.jsdelivr.com/package/npm/medium-zoom. 

Extract /package/dist/medium-zoom.js and modify all

1
2
3
.medium-zoom-overlay {
opacity: 0 /* 0 means opaque; 1 means completely transparent*/
}

Actually, just modify the last one is ok. Then push this file to one of your github repo and migrate its url from github to jsDelivr on https://www.jsdelivr.com/github, for example:

1
2
3
4
# github
https://github.com/zclzcl0223/my_medium-zoom/blob/master/medium-zoom-v7.js
# jsDelivr
https://cdn.jsdelivr.net/gh/zclzcl0223/my_medium-zoom@master/medium-zoom-v7.js

Set your jsDelivr url as your vendor of mediumzoom in /themes/next/_config.yml mediumzoom:. The effect is as follows (opacity: 0.5):

10

Related posts

Add related posts at the bottom of each post based on tag relevance and creation time. First, download dependencies:

1
npm install hexo-related-popular-posts --save

Just ignoring the warnings is ok. Then, set related_posts to true in /themes/next/_config.yml. The effect is as follows:

11

Running time of site

Add:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- <br /> -->
<!-- 网站运行时间的设置 -->
<span id="timeDate">载入天数...</span>
<!-- <span id="times">载入时分秒...</span> -->
<script>
  var now = new Date();
  function createtime() {
      var grt= new Date("11/17/2022 8:00:00");//此处修改你的建站时间或者网站上线时间
      now.setTime(now.getTime()+250);
      days = (now - grt ) / 1000 / 60 / 60 / 24; dnum = Math.floor(days);
      hours = (now - grt ) / 1000 / 60 / 60 - (24 * dnum); hnum = Math.floor(hours);
      if(String(hnum).length ==1 ){hnum = "0" + hnum;} minutes = (now - grt ) / 1000 /60 - (24 * 60 * dnum) - (60 * hnum);
      mnum = Math.floor(minutes); if(String(mnum).length ==1 ){mnum = "0" + mnum;}
      seconds = (now - grt ) / 1000 - (24 * 60 * 60 * dnum) - (60 * 60 * hnum) - (60 * mnum);
      snum = Math.round(seconds);
      if(String(snum).length ==1 ){snum = "0" + snum;}
      // var times = document.getElementById("times").innerHTML = hnum + " 小时 " + mnum + " 分 " + snum + " 秒";
      document.getElementById("timeDate").innerHTML = "本站已安全运行 "+dnum+" 天 "+hnum + " 小时 " + mnum + " 分 " + snum + " 秒";
  }
setInterval("createtime()",250);
</script>

to /themes/next/layout/_partials/footer.swig.

Icon on footer

12

Modify the following code in /themes/next/_config.yml:

1
2
3
4
5
6
7
8
footer:
icon:
# name: fa fa-heart
name: fas fa-star-of-david
# If you want to animate the icon, set it to true.
animated: false
# Change the color of icon, using Hex Code.
color: "#B0E0E6"

Search for your favorite icon in https://fontawesome.com/v5/search and modify name: xx (remember to use v5.15.4).

Font size, line & paragraph spacing

All these configurations are in /themes/next/source/css/_variables/base.styl:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Font size
$font-size-base = (hexo-config('font.enable') and hexo-config('font.global.size') is a 'unit') ? unit(hexo-config('font.global.size'), em) : 1em;
$font-size-smallest = .75em;
$font-size-smaller = .8125em;
$font-size-small = .875em;
$font-size-medium = 1em;
$font-size-large = 1.125em;
$font-size-larger = 1.25em;
$font-size-largest = 1.5em;


// Headings font size
$font-size-headings-step = .15em; // discounts for all levels
$font-size-headings-base = (hexo-config('font.enable') and hexo-config('font.headings.size') is a 'unit') ? unit(hexo-config('font.headings.size'), em) : 1.75em;


// Global line height
$line-height-base = 1.5; // line spacing
$line-height-code-block = 1.5; // Can't be less than 1.3;

// paragrah spacing
.post-block p {
margin-bottom: 5px;
}

Local search

Install:

1
npm install hexo-generator-searchdb --save

In /themes/next/_config.yml enable local_search.

Reference