preface

This post is based on the premise that gitPage + Hexo has been built. Learn about githubPages+ Hexo to build a blog or use Gitpage+hexo to develop your own blog. These two posts are more detailed to teach you the basics of how to build a blog. This post is an advanced version of the next theme, with the following content

  • Domain binding: Bind github blog to your own domain name
  • Add more menu content
  • Add a picture
  • Define your website’s personality logo
  • Customize styles, override default styles, and personalize your blog
  • Cool dynamic background making
  • Add NetEase Cloud Music
  • Add NetEase Cloud comment
  • Add the count of leanCloud read counts function
  • Add wordcount to the wordcount page
  • Add the fork Me on Github feature

For the quickest way to see how these features work, check out my personal blog: www.cherryblog.site/, by the way, ask a fork, ye have seen can comment, try the new addition of NetEase cloud follow-up effect, how angry (●´ε ‘●) Blue first to talk about the version I use, this is very important, my blog was first created in September 2016, Distance from now has been more than half a year, so many versions have been updated, especially the next theme integrated with more plug-ins, it is not too cool \ (@ ~ ∇ @) /

Hexo v3.2.2 next V5.1.0 node v4.5.0

After changing it to the desired effect, I got a general idea of the overall Hexo Next theme. In fact, the latest version of the Next theme (5.1) already integrates most of the plug-ins we need. Just change the default false to true in the theme configuration file. But we still need to know what new features are available, and the best way to do that is to go directly to the API on the website: next website

Hexo website

I hope we will all understand the source code and create our own ̀ᴗ•́ blog

There are only a few files we need to change, most of which do not need to be changed. Next has already configured the ~ default directory structure for us:

. ├ ─ ─. Deploy ├ ─ ─ public ├ ─ ─ scaffolds ├ ─ ─ scripts ├ ─ ─source| ├ ─ ─ _drafts | └ ─ ─ _posts ├ ─ ─ themes ├ ─ ─ _config. Yml └ ─ ─ package. The jsonCopy the code
  • Deploy: Run the hexo deploy command to deploy to the content directory on GitHub
  • Public: Static directory of web content generated by executing hexo generate
  • Scaffolds: Layout template files directory to which MD files can be added with edits
  • Scripts: Extended script directory where you can customize some javascript scripts
  • Source: The article source directory, where markdown and HTML files are processed by Hexo. This page should face the root directory of the repo, 404 files, favicon.ico files, CNAME files, etc. This is where you can create a new page directory.
    • Drafts: Draft articles
    • Posts
  • Themes: the theme file directory
  • _config.yml: Global configuration file, where most Settings are found
  • Package. json: Application data indicating the version of the hexo, similar to buttons in general software

The first thing we should change is the configuration file _config.yml in the root directory of hexo. Here is the configuration information for the entire site. Yml :\Hexo\themes\next\_config.yml :\Hexo\themes\next\_config.yml :\Hexo\themes\next\_config. This configuration file is a bit more verbose, and it’s where most of our changes are made. The default is false, we need to change it to true and configure the corresponding app_key to use the plugin. Is this convenient? (^ ◕ᴥ◕ ^) Then we need to change the style, we need to set the CSS and even change the template. All the logic displayed on the page is controlled in each theme. The source code is in the hexo themes you use. Take the next theme as an example:

