【部落格開發】日誌 0x03

部落格要恢復更新啦

距離上次更新也過了一年多了,期間為了更加客製化主題,還想過要自己從頭刻部落格,真是太天真了啊
最後還是回來用新版的 icarus 主題,真香。
之前是把 icarus 主題跟部落格綁在同個 repo 一起更新,但這樣不好管理,所以現在就直接 fork 一份出來維護,是用最版的 5.0.0-rc.1,之後有新版本就再 merge 進來就好了。把之前做過得一些改動都整合進主題了,還是自己客製化過得最對味啊。
之後會慢慢把之前的文章再放回來,應該至少一週一更吧,希望xD

icarus 大改版

我之前用的 icarus 版本還在寫 .ejs
現在已經在寫 .jsx
之前的部落格開發日誌上的程式碼有些可能都不能直接套用了
不過不用擔心我現在已經把我改的程式碼推到 這裡

Excerpt

我發現 icarus 的 excerpt 可以寫在文章內容的開頭,而不用寫在 front matter
中間加一個 <!-- more --> 和文章主體區隔
像是下面這樣,或是看這裡範例

1
2
3
4
5
Hello, this is the excerpt

<!-- more -->

This is the article

這樣 excerpt 也可以快樂寫 markdown
在首頁也只會顯示到 <!-- more --> 之前的內容
但是點 Read More 的按鈕跳進去文章之後,會發現 excerpt 其實還在
只是頁面會捲動到 #more 這個 hashtag 也就是文章主體的開頭
不過這樣感覺只是一個偷懶的作法,不是一個完美的作法

Read more

【部落格開發】日誌 0x02

Admonition

我把 Material for MkDocs - Admonition Extension 搬過來啦,因為實在太好看,就搬過來用了,並且做了下面兩個小改動

  1. border-radius 拔掉了,還是方的好看
  2. 陰影改淡了,感覺比較對
example

這是範例

note

這是範例

abstract

這是範例

info

這是範例

tip

這是範例

success

這是範例

question

這是範例

warning

這是範例

failure

這是範例

danger

這是範例

quote

這是範例

實作

hexo-tag-admonition 借 code 過來改
基本上就是 register 一個新的 hexo tag,然後用到了 detailssummary 這兩個 html5 新的 tag
改的時候有幾個小地方要注意

  1. details tag 原本就有一個箭頭但是很醜,在 summary::-webkit-details-marker 設定 display:none 拔掉他
  2. icon 用到了 font-family: Material Icons,要在 head 裡面加個字體

Code block

另一個改動是程式碼區塊的部分,原來的有點小醜,就改了幾下

  1. 沒有給檔名就不要顯示上面的 header
  2. 可以指定起始行數,以及指定標記特定行數,如下範例
1
python run.py >3,6
run.py >3,6
1
2
3
4
5
6
import math

def main():
print(f'test {math.factorial(5)}')

main()
Read more

【部落格開發】日誌 0x01

部落格架好後,趁熱使用一下各種網站追蹤評測的工具,比如 Google Search Console, Google Analytics, PageSpeed Insights, Sitechecker, Hotjar

Hotjar

記錄使用者點擊的 heatmap

記錄使用者游標移動的路徑

還可以收集使用者的 feedback 回饋,不過載入時間有點久,部落格也不太需要這些資訊,所以就拔掉了,試用一下而已xD

SEO

Defer offscreen images

參考 Lazy load offscreen images with lazysizes,只要載入 lazysizes 這個 scripts 進來,然後把 src 改成 data-src 並加上 class="lazyload" 就好了

註冊個 hexo 的 after_render,把所有 img tag 抓出來改就完事了

scripts/lazy-load-image.js
1
2
3
hexo.extend.filter.register('after_render:html', function (htmlContent) {
return htmlContent.replace(/<img src="([^"]*)" (?:class="([^"]*)")?([^>]*)>/, '<img data-src="$1" class="$2 lazyload" $3>')
});

lazysizes 有 cdn,很方便的

layout/common/scripts.ejs
1
<script src="https://cdnjs.cloudflare.com/ajax/libs/lazysizes/5.2.0/lazysizes.min.js" defer></script>

Sitemap

1
npm install hexo-generator-sitemap

裝好 hexo-generator-sitemap 之後,在 _config.yml 加一行收工

1
2
sitemap:
path: sitemap.xml

Robots.txt

直接放在 source/_posts 下面就行了,簡單搞定

Read more

【部落格開發】日誌 0x00

之前的部落格是用 mkdocs,但是 mkdocs 其實是用來生成 document 的,不是拿來生成部落格的,所以文章都沒有日期,也沒有近期文章或是標籤的功能,我之所以選 mkdocs 是因為 mkdocs-material 實在太好看了很對我胃口,不過最近興起了想幫部落格換個皮的念頭,主要是看上了 icarusmaterial-x 這兩個主題,都是 hexo 的主題,最後選了 icarus,然後再自己手動調整,下面會說明一下我手動調整的內容

排版

這個主題整體來說很好看的,但是我不喜歡他的排版,文章只能擠在中間細細長長的,左右兩邊還留了很多空隙,不知道是作者的螢幕太小還是我螢幕太大,所以我把所有 widget 都移到左邊,然後把欄位的比例改成 3:9,css 的部份在 source/css/style.styl:21 把寬度調寬

layout/layout.ejs
1
2
case 2:
return 'is-9-tablet is-9-desktop is-9-widescreen';
layout/common/widget.ejs
1
2
case 2:
return 'is-3-tablet is-3-desktop is-3-widescreen';
source/css/style.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
gap = 40px
...
@media screen and (min-width: screen-widescreen)
.is-1-column .container
.is-2-column .container
max-width: screen-widescreen - 2 * gap
width: screen-widescreen - 2 * gap
@media screen and (min-width: screen-fullhd)
.is-2-column .container
max-width: screen-fullhd - 2 * gap
width: screen-fullhd - 2 * gap
.is-1-column .container
max-width: screen-fullhd - 2 * gap
width: screen-fullhd - 2 * gap

