Part 1: Using Github Pages and Hexo to manage personal blogs on Ubuntu

Part 1: Using Github Pages and Hexo to manage personal blogs on Ubuntu.

Series

Hexo Tutorial

Github recommends us to use Jekyll to manage static pages, which is based on Ruby and is difficult for us to install and configure. So we use Hexo instead. Hexo is a static blog framework similar to Jekyll ,which is based on Node.js and easier for use to use.

use Github to create repo

  1. create a new repo in github, name by username.github.io: kezunlin.github.io

  2. Setting | Automatic Page Generator, choose a theame and deploy.

install by apt-get

sudo apt-get -y install nodejs
sudo apt-get -y install nodejs-legacy
sudo apt-get -y install npm
node -v 
npm -v 

install nodejs from source

# download and compile
wget https://nodejs.org/dist/v8.9.3/node-v8.9.3.tar.gz
tar xzvf node-v8.9.3.tar.gz
cd node-v8.9.3
./configure
make -j8
sudo make install

# link to /usr/bin
sudo ln -s /usr/local/bin/node /usr/bin/node
sudo ln -s /usr/local/bin/npm /usr/bin/npm

# check version
node -v 
npm -v 

test node

cat hello.js
console.log('Hello World');

node hello.js
Hello World

install hexo

# install hexo globally
sudo npm install hexo-cli -g
#sudo npm install hexo --save

# use cnpm from taobao instead of offical npm, which is slow for chinese users.
sudo npm install -g cnpm --registry=https://registry.npm.taobao.org

use cnpm instead of npm (optional)

# cnpm install 
sudo cnpm install hexo-cli -g

# check version
hexo -v

create hexo site

cd workspace
mkdir blog
cd blog

hexo init
#npm install
hexo generate
hexo server

now we can visit localhost:4000 and create posts.

deploy to github

vim blog/_config.yml

1
2
3
4
deploy:
type: git
repo: [email protected]:kezunlin/kezunlin.github.io.git
branch: master

generate ssh-key and copy to github

# generate ssh-key 
cd ~
ssh-keygen
cat .ssh/id_rsa.pub

# copy content to github
# https://github.com/settings/keys

# install plungin and deploy to github
npm install hexo-deployer-git --save
hexo deploy

now we can visit https://kezunlin.github.io/

add README and skip render

  1. add README.md to source folder
  2. edit blog/_config.yml to skip render README.md

    skip_render:
        - README.md
    

use hexo generate to copy README.md from source/ to public/

new post and deploy again

hexo new 'first post'
vim source/_posts/first-post.md

hexo generate
hexo server
hexo deploy

now we can visit https://kezunlin.github.io/ and see our first post.

Appendix

Hexo commands

Hexo common commands:

hexo new "postName"       #new post
hexo new page "pageName"  #new page
hexo generate             #generate static files to public/
hexo server               #start server on localhost:4000 
hexo deploy               #push .deploy_git/ to GitHub
hexo clean                #clean files

Hexo short commands:

hexo n == hexo new
hexo g == hexo generate
hexo s == hexo server
hexo d == hexo deploy

Hexo composite commands:

hexo server -g
hexo deploy -g

Post content

header template

---
title: Using Github Pages and Hexo to manage personal blogs
date: 2017-12-26 17:28:10
categories: tutorial
tags: 
    - github pages
    - hexo
    - nodejs
    - npm
---

more to control web display

<!--more-->
Use static blog framework Hexo to manage site
-----------------------------------------------

Use next theme

cd blog
git clone https://github.com/iissnan/hexo-theme-next themes/next

vim blog/_config.yml

1
2
#theme: landscape
theme: next

Avatar

edit blog\themes\next\_config.yml

1
avatar: /images/avatar.jpg

Plugins

install plugin by

npm install <plugin-name> --save

hexo admin

cnpm install --save hexo-admin

now we can visit http://localhost:4000/admin/

git deployer

npm install hexo-deployer-git --save
hexo deploy

rss feed