├ ─ ─. Dead simple# git information├ ─ ─ languages# multiple languages| ├ ─ ─ default. Yml# default language| └ ─ ─ useful - Hans. Yml# Simplified Chinese| └ ─ ─ useful - tw. Yml# Traditional Chinese├ ─ ─ layoutEjs files in the root directory are controls for home pages, pagination, archiving, etc| ├ ─ ─ _custom# You can modify the template, overwrite the original template| | ├ ─ ─ _header. Swig# header style| | ├ ─ ─ _sidebar. Swig# Sidebar style| ├ ─ ─ _macro# You can modify the template, overwrite the original template| | ├ ─ ─ post. Swig# article template| | ├ ─ ─ reward. Swig# Tip template| | ├ ─ ─ sidebar. Swig# Sidebar template| ├ ─ ─ _partial# Local layout| | ├ ─ ─ the head# header template| | ├ ─ ─ the search# Search template| | ├ ─ ─ share# Share template| ├ ─ ─ _script# Local layout| ├ ─ ─ _third - party# Third-party templates| ├ ─ ─ _layout. Swig# Home page template| ├ ─ ─ index. Swig# Home page template| ├ ─ ─ page# page template| └ ─ ─ tag. Swig# tag template├ ─ ─ scripts# script source| ├ ─ ─ tags#tags script source| ├ ─ ─ marge. Js# page template├ ─ ─source             # source| ├ ─ ─ the CSS# CSS source| | ├ ─ ─ _common# *. Styl basic CSS| | ├ ─ ─ _custom# *. Styl local CSS| | └ ─ ─ _mixins# mixins CSS| ├ ─ ─ fonts# font| ├ ─ ─ images# image| ├ ─ ─ uploads# Add file| └ ─ ─ js# javascript source code├ ─ ─ _config. Yml# Theme profile└ ─ ─ the README. Md# GitHub knowsCopy the code

Binding domain

The roadmap for binding domain names is as follows:

  • Buy your favorite domain name in wanwang (.com will be a little more expensive,.site and.xyz are relatively cheap, some only need a few dollars a year can)
  • Resolve the DNS
  • Add the CNAME file to hexo

Buy a domain name

When I didn’t buy a domain name before, I wanted to use NetEase Cloud comment, but I found that I used the original domain name to indicate “URL has been used” when I registered NetEase Cloud comment, because NetEase Cloud comment does not recognize secondary domain names, so I had to buy a domain name by myself. I choose is ten thousand net, ali below. I chose a. Site domain name, the original price of 8 yuan, using aliyun APP to pay 5 yuan discount, equal to 3 yuan to get a domain name (one year) ~ according to the official website step by step can be ~

Resolve the DNS

After purchasing the domain name, we need to resolve the DNS address. In the administrative console, there is the domain name option on the left. Then find your domain name and click “Resolve”.

Resolve the DNS

Click Add resolution, record type A or CNAME,

Github (official document) provides two IP addresses, 192.30.252.153 and 192.30.252.154. These two IP addresses are github server addresses. Both IP addresses must be filled in. CNAME records the value of your Github blog url. For example, mine is Sunshine940326. github. IO.

Add the CNAME file to hexo

Next, create a new CANME file in your hexo folder, under your source folder, and add the domain name you just purchased, such as my cherryblog.site

If you go to cherryblog.site you can go to www.cherryblog.site and cherryblog.site and you can go to our website, However, if you enter www.cherryblog.site, you can only use www.cherryblog.site, not cherryblog.site

Added CNAME resolution to hexo



hexo clean
hexo g
hexo d


Analyze and complete the effect drawing

Add menu page

Add menu page (add menu page is to add a page, there are two ways) : Git hexo new page “photo” to create a C: hexo source photo index.md file and then edit the index.md file

New articles


  • Add the menu index path to the theme’s configuration file (the root path is hexo\source, so if you want to change the contents of the page, go to hexo\source and find the corresponding folder. The default is under its index.md file)
  • Add the corresponding folder under hexo’s Source file
  • Add the icon corresponding to the menu_icon field Settings in the theme’s configuration file
  • Modify the zh-Hans language package in the language file
  • You can see it by adding the corresponding menu field when you publish the article

At the beginning, I didn’t understand the difference between adding classified pages and adding articles. The company used wordpress in a project, and then found that there were similarities between the two. The difference is that wordpress has a visual operation background, while Hexo needs git bash to create its own. What is an article? In Hexo, the content under Menu is a new page. We can create it by hexo new Page “Pagename”, hexo has only three default pages, home, Archives and Tags. The name.md file created by hexo new “name” is in the root directory under source\_posts. In the header of each article, we can configure tags or categories, which are the next level of the page

