本篇文章是在已经搭建好gitpage+hexo的博客的前提下(不懂怎么搭建的能够参考个人另外一篇博文:了解githubPages+hexo搭建博客的原理 或者利用Gitpage+hexo开发本身的博客,这两篇博文都比较详细的教你们最基础的怎么将博客搭建起来。本篇博文是使用next主题的进击版本,主要是有如下内容javascript
要想最快的知道这些功能的效果,请移步个人我的博客:www.cherryblog.site/ ,顺便求个fork,大爷们看过能够评论一下,试一下新加上的网易云跟帖效果怎么样ヽ(●´ε`●)ノ
首先要说一下我使用的版本,这个是很重要的,个人博客最早建立于2016年的9月份,距离如今已经有大半年了,因此好多版本都已经进行了更新,特别是next主题集成了更多的插件,简直不要太爽\(@ ̄∇ ̄@)/css
hexo v3.2.2
next v5.1.0
node v4.5.0html
在改为本身想要的效果以后,对总体的hexo的next主题我有了一个大概的了解,其实next主题的最新版(5.1)已经集成了大部分咱们须要的插件,只须要在主题配置文件中将默认的false改成true便可,可是咱们也仍然须要知道都有哪些新的功能,最有效的方法是直接去查看官网的api:next官网java
授之于鱼不如授之于渔
但愿咱们都可以理解其源码,制做出属于本身专属的个性化博客(•̀ᴗ•́)node
咱们须要改的文件其实也就那么几个,大部分是不须要更改,next都已经帮咱们配置好了~
默认目录结构:git
.
├── .deploy
├── public
├── scaffolds
├── scripts
├── source
| ├── _drafts
| └── _posts
├── themes
├── _config.yml
└── package.json复制代码
咱们最早修改的应该是在hexo根目录下的配置文件_config.yml
文件,这里是配置整个站点的配置信息,在文章的最后贴出个人配置文件,有兴趣的朋友能够参考一下~
其次就是咱们的主题配置文件
在对应的主题下的_config.yml
由于我使用的是next主题,因此目录的路径为C:\Hexo\themes\next\_config.yml
这里配置的是使用主题的配置文件,这个配置文件的东西就有点多了,咱们大部分的修改也是在这个文件下完成的。好比说使用集成的第三方插件,默认为false,咱们须要将其改成true而且配置相应的app_key就可使用该插件了~有木有很方便(^ ◕ᴥ◕ ^)
而后咱们须要修改样式的话是须要设置css和甚至是修改模板,
页面展示的所有逻辑都在每一个主题中控制,源代码在hexo\themes\你使用的主题\中,以next主题为例:es6
├── .github #git信息
├── languages #多语言
| ├── default.yml #默认语言
| └── zh-Hans.yml #简体中文
| └── zh-tw.yml #繁体中文
├── layout #布局,根目录下的*.ejs文件是对主页,分页,存档等的控制
| ├── _custom #能够本身修改的模板,覆盖原有模板
| | ├── _header.swig #头部样式
| | ├── _sidebar.swig #侧边栏样式
| ├── _macro #能够本身修改的模板,覆盖原有模板
| | ├── post.swig #文章模板
| | ├── reward.swig #打赏模板
| | ├── sidebar.swig #侧边栏模板
| ├── _partial #局部的布局
| | ├── head #头部模板
| | ├── search #搜索模板
| | ├── share #分享模板
| ├── _script #局部的布局
| ├── _third-party #第三方模板
| ├── _layout.swig #主页面模板
| ├── index.swig #主页面模板
| ├── page #页面模板
| └── tag.swig #tag模板
├── scripts #script源码
| ├── tags #tags的script源码
| ├── marge.js #页面模板
├── source #源码
| ├── css #css源码
| | ├── _common #*.styl基础css
| | ├── _custom #*.styl局部css
| | └── _mixins #mixins的css
| ├── fonts #字体
| ├── images #图片
| ├── uploads #添加的文件
| └── js #javascript源代码
├── _config.yml #主题配置文件
└── README.md #用GitHub的都知道复制代码
绑定域名的思路以下:github
以前没有买域名的时候我想使用网易云跟帖,发如今注册网易云跟帖的时候使用原来的域名提示“url已被使用”,这是由于网易云跟帖不承认二级域名,因此要本身买域名。
我选择的是万网,阿里下面的。我选择了一个.site
的域名,原价8元,使用阿里云app支付还优惠5元,等于3元到手一个域名(一年)~
按照官网的步骤一步一来就能够了~web
购买完域名以后咱们须要解析DNS地址,在管理控制台中的左侧有域名选项,而后找到你的域名,点击后面的“解析”
express
点击添加解析,记录类型选A或CNAME,
A记录的记录值就是ip地址,github(官方文档)提供了两个IP地址,192.30.252.153和192.30.252.154,这两个IP地址为github的服务器地址,两个都要填上,
解析记录设置两个www和@,线路就默认就好了,CNAME记录值填你的github博客网址。如个人是sunshine940326.github.io。
接下来在你的hexo文件夹下source文件夹下新建一个CANME文件,里面加上你刚刚购买的域名好比个人cherryblog.site
若是直接填写
cherryblog.site
的话直接访问www.cherryblog.site 和 cherryblog.site 均可以访问到咱们的网站,可是若是填写www.cherryblog.site 的话只能经过www.cherryblog.site 访问,不能经过cherryblog.site 访问
hexo clean
,
hexo g
,
hexo d
发布你的博客看看效果啦~
添加菜单页的思路(添加菜单页就是添加一个页面,有两种方式):第一种是使用git命令hexo new page "photo"
就直接建立了C:\Hexo\source\photo\index.md
文件,而后编辑index.md 文件就能够了~
刚开始的时候不理解怎么添加分类页和添加文章的区别,公司有一个项目用到了wordpress,而后发现二者有类似的地方,不一样的就是wordpress是有可视化的操做后台,而hexo是须要git bash本身建立
首先咱们要分清什么是页面,什么是文章,
在hexo中menu下的内容都是新的页面咱们能够经过hexo new page "pagename"
建立,hexo默认的页面只有home
,archives
,tags
三个,以后咱们写的博文就是文章,经过hexo new "name"
建立的name.md
文件在根目录的source\_posts
下,在每个文章的头部,咱们能够配置其tags或者categories内容,至关于文章是页面的下一级
咱们能够在主题配置的_config文件下找到相应的字段,字段前加#
表示被注释掉,咱们也能够本身添加menu的内容,好比我又新增了两个menulife
和photo
这里添加的字段实际上是加上文件索引的路径,这里hexo设置的根路径是
hexo/source
接下来咱们在这个根路径下创建相应的文件夹就能够实现点击mune跳转到相应的页面上了
咱们须要在这个路径下本身创建对应的页面,好比说我新建了menulife
和photos
,而后再source文件夹下面新建两个名字为life
和photo
的文件夹,里面添加一个index.md
markdown文件,内容是相似这样的
---
title: photo
date: 2017-04-04 22:14:07
type: "photo"
comments: false
---
啦啦啦~复制代码
若是只是上面的步骤,那么你可能会建立出一个新的页面,可是显示的效果会是这样:
怎么icon没有换???其实hexo中换icon是一个很简单的事情,由于hexo集成了FontAwsome
因此咱们只须要在主题的配置文件中加入相应的icon名字便可
FontAwsome
icon 这时候你想要换一个本身喜欢的icon怎么办,这就须要本身动手,丰衣足食了,你须要本身到FontAwsome官网,而后鼠标往下拉,在图标集中选择本身喜欢的icon,而后记住名字,保存在上面的menu_icon字段中就能够啦~
上面的步骤完成以后你会发现,在你的博客首页显示的仍然是英文名,而咱们想要有一个中文的名字,而且想要个性化定制咱们的页面,咱们能够在主题的language文件下的zh-hans(中文)语言包下增长相应的字段(作过翻译的童鞋应该都知道什么意思~)还能够修改其余的字段,这样就能够定制咱们的博客了呢~
在咱们写文章的时候只要在头部信息添加相应的字段就在tags页面和categories中显示相应的分类,例如:
---
title: Git使用中的报错状况
date: 2017-03-11 23:54:11
tags: [git,实战经验]
categories: git
---复制代码
tags、categories都是支持数组的形式的,能够添加多个tags、categories。这样咱们在tags、categories页面就能够看见相应的分类了
我使用的主题头像是位于侧边栏,显示的效果以下,
# Sidebar Avatar
# in theme directory(source/images): /images/avatar.jpg
# in site directory(source/uploads): /uploads/avatar.jpg
avatar: /uploads/avatar.png复制代码
跟设置头像实际上是一个思路,都是在配置文件中引入正确的地址就能够了,不过网站的logo是对图片有要求的,咱们须要在Favicon在线制做工具中制做32*32的.ico图片,而后放在source/images下面。而后在主题配置文件下添加主题配置文件中添加:favicon: images/favicon.ico
不得不说next仍是很人性化的,你能够个性化定制你的网站,你全部的改动(css)须要放在主题文件的source/css/_costum/costum.styl文件中,会覆盖原来的css,因此只要你不想要你修改的样式,只须要删除这个文件夹就能够了,不再用担忧还原不回去了~
2017.5.8更新,具体过程往下看仿知乎动态背景
以前作过一个相似的canvas-nest的效果。新版本的next已经支持canvas-nest了,可是效果不怎么样,就不用了,可是也介绍一下,毕竟简单,只有两步就能够了。
添加修改代码next\layout\_layout.swig
在</body>
以前加上
{% if theme.canvas_nest %}
<script type="text/javascript" src="//cdn.bootcss.com/canvas-nest.js/1.0.0/canvas-nest.min.js"></script>
{% endif %}复制代码
打开next\_config.yml
,添加如下代码就能够了:
# Canvas-nest
canvas_nest: true复制代码
这种虽然简单,可是我认为效果不够好,因而我决定添加原生的js来仿知乎的登陆界面作背景,这就须要修改模板来实现了。只要咱们知道了next文件的结构,咱们想改什么只须要找到对应的位置就好(在前言中有next的目录结构)~
_layout.swig
添加一个canvas
<div class="bg_content">
<canvas id="canvas"></canvas>
</div>复制代码
而后使用原生js写一个仿知乎页面
<script>
class Circle {
//建立对象
//以一个圆为对象
//设置随机的 x,y坐标,r半径,_mx,_my移动的距离
//this.r是建立圆的半径,参数越大半径越大
//this._mx,this._my是移动的距离,参数越大移动
constructor(x, y) {
this.x = x;
this.y = y;
this.r = Math.random() * 10 ;
this._mx = Math.random() ;
this._my = Math.random() ;
}
//canvas 画圆和画直线
//画圆就是正常的用canvas画一个圆
//画直线是两个圆连线,为了不直线过多,给圆圈距离设置了一个值,距离很远的圆圈,就不作连线处理
drawCircle(ctx) {
ctx.beginPath();
//arc() 方法使用一个中心点和半径,为一个画布的当前子路径添加一条弧。
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();
//开始一条路径,移动到位置 this.x,this.y。建立到达位置 _circle.x,_circle.y 的一条线:
ctx.moveTo(this.x, this.y); //起始点
ctx.lineTo(_circle.x, _circle.y); //终点
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();
}
}
//更新页面用requestAnimationFrame替代setTimeout
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>复制代码
2017.5.8更新,不少朋友都私信我说这个动态背景没有效果,发现上面的js代码是es6写的,兼容性很差,而且中间也漏了一步添加css样式的,致使好多显示的不彻底,特此更新
完整步骤以下
1:首先在主题文件的layout中的_layout.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); return Constructor; }; }();
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: function drawCircle(ctx) {
ctx.beginPath();
//arc() 方法使用一个中心点和半径,为一个画布的当前子路径添加一条弧。
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); //起始点
ctx.lineTo(_circle.x, _circle.y); //终点
ctx.closePath();
ctx.strokeStyle = 'rgba(204, 204, 204, 0.3)';
ctx.stroke();
}
}
}, {
key: 'move',
value: function 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;
}
}]);
return Circle;
}();
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;
};复制代码
2:在主题文件的C:\Hexo\themes\next\source\css\_custom\custom.styl
文件中加上css代码
/*设置背景*/
.bg_content{
position: fixed;
top: 0;
z-index: -1;
width: 100%;
height: 100%;
}
#canvas{
width: 100%;
height:100%;
}
/*将头部背景变为透明*/
.header{
background: transparent ;
}复制代码
在知道了页面的结构以后,你就能够将你的播放器添加在页面的任意位置,开始我是放在了首页,而后发现一上来就自动播放太吵了,因而就放在了侧边栏,想要听得朋友能够手动点击播放,
咱们能够直接在网易云音乐中搜索咱们想要插入的音乐,而后点击生成外链播放器
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>复制代码
而后就能够在侧边栏看见个人播放器了~
以前用的是多说,可是多说在2017年6月1日就关闭评论服务了= =,很忧伤,因而转到了网易云跟帖。因为最新版(5.1)版本的next已经集成了网易云跟帖,因此只须要在主题的设置文件中配置你的productKey就能够了。获取productKey也很简单,在官网网易云跟帖中注册,而后在获取代码>通用代码中拿到productKey,以后在你的主题配置文件中的gentie_productKey字段后添加便可~
#添加Fork me on GitHub
去网址github.com/blog/273-gi… 挑选本身喜欢的样式,并复制代码,添加到themes\next\layout_layout.swig的body标签以内便可
记得把里面的url换成本身的!
npm install hexo-wordcount --save
就能够安装wordcount插件,
# Post wordcount display settings
# Dependencies: https://github.com/willin/hexo-wordcount
post_wordcount:
item_text: true
wordcount: true
min2read: true复制代码
next也集成了leancloud,在leancloud官网
中注册帐号等一步一步的操做就不说了哈~,咱们主要是为了拿到app_key和app_id,而后在主题配置文件作一下配置
# 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_key复制代码
而后再leancloud的控制台中的存储添加一个counter的class就能够检测到咱们的浏览量了,同时在你文章的副标题也能够看到有阅读次数的显示
# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/
# Site 站点信息
title: Cherry's Blog #站点名字 subtitle: To Be a Batter Me #副标题 description: 作更好的本身 #站点描述,在侧边栏显示 author: Cherry #博主名字 email: 991939332@qq.com #联系邮箱 language: zh-Hans #使用的语言包,语言包在主题文件的language文件夹下,能够更改网站显示出的文案 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 #新建一个页面后自动生成一个同名文件夹(默认为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://git@github.com/sunshine940326/sunshine940326.github.io复制代码