npm install hexo-generator-feed --save

# visit http://localhost:4000/atom.xml

sitemap

npm install hexo-generator-sitemap --save

vim blog/_config.yml

1
2
sitemap:
path: sitemap.xml

now we can visit http://localhost:4000/sitemap.xml

baidu sitemap

npm install hexo-generator-baidu-sitemap --save

vim blog/_config.yml

1
2
baidusitemap:
path: baidusitemap.xml

now we can visit http://localhost:4000/baidusitemap.xml

cnpm install hexo-abbrlink --save

edit blog\_config.yml

1
2
3
4
permalink: post/:abbrlink/
abbrlink:
alg: crc32 # crc16(default) and crc32
rep: hex # dec(default) and hex

will fill abbrlink in your post.md

1
2
3
4
5
6
7
8
9
---
title: Hello World
categories:
- tutorial
tags:
- hexo
abbrlink: 4a17b156
date: 2017-12-26 17:20:10
---

index/archive/category/tag

npm install hexo-generator-index --save
npm install hexo-generator-archive --save
npm install hexo-generator-category --save
npm install hexo-generator-tag --save

tags list page

hexo new page "tags"
# generate source/tags/index.md

edit source/tags/index.md

1
2
3
4
5
---
title: tags
date: 2017-12-27 15:46:09
type: "tags"
---

now we can visit http://localhost:4000/tags/

categories list page

hexo new page "categories"
# generate source/categories/index.md

edit source/categories/index.md

1
2
3
4
5
---
title: categories
date: 2017-12-27 15:46:03
type: "categories"
---

now we can visit http://localhost:4000/categories/

install search plugin

cnpm install hexo-generator-search --save
cnpm install hexo-generator-searchdb --save

edit themes\next\_config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    local_search:
enable: true # create a new 'Search' button next to 'Archives'
# 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

edit `_config.yml`

search:
path: search.xml
field: post
format: html
limit: 10000

install_hexo_plugins.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash

cnpm install hexo-deployer-git --save

cnpm install hexo-generator-feed --save

cnpm install hexo-generator-sitemap --save
cnpm install hexo-generator-baidu-sitemap --save

cnpm install hexo-generator-index --save
cnpm install hexo-generator-archive --save
cnpm install hexo-generator-category --save
cnpm install hexo-generator-tag --save

cnpm install hexo-generator-search --save
cnpm install hexo-generator-searchdb --save

Upload images to cnblog

  1. install img-uploader chrome extension by here
  2. upload image and get url.
  3. use url in markdown.