Add the menu index path to the configuration file

We can find the corresponding field in the _config file of the topic configuration, and add # before the field to indicate that it is commented out. We can also add the content of menu by ourselves, for example, I added two more MenuLife and photo

Add the menu index path to the configuration file

The field added here is actually the path to the file index, so the root path set by hexo is hexo/source, and then we can create the corresponding folder under this root path and click Mune to jump to the corresponding page

Create the corresponding folder under the path

Add the Menu folder to the source file

We need to create our own pages in this path. Let’s say I create menuLife and Photos, and then create two new folders under the source folder named Life and Photo, and add an index.md markdown file that looks something like this

---
title: photo
date: 2017-04-04 22:14:07
type: "photo"
comments: false-- La la laCopy the code

Added successful renderings



2017.5.8 update, use HTML file directly just add layout:false at the top of the file

Add icon to menu

If it were just the above steps, you might create a new page, but it would look something like this:

No icon is added to the field

Why icon is not changed?? It is easy to change the icon in Hexo, because Hexo integrates FontAwsome, so we just need to add the icon name in the theme configuration file

Add icon position and icon

To find theFontAwsome icon

If you want to change your favorite icon, go to FontAwsome’s official website, then click down, select your favorite icon from the icon set, remember the name, and save it in the menu_icon field

FontAwsome official website icon

Add zh-Hans translation fields in language

After completing the above steps, you will find that your blog will still display an English name on the front page, but we want to have a Chinese name and we want to customize our page. We can add fields to the zh-Hans (Chinese) language package in the theme’s language file and modify other fields to customize our blog

Add zh-Hans translation fields in language

Add the corresponding menu field at post time

When we wrote the article, we simply added the corresponding fields in the header information to display the corresponding categories in the tags page and Categories, for example:

Categories: Git -- Categories: Git --Copy the code

Tags and Categories are supported in the form of arrays. You can add multiple tags and categories. This allows us to see the categories in the Tags and Categories page

Added successful renderings

Add a picture

The theme avatar I used is in the sidebar and it looks like this,

Sidebar head rendering

# Sidebar Avatar
# in theme directory(source/images): /images/avatar.jpg
# in site directory(source/uploads): /uploads/avatar.jpg
avatar: /uploads/avatar.pngCopy the code

Add sidebar avatar

Setting the Website Logo

It’s the same idea as setting your profile picture, it’s all about introducing the correct address in the profile file, but the logo of the site is required for the image, we need to create a 32*32. Ico image in the Favicon online authoring tool and place it under source/images. Then under the theme profile add: favicon: images/favicon.ico in the theme profile

Custom styles

I have to say that next is very personal, you can customize your site, all your changes (CSS) need to be in the theme file source/ CSS /_costum/costum.styl, will overwrite the original CSS, so as long as you don’t want your changes, Just delete this folder and you don’t have to worry about restoring it

Customize the CSS file location

Cool dynamic background

2017.5.8 Update, the specific process to look at the imitation zhihu dynamic background

I did a similar canvas nest effect before. The new version of next already supports Canvas-Nest, but the effect is not very good, so I will not use it, but also introduce, after all, simple, only two steps can be done. Add modification code next\layout\_layout. Swig before

{% if theme.canvas_nest %}
<script type="text/javascript" src="/ / cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
{% endif %}Copy the code

Open next\_config.yml and add the following code:

 # Canvas-nest
canvas_nest: trueCopy the code

This is simple, but I think the effect is not good enough, so I decided to add native JS to imitate the login interface of Zhihu as the background, which needs to modify the template to achieve. Once we know the structure of the next file, we just need to find the corresponding location to change it

Write the picture description here



_layout.swig

<div class="bg_content">
    <canvas id="canvas"></canvas>
</div>Copy the code

Then use native JS to write a fake Zhihu page