Read More

原本 icarus 只有 excerpt 這個選項可以加在文章的 front-matter 中,如下

1
2
3
4
---
title: "部落格開發日誌"
excerpt: 寫一些摘要在這邊
---

但是要每一篇都要自己寫摘要好麻煩,我比較想要的是只顯示固定長度,然後邊邊模糊處理,所以就自己手刻了一個

layout/common/article.ejs
1
2
3
4
5
6
7
8
<div class="card <%= index && (!post.hasOwnProperty('readmore') || post.readmore) ? 'card-readmore' : '' %>">
...
<% if (index && (!post.hasOwnProperty('readmore') || post.readmore)) { %>
<div class="level is-mobile readmore-button">
...
</div>
<% } %>
...
source/css/style.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
25
26
27
28
.card-readmore
max-height: 400px
overflow: hidden
position: relative
.readmore-button
position absolute
left: 0
bottom: 20px
width: 100%
display: flex
justify-content center
z-index: 20
&:after
content: ''
position: absolute
bottom: 60px
width: 100%
height: 100px
z-index: 10
background-image: linear-gradient(to bottom, hsla(0, 100%, 100%, 0), hsla(0, 100%, 100%, 0.9))
&:before
content: ''
position: absolute
bottom: 0
width: 100%
height: 60px
z-index: 10
background-image: linear-gradient(to bottom, hsla(0, 100%, 100%, 0.9), hsla(0, 100%, 100%, 1))

Adblock

我本身有在用 AdBlock,然後在用 icarus 主題的時候發現有些物件會憑空消失,比如 back-to-top 那個按了可以回到頁面頂端的小按鈕,後來發現是被 AdBlock 砍了,因為那個小按鈕有 .back-to-top 這個 class,不只 .back-to-top 還有很多關鍵字會被砍,可以看這份 Class and ID to avoid because of AdBlock,那我的解決辦法就是把原始碼裡所有的 back-to-top 改名成 bottom-to-top

就在剛剛,我寫完第一段之後,發現上面的 h2 標題 Adblock 因為 markdown 生成 html 時自動加了 id=Adblock,然後就被 AdBlock 砍了,只好改成自己手刻 html

1
<h2>Adblock</h2>

另一個被砍掉的是 font-awesome 的 icon .fa-instagram,這個就不好改名了,所以我加了一小行 javascript 把 .fa-ig 改成 .fa-instagram,以結果來看我的 script 跑的順序應該是比 AdBlock 來得後面所以沒有被砍

source/js/main.js
1
2
3
4
$(document).ready(function() {
$('.fa-ig').addClass('fa-instagram');
$('.fa-ig').removeClass('fa-ig');
});

Github

mkdocs-material 主題的右上角有顯示 github star 的功能,我覺得很酷,所以就搬過來了

layout/common/navbar.ejs
1
2
3
4
5
6
<a class="navbar-item github-source" href="<%= github.url %>">
<div class="github-source-icon"><i class="fab fa-lg fa-github-alt"></i></div>
<div class="github-source-repository">
<%= github.name %>
</div>
</a>
source/css/style.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
25
26
.github-source
.github-source-icon
padding: 5px
.github-source-repository
padding-left: 10px
font-size: 10px
font-weight: 1000
ul
animation: animateElement linear .3s;
animation-iteration-count: 1;
li
float: left
font-weight: 200
#github-forks
margin-left: 3px

@keyframes animateElement{
0% {
opacity:0;
transform: translate(0px,10px);
}
100% {
opacity:1;
transform: translate(0px,0px);
}
}
source/js/main.js
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
if (typeof (IcarusThemeSettings) !== 'undefined' &&
typeof (IcarusThemeSettings.github.url) !== 'undefined') {
const url = IcarusThemeSettings.github.url
console.log(url)
const matches = /^.+github\.com\/([^/]+)\/?([^/]+)?.*$/.exec(url)
console.log(matches)
if (matches && matches.length === 3) {
const [, user, name] = matches
console.log(user, name)
const api = `https://api.github.com/users/${user}/repos`
const paginate = (page = 0) => (
fetch(`${api}?per_page=100&sort=updated&page=${page}`)
.then(response => response.json())
.then(data => {
if (!(data instanceof Array))
return []

/* Display number of stars and forks, if repository is given */
if (name) {
const repo = data.find(item => item.name === name)
if (!repo && data.length === 30) return paginate(page + 1)

if (typeof repo.stargazers_count !== 'number' || typeof repo.forks_count !== 'number') return []
/* If we found a repo, extract the facts */
return repo
? [
`${repo.stargazers_count} Stars`,
`${repo.forks_count} Forks`
]
: []

/* Display number of repositories, otherwise */
} else {
return [
`${data.length} Repositories`
]
}
})
)
paginate().then(data => {
console.log(data)
const [stars, forks] = data
const facts = $(`<ul class="github-facts"><li id="github-stars">${stars}</li><li id="github-forks">• ${forks}</li></ul>`)
$('.github-source-repository').append(facts)
})
}
}

舊部落格

舊的部落格我還在慢慢搬移當中,所以我把 mkdocs 生成的 html 放進來 hexo 當 static files,只要放在 source/old/ 底下然後在 _config.yml 裡面加一行 skip_render: old/**,hexo 就不會去 render 他了

疑難雜症

在改主題原始碼的過程中,遇到各種奇怪問題時,記得先 hexo clean 一下

Read more