1
![image here](http://images2017.cnblogs.com/.../123.png)

Multiple deploy

  • deploy to github.com: username.github.io
  • deploy to coding.net (gitcaffe): username

vim blog/_config.yml

1
2
3
4
5
deploy:
type: git
repo:
github: [email protected]:<username>/<username>.github.io.git,master
coding: [email protected]:<username>/<username>.git,master

Advanced

custom domain and https

  • blog: Github pages
  • SSL:CloudFlare
  • domain: Godaddy (dns nameservers from CloudFlare)

get ips by

dig kezunlin.github.io +noall +answer

we get

185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
  • A: point to 185.199.109.153
  • CNAME: point to kezunlin.me

steps:

  1. get kezunlin.me from Godaddy.com
  2. add kezunlin.me to github blog’s blog\source\CNAME file
  3. register CloudFlare.com and add A record with github page IP 185.199.109.153 and get dns nameservers dina.ns.cloudflare.com and paul.ns.cloudflare.com
  4. add dns nameservers dina.ns.cloudflare.com and paul.ns.cloudflare.com from here

wait for some seconds and we get results from CloudFlare

kezunlin.me
Status: Active

This website is active on Cloudflare.

Universal SSL Status Active Certificate

Active means nameservers take effect.

configure

Crypto | Always use HTTPS
Page Rules| 2 rules for Always use HTTPS

google analytics

get google-site-verification from google search console and add to themes/next/layout/_partials/head.swig

<meta name="google-site-verification" content="***" />

get google_analytics and edit themes\next\_config.yml

1
google_analytics: UA-***

google adsense

copy ad script to themes/next/layout/_partials/head.swig

1
<script data-ad-client="ca-pub-5653382914441020" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>

copy ad scripts to themes/next/layout/_layout.swig inside body tag

1
2
3
4
5
6
7
8
9
10
11
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- kezunlin ad -->
<ins class="adsbygoogle"
style="display:block"
data-ad-client="ca-pub-5653382914441020"
data-ad-slot="7570408610"
data-ad-format="auto"
data-full-width-responsive="true"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

google structured-data

  1. grep search for keywords
1
2
grep -r Organization .
./themes/next/layout/_macro/post.swig: <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">

add logo for publisher

  1. edit themes\next\_config.yml and add

    logo: /images/logo.png

  2. edit ./themes/next/layout/_macro/post.swig

1
2
3
4
5
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="{{ config.title }}">
<img itemprop="logo" src="{{ url_for( theme.logo ) }}" />
#<img itemprop="logo" src="/images/logo.png" />
</span>

baidu zhanzhang

get baidu-site-verification from https://ziyuan.baidu.com/ and add to themes/next/layout/_partials/head.swig

<meta name="baidu-site-verification" content="***" />

360 zhanzhang

get 360-site-verification from http://zhanzhang.so.com/sitetool/ and add to themes/next/layout/_partials/head.swig

<meta name="360-site-verification" content="***" />

recommend posts

install plugin

npm install hexo-recommended-posts --save

edit blog\_config.yml

1
2
3
4
5
6
7
8
9
10
# 推荐文章
#recommended_posts:
# autoDisplay: false # 自动在文章底部显示推荐文章,如果你使用Material-X主题,这里要设置为false。
server: https://api.truelaurel.com # 后端推荐服务器地址
timeoutInMillis: 10000 # 服务时长,超过此时长,则使用离线推荐模式
excludePattern: []
titleHtml: <h1>Related Recommend Posts</h1> #自定义标题
internalLinks: 4 # 内部文章数量
externalLinks: 1 # 外部文章数量
fixedNumber: false

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

see here

stats

busuanzi

edit /theme/next/layout/_third-party/analytics/busuanzi-counter.swig

replace

1
<script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>

with

1
<script async src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

edit blog\themes\next\_config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
busuanzi_count:
# count values only if the other configs are false
enable: true
# custom uv span for the whole site
site_uv: true
site_uv_header: <i class="fa fa-user"></i>
site_uv_footer: Visitors
# custom pv span for the whole site
site_pv: true
site_pv_header: <i class="fa fa-eye"></i>
site_pv_footer: Total Visits
# custom pv span for one page only
page_pv: true
page_pv_header: <i class="fa fa-eye"></i>
page_pv_footer: Reads

gitment for comment

We can use github repo to store blog site’s comments in issues

register OAuth Application

  1. visit https://github.com/settings/applications/new
  2. fill in blanks, callback URL: https://kezunlin.me
  3. get client ID and client secret

go to https://github.com/settings/developers to check your OAuth Apps

gitment config

  1. create a new repo named gitment in Github for storing comments in issues
  2. edit blog\themes\next\_config.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
gitment:
enable: true
mint: true # RECOMMEND, A mint on Gitment, to support count, language and proxy_gateway
count: true # Show comments count in post meta area
lazy: true # Comments lazy loading with a button
cleanly: false # Hide 'Powered by ...' on footer, and more
language: zh-Hans # Force language, or auto switch by theme
github_user: kezunlin # MUST HAVE, Your Github ID
github_repo: gitment # MUST HAVE, The repo you use to store Gitment comments
client_id: <***> # MUST HAVE, Github client id for the Gitment
client_secret: <***> # EITHER this or proxy_gateway, Github access secret token for the Gitment
proxy_gateway: # Address of api proxy, See: https://github.com/aimingoo/intersect
redirect_protocol: # Protocol of redirect_uri with force_redirect_protocol when mint enabled

Notice

  • github_user: kezunlin
  • github_repo: gitment

init page comment

  1. hexo deploy to deploy blogs
  2. visit page and click button Initialize Comment
  3. post your first comment.

error fix: https://github.com/imsun/gitment/issues/188

gitalk for comment

see gitalk for hexo next

valine

skip now.

copy code

see hexo-copy

see hexo copy 2

Link Card

pin top post

cnpm install hexo-generator-index-pin-top --save 

and edit _posts/your-post.md

1
2
3
4
5
6
7
8
---
title: hexo blog
top: 1
tags:
- hexo
categories:
- blog
---

see here

get alexa rank

access http://data.alexa.com/data?cli=10&dat=snbamz&url=kezunlin.me

output

1
2
3
4
5
6
7
8
9
10
11
12
<!--
Need more Alexa data? Find our APIs here: https://aws.amazon.com/alexa/
-->
<ALEXA VER="0.9" URL="kezunlin.me/" HOME="0" AID="=" IDN="kezunlin.me/">
<RLS PREFIX="http://" more="0"> </RLS>
<SD TITLE="A" FLAGS="" HOST="kezunlin.me"> </SD>
<SD>
<POPULARITY URL="kezunlin.me/" TEXT="4070983" SOURCE="panel"/>
<REACH RANK="3600610"/>
<RANK DELTA="+1226051"/>
</SD>
</ALEXA>

kezunlin.me alexa rank is 4070983.

customize hexo

share

jiathis/baidushare

jiathis and baidushare do not support https

shareJS

see here

optimize for speed

multiple deploy

deploy to coding.net.

hexo-neat

cnpm install hexo-neat --save

edit blog\_config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# hexo-neat
neat_enable: true

neat_html:
enable: true
exclude:

neat_css:
enable: true
exclude:
- '*.min.css'

neat_js:
enable: true
mangle: true
output:
compress:
exclude:
- '*.min.js'

hexo-all-minifier (not)

npm install hexo-all-minifier --save

edit blog\_config.yml

1
all_minifier: true

Tips: not enable minifier currently because not stable.

hexo-filter-optimize

cnpm install hexo-filter-optimize

and edit blog\theme\next\_config.yml

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
filter_optimize:
enable: true
# remove static resource query string
# - like `?v=1.0.0`
remove_query_string: true
# remove the surrounding comments in each of the bundled files
remove_comments: false
css:
enable: true
# bundle loaded css file into the one
bundle: true
# use a script block to load css elements dynamically
delivery: true
# make specific css content inline into the html page
# - only support the full path
# - default is ['css/main.css']
inlines:
excludes:
js:
# bundle loaded js file into the one
bundle: true
excludes:
# set the priority of this plugin,
# lower means it will be executed first, default is 10
priority: 12

Lazy load

Lazy load offscreen images with lazysizes

cdn

NOTICE:

We can not use fourth level `####` for header,
otherwise post page will not display properly.

jquery

jquery: https://cdn.jsdelivr.net/jquery/2.1.3/jquery.min.js

faq

errors:

hexo -v
ERROR Local hexo not found in /home/kezunlin/git/blog

solution:

cd blog
rm node_modules
cnpm install --save

Seo

optimize speed

tools

very good ref here

image resource

experiements

  • Global Site Tag
  • Sitelinks Search Box
  • Google Tag Manager

Reference

History

  • 2017/12/26: created.
  • 2017/12/27: add Appendix,use next theame,add tags/categories page.
  • 2017/12/28: add Advanced, use gitment,baidushare,local search,etc.
  • 2018/01/02: upload images to cnblogs.
  • 2018/01/03: hexo-neat to compress,cdn,etc.
  • 2018/01/22: add part2.
  • 2018/09/05: add ssl.
  • 2019/11/07: reorganize post contents.

Copyright

坚持技术分享,您的支持将鼓励我继续创作!