<script> class Circle {// Create an object // Take a Circle as an object // set random x, y coordinates, r radius, _mx, _my distance to move //this.r is the radius to create the Circle, Constructor (x, y) {this.x = x; // This. this.y = y; this.r = Math.random() * 10 ; this._mx = Math.random() ; this._my = Math.random() ; } // Drawing a circle on canvas is normal to draw a circle on canvas. // Drawing a line is a line between two circles. In order to avoid too many lines, a value is set for the distance of the circle. DrawCircle (CTX) {ctx.beginPath(); The arc() method uses a center point and radius to add an arc to the current subpath of a canvas. ctx.arc(this.x, this.y, this.r, 0, 360) ctx.closePath(); ctx.fillStyle ='rgba (204, 204, 204, 0.3)';
        ctx.fill();
    }

    drawLine(ctx, _circle) {
        let dx = this.x - _circle.x;
        let dy = this.y - _circle.y;
        let d = Math.sqrt(dx * dx + dy * dy)
        if(d < 150) { ctx.beginPath(); // Start a path and move to positions this.x,this.y. Create a line that reaches positions _circine. x, _circine. y: ctx.moveto (this.x, this.y); // start ctx.lineto (_circle.x, _circle.y); / / the end CTX. ClosePath (); ctx.strokeStyle ='rgba (204, 204, 204, 0.3)'; ctx.stroke(); Move (w, h) {this._mx = (this.x < w && this.x > 0)? this._mx : (-this._mx); this._my = (this.y < h && this.y > 0) ? this._my : (-this._my); this.x += this._mx / 2; this.y += this._my / 2; Class currentCirle extends Circle {constructor(x, y) {super(x, y)} drawCircle(CTX) {ctx.beginPath();  // This.r = (this.r < 14 && this.r > 1)? this.r + (Math.random() * 2 - 1) : 2; this.r = 8; ctx.arc(this.x, this.y, this.r, 0, 360); ctx.closePath(); //ctx.fillStyle ='rgba(0,0,0,' + (parseInt(Math.random() * 100) / 100) + ') '
        ctx.fillStyle = 'rgba (255, 77, 54, 0.3)'ctx.fill(); }} // Update the page with requestAnimationFrame insteadsetTimeout
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let w = canvas.width = canvas.offsetWidth;
let h = canvas.height = canvas.offsetHeight;
let circles = [];
let current_circle = new currentCirle(0, 0)

let draw = function () {
    ctx.clearRect(0, 0, w, h);
    for (let i = 0; i < circles.length; i++) {
        circles[i].move(w, h);
        circles[i].drawCircle(ctx);
        for (j = i + 1; j < circles.length; j++) {
            circles[i].drawLine(ctx, circles[j])
        }
    }
    if (current_circle.x) {
        current_circle.drawCircle(ctx);
        for (var k = 1; k < circles.length; k++) {
            current_circle.drawLine(ctx, circles[k])
        }
    }
    requestAnimationFrame(draw)
}

let init = function (num) {
    for (var i = 0; i < num; i++) {
        circles.push(new Circle(Math.random() * w, Math.random() * h));
    }
    draw();
}
window.addEventListener('load', init(60));
window.onmousemove = function (e) {
    e = e || window.event;
    current_circle.x = e.clientX;
    current_circle.y = e.clientY;
}
window.onmouseout = function () {
    current_circle.x = null;
    current_circle.y = null;

};
</script>Copy the code

Imitated Zhihu dynamic background


I found that the JS code above was written by ES6, which was not compatible well. In addition, one step of adding CSS style was missed in the middle, which led to many incomplete displays. Therefore, I hereby update the complete steps as follows

SwigC :\Hexo\themes\next\layout\_layout. Swig

  <div class="bg_content">
       <canvas id="canvas"></canvas>
  </div>
 'use strict';

    var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); }}return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); returnConstructor; }; } ();function _possibleConstructorReturn(self, call) { if(! self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function")? call : self; }function _inherits(subClass, superClass) { if(typeof superClass ! = ="function"&& superClass ! == null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true}});if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

    function _classCallCheck(instance, Constructor) { if(! (instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

    var Circle = function () {
       function Circle(x, y) {
            _classCallCheck(this, Circle);

            this.x = x;
            this.y = y;
            this.r = Math.random() * 10;
            this._mx = Math.random();
            this._my = Math.random();
        }

       _createClass(Circle, [{
            key: 'drawCircle',
            value: functiondrawCircle(ctx) { ctx.beginPath(); The arc() method uses a center point and radius to add an arc to the current subpath of a canvas. ctx.arc(this.x, this.y, this.r, 0, 360); ctx.closePath(); ctx.fillStyle ='rgba (204, 204, 204, 0.3)';
                ctx.fill();
            }
        }, {
            key: 'drawLine',
            value: function drawLine(ctx, _circle) {
                var dx = this.x - _circle.x;
                var dy = this.y - _circle.y;
                var d = Math.sqrt(dx * dx + dy * dy);
                if(d < 150) { ctx.beginPath(); ctx.moveTo(this.x, this.y); // start ctx.lineto (_circle.x, _circle.y); / / the end CTX. ClosePath (); ctx.strokeStyle ='rgba (204, 204, 204, 0.3)';
                    ctx.stroke();
                }
            }


        }, {
            key: 'move',
            value: functionmove(w, h) { this._mx = this.x < w && this.x > 0 ? this._mx : -this._mx; this._my = this.y < h && this.y > 0 ? this._my : -this._my; this.x += this._mx / 2; this.y += this._my / 2; }}]);returnCircle; } (); var currentCirle =function (_Circle) {
        _inherits(currentCirle, _Circle);

        function currentCirle(x, y) {
            _classCallCheck(this, currentCirle);

            return _possibleConstructorReturn(this, (currentCirle.__proto__ || Object.getPrototypeOf(currentCirle)).call(this, x, y));
        }

        _createClass(currentCirle, [{
            key: 'drawCircle',
            value: function drawCircle(ctx) {
                ctx.beginPath();

                //this.r = (this.r < 14 && this.r > 1) ? this.r + (Math.random() * 2 - 1) : 2;
                this.r = 8;
                ctx.arc(this.x, this.y, this.r, 0, 360);
                ctx.closePath();
                //ctx.fillStyle = 'rgba(0,0,0,' + (parseInt(Math.random() * 100) / 100) + ') '
                ctx.fillStyle = 'rgba (255, 77, 54, 0.6)'; ctx.fill(); }}]);return currentCirle;
    }(Circle);


    window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;

    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    var w = canvas.width = canvas.offsetWidth;
    var h = canvas.height = canvas.offsetHeight;
    var circles = [];
    var current_circle = new currentCirle(0, 0);

    var draw = function draw() {
        ctx.clearRect(0, 0, w, h);
        for (var i = 0; i < circles.length; i++) {
            circles[i].move(w, h);
            circles[i].drawCircle(ctx);
            for(j = i + 1; j < circles.length; j++) { circles[i].drawLine(ctx, circles[j]); }}if (current_circle.x) {
            current_circle.drawCircle(ctx);
            for (var k = 1; k < circles.length; k++) {
                current_circle.drawLine(ctx, circles[k]);
            }
        }
        requestAnimationFrame(draw);
    };

    var init = function init(num) {
        for (var i = 0; i < num; i++) {
            circles.push(new Circle(Math.random() * w, Math.random() * h));
        }
        draw();
    };
    window.addEventListener('load', init(60));
    window.onmousemove = function (e) {
        e = e || window.event;
        current_circle.x = e.clientX;
        current_circle.y = e.clientY;
    };
    window.onmouseout = function () {
        current_circle.x = null;
        current_circle.y = null;
    };Copy the code

2: Add CSS code to the C: Hexo\themes\next\source\ CSS \_custom\custom.styl file of the theme file

/* Set the background */. Bg_content {position: fixed; top: 0; z-index: -1; width: 100%; height: 100%; }#canvas{width: 100%; height:100%; } /* Make the header background transparent */. Header {background: transparent; }Copy the code

Add NetEase Cloud Music

After know the structure of the page, you can add your players in any position of the page, I was on the front page, and then find a come up automatically play is too noisy, and then put the sidebar, want to listen to friends can manually click the play, we can directly in netease cloud music search we want to insert in the music, Then click generate external chain player

NetEase Cloud Music page





Add external chain page



layout\_macro\sidebar.swig

<div id="music163player">
    <iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=280 height=86 src="//music.163.com/outchain/player?type=2&id=38358214&auto=0&height=66">
    </iframe>
</div>Copy the code

Then you can see my player in the sidebar

Added NetEase cloud music renderings

NetEase cloud comment

Duoshuo was used before, but duoshuo closed its comment service on June 1, 2017. It was very sad, so it moved to NetEase Cloud to comment. Since the latest (5.1) release of next already integrates NetEase Cloud posts, you only need to configure your productKey in the theme Settings file. It is also easy to obtain productKey. You can register productKey in the comment thread of NetEase cloud on the official website, and then go to “Get Code > Generic code” to get productKey. Then add the productKey field in your theme profile

# Fork me on GitHub Select your favorite style, copy the code and add it to the body TAB of themes\next\layout_layout.swig to change the URL to your own.

Hexo-wordcount implements statistics

Write the picture description here






npm install hexo-wordcount --save














# Post wordcount display settings
# Dependencies: https://github.com/willin/hexo-wordcount
post_wordcount:
  item_text: true
  wordcount: true
  min2read: trueCopy the code

Leancloud read count

Next is also integrated with leanCloud. We need to register an account in leanCloud’s official website step by step. We need to get the app_key and app_id, and then do the configuration in the theme configuration file

# Show number of visitors to each article.
# You can visit https://leancloud.cn get AppID and AppKey.
leancloud_visitors:
  enable: true
  app_id: yourapp_id
  app_key: yourapp_keyCopy the code

Then add a counter class to the storage in the console of leanCloud to detect our page views. At the same time, you can also see the number of views displayed in the subtitle of your article

Write the picture description here

Personal Website Address:Cherryblog. Site /, by the way, fork

Appendix 1: Site configuration files

 # Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/

# Site Site information
title: Cherry* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * The language package is in the language folder of the theme file. You can change the text displayed on the website. Timezone: # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' url: http://yoursite.com root: / permalink: :year/:month/:day/:title/ permalink_defaults: # Directory source_dir: source public_dir: public tag_dir: tags archive_dir: archives category_dir: categories code_dir: downloads/code i18n_dir: :lang skip_render: # Writing new_post_name: :title.md # File name of new posts default_layout: post titlecase: false # Transform title into titlecase external_link: true # Open external links in new tab filename_case: 0 render_drafts: false post_asset_folder: True # Automatically generates a folder with the same name (default false) relative_link: false Future: true highlight: enable: true line_number: true auto_detect: false tab_replace: # Category & Tag default_category: uncategorized category_map: tag_map: # Date / Time format ## Hexo uses Moment.js to parse and display date ## You can customize the date format as defined in  ## http://momentjs.com/docs/#/displaying/format/ date_format: YYYY-MM-DD time_format: HH:mm:ss # Pagination ## Set per_page to 0 to disable pagination per_page: 10 pagination_dir: page # Extensions ## Plugins: https://hexo.io/plugins/ ## Themes: https://hexo.io/themes/ theme: next # Deployment ## Docs: https://hexo.io/docs/deployment.html deploy: type: git repository: https://github.com/sunshine940326/sunshine940326.github.io.git #repository: ssh://[email protected]/sunshine940326/sunshine940326.github.ioCopy the code