Hexo Icarus 修改歷程

Blog 客製化

更改背景色

更改$body-background-color

~\themes\icarus\include\style\base.styl
1
$body-background-color ?= $blue

參數路徑:

~\node_modules\bulma-stylus\stylus\utilities\initial-variables.styl
1
2
3
4
5
6
$orange ?=       hsl(16,  100%, 50%)
$yellow ?= hsl(48, 100%, 67%)
$green ?= hsl(141, 53%, 53%)
$turquoise ?= hsl(171, 100%, 41%)
$cyan ?= hsl(204, 71%, 53%)
$blue ?= hsl(219, 97%, 14%)

將links mark 起來

~\_config.icarus.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
navbar:
# Navigation menu items
menu:
Home: /
Archives: /archives
Categories: /categories
Tags: /tags
About: /about
# Links to be shown on the right of the navigation bar
# links:
# Download on GitHub:
# icon: fab fa-github
# url: 'https://github.com/ppoffice/hexo-theme-icarus'

修改Footer背景顏色

~\themes\icarus\include\style\base.styl
1
$footer-background-color ?= #E9F4FA
~\_config.icarus.yml
1
2
3
4
5
6
7
8
9
10
footer:
# Links to be shown on the right of the footer section
links:
CC BY-NC-SA 4.0:
icon:
- fab fa-creative-commons
- fab fa-creative-commons-by
- fab fa-creative-commons-nc
- fab fa-creative-commons-sa
url: 'https://creativecommons.org/licenses/by-nc-sa/4.0/'

更改上一篇/下一篇文字顏色

如果使用深色背景時,預設文字顏色會看不清楚。

更改post-navigation-fg

~\themes\icarus\include\style\pagination.styl
1
$post-navigation-fg ?= #EEEEEE

增加Disqus評論

先到Disqus註冊帳號,相關方式請搜尋Disqus註冊。

~\_config.icarus.yml
1
2
3
4
5
6
7
comment:
# Name of the comment plugin
type: disqus
enable: true
shortname: 'your_disqus_short_name'
count: true
lazyload: false

繼續閱讀按鈕放置右方

在首頁檢視時,讓Tag也在文章下顯示,並將繼續閱讀按鈕放置右方。

~\themes\icarus\layout\common\article.jsx
1
2
3
4
5
6
7
8
9
10
11
<hr style="height:1px;margin:1rem 0"/>
<div className="level is-mobile is-flex">
{/* Tags */}
{page.tags && page.tags.length ? <div class="article-tags is-size-7 is-uppercase">
<i class="fas fa-tags has-text-grey"></i>&nbsp;
{page.tags.map((tag, index) => {
return <a class="link-muted" rel="tag" href={url_for(tag.path)}>{tag.name}{index !== page.tags.length-1? ', ':''}</a>;
})} </div> : null}
{/* "Read more" button */}
{index && page.excerpt ? <a class="article-more button is-small is-size-7" href={`${url_for(page.link || page.path)}#more`}><i class="fas fa-book-reader has-text-grey"></i>&nbsp;&nbsp;{__('article.more')}</a> : null}
/div>

更改繼續閱讀文字顏色

更改繼續閱讀icon顏色,將has-text-grey改為has-text-info

~\themes\icarus\layout\common\article.jsx
1
2
{/* "Read more" button */}
{index && page.excerpt ? <a class="article-more button is-small is-size-7" href={`${url_for(page.link || page.path)}#more`}><i class="fas fa-book-reader has-text-info"></i>&nbsp;&nbsp;{__('article.more')}</a> : null}

更改繼續閱讀文字顏色,在article.styl中的article-more增加color屬性。

~\themes\icarus\include\style\article.styl
1
2
3
4
&.article
.article-more
@extend .button.is-light
color: hsl(204, 86%, 53%)

Card Widget

Card Widget增加浮動陰影

在card.styl增加hover變化

~\themes\icarus\include\style\card.styl
1
2
3
4
5
.card
overflow: visible
border-radius: $card-radius
&:hover
box-shadow: 0 6px 15px rgba(255,168,63,0.5), 0 0 1px rgba(255,168,63,0.25)

增加box-shadow動畫效果

~\themes\icarus\source\js\animation.js
1
2
3
4
5
setTimeout(() => {
$('body > .navbar, body > .section, body > .footer').forEach(element => {
element.style.opacity = '1';
element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out, box-shadow 0.3s ease-in-out';
});
~\themes\icarus\source\js\animation.js
1
2
3
4
5
6
7
8
$(selector).forEach(element => {
setTimeout(() => {
element.style.opacity = '1';
element.style.transform = '';
element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out, box-shadow 0.3s ease-in-out';
}, i * 100);
i++;
});

目錄黏貼

原本只支援整欄黏貼,修改成可讓目錄單獨隨文章Scroll時,上下移動。

增加toc.addClass(‘column-left is-sticky’);

~\themes\icarus\source\js\main.js
1
2
3
4
const $toc = $('#toc');
if ($toc.length > 0) {
$toc.addClass('column-left is-sticky');
const $mask = $('<div>');

增加 #toc

~\themes\icarus\include\style\widget.styl
1
2
3
4
5
6
7
widget
.menu-list


#toc
max-height: calc(100vh - 22px)
overflow-y: scroll

將最新文章, Tag等設定在右邊

~\_config.icarus.yml
1
2
3
4
# Recent posts widget configurations (最新文章)
-
position: right
type: recent_posts

取消 SUBSCRIBE FOR UPDATES

~\_config.icarus.yml
1
2
3
4
5
6
7
8
# Google FeedBurner email subscription widget configurations
# Where should the widget be placed, left sidebar or right sidebar
# position: left
# type: subscribe_email
# Hint text under the email input
# description:
# Feedburner ID
# feedburner_id: ''

取消 FOLLOW.IT

~\_config.icarus.yml
1
2
3
4
5
6
7
8
9
10
# Follow.it email subscription widget configurations
# Where should the widget be placed, left sidebar or right sidebar
# position: left
# type: followit
# Hint text under the email input
# description:
# Subscription form action URL
# action_url: ''
# Feed claiming verification code
# verification_code: ''

取消 Google AdSense

~\_config.icarus.yml
1
2
3
4
5
6
7
8
# Google AdSense unit configurations
# Where should the widget be placed, left sidebar or right sidebar
# position: left
# type: adsense
# AdSense client ID
# client_id: ''
# AdSense AD unit ID
# slot_id: ''

取消 ShareThis

~\_config.icarus.yml
1
2
3
4
# share:
# type: sharethis
# URL to the ShareThis share plugin script
# install_url: ''

優化不同屏幕下顯示設定

加上is-3-column

~\themes\icarus\include\style\responsive.styl
1
2
3
4
5
6
7
+widescreen()
.is-1-column .container, .is-2-column .container
max-width: $desktop - 2 * $gap
width: $desktop - 2 * $gap
.is-3-column .container
max-width: $widescreen - $gap
width: $widescreen - $gap
~\themes\icarus\include\style\responsive.styl
1
2
3
4
5
6
7
8
9
10
11
12
+fullhd()
.is-2-column .container
max-width: $widescreen - 2 * $gap
width: $widescreen - 2 * $gap

.is-1-column .container
max-width: $desktop - 2 * $gap
width: $desktop - 2 * $gap

.is-3-column .container
max-width: $fullhd - 2 * $gap
width: $fullhd - 2 * $gap

增加密碼輸入錯誤樣式

~\themes\icarus\include\style\article.styl
1
2
3
4
.password-error {
box-shadow: 0px 4px 12px rgba(0,0,0,0.15);
border-radius: 4px;
}

更改按鈕顏色

目前按鈕顏色是根據base.styl中的primary顏色而定,所以更改primary設定即可。

~\themes\icarus\include\style\base.styl
1
$primary ?= #FF4500

文章設定為兩欄模式

由於我們將一些Card放到右邊的關係,所以首頁和文章都會顯示為三欄模式。  
但我們希望看文章時,只顯示兩欄模式,讓使用者專注於文章的瀏覽,可透過以下的方式設定為首頁為三欄模式,觀看文章時為兩欄模式。

更改columnCount

~\themes\icarus\layout\layout.jsx
1
const columnCount = (['page', 'post'].includes(page.layout)) ? 2 : Widgets.getColumnCount(config.widgets, config, page); 

但由於是強制設定為兩欄模式,所以右邊的card會被擠壓到,因此我們需要將右邊的card隱藏起來。

在formatWidgets函式中,增加一個變數page,並增加判斷如果是右邊的widget,則不顯示在page or post文章中。

~\themes\icarus\layout\common\widgets.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function formatWidgets(widgets, page) {
const result = {};
if (Array.isArray(widgets)) {
widgets.filter(widget => typeof widget === 'object').forEach(widget => {
if ('position' in widget && (widget.position === 'left' || widget.position === 'right')) {
if (!(widget.position in result)) {
if (widget.position === 'right') {
if (!['page', 'post'].includes(page.layout)) {
result[widget.position] = [widget];
}
} else {
result[widget.position] = [widget];
}
} else {
result[widget.position].push(widget);
}
}
});
}
return result;
}

在程式一開始render時,帶入page參數。

~\themes\icarus\layout\common\widgets.jsx
1
2
3
4
5
6
class Widgets extends Component {
render() {
const { site, config, helper, page, position} = this.props;
const widgets = formatWidgets(config.widgets, page)[position] || [];
}
}

文章內容

將標題放到Matadata上方

先將Title移到Metadata上方。

~\themes\icarus\layout\common\article.jsx
1
2
3
4
5
{/* Title */}
{page.title !== '' ? <h1 class="title is-3 is-size-4-mobile">
{index ? <a class="link-muted" href={url_for(page.link || page.path)}>{page.title}</a> : page.title}
</h1> : null}
{/* Metadata */}

再客製化讓標題在文章中置中顯示,在首頁靠左顯示。

~\themes\icarus\layout\common\article.jsx
1
2
3
4
{/* Title */}
{index ? <a className="has-link-black-ter is-size-3 is-size-4-mobile " href={url_for(page.link || page.path)}> {page.title}</a> : [<h1 className="title has-text-centered is-size-3 is-size-4-mobile has-text-weight-normal">{page.title}</h1>]
}
{/* Metadata */}

設定Metadata

將每個Metadata新增icon,使用&#9474;做隔開,並將閱讀時間和字數統計分開及取消作者欄位。

~\themes\icarus\layout\common\article.jsx
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
<div class="level-left">
{/* Creation Date */}
{page.date &&
<span class="level-item">
<i className="far fa-calendar-alt">&nbsp;</i>
<time dateTime={date_xml(page.date)} title={date_xml(page.date)}>{date(page.date)}</time>
</span>}
<span class="level-item" >&#9474;</span>

{/* Last Update Date */}
{shouldShowUpdated && <span class="level-item" dangerouslySetInnerHTML=
{ {'article.updated_at', `<i class="far fa-edit">&nbsp;</i>&nbsp;</i><time dateTime="${date_xml(page.updated)}" title="${new Date(page.updated).toLocaleString()}">${date(page.updated)}</time>`} }></span>}
<span class="level-item" >&#9474;</span>
{/* Read time */}
{article && article.readtime && article.readtime === true ? <span class="level-item">
<i class="far fa-clock">&nbsp;</i>
{(() => {const words = getWordCount(page._content);
const time = moment.duration((words / 150.0) * 60, 'seconds');
return `${_p('article.read_time', time.locale(index ? indexLaunguage : language).humanize())}`;
})()}
</span> : null}
<span class="level-item" >&#9474;</span>

{/* Words */}
{article && article.readtime && article.readtime === true ? <span class="level-item">
<i class="far fa-file-word">&nbsp;</i>
{(() => { const words = getWordCount(page._content);
return `${_p('article.word_count', words)}`;
})()}</span> : null}

{/* Visitor counter */}
{!index && plugins && plugins.busuanzi === true ? <span class="level-item" id="busuanzi_container_page_pv" dangerouslySetInnerHTML={ {
__html: _p('plugin.visit_count', '<span class="level-item" >&#9474;</span><span  id="busuanzi_value_page_pv">0</span>')
} }></span> : null}
</div>

將Metadata設定為文章閱讀時置中顯示,首頁靠左顯示。

在return前加入contentInfoHeaderClass

~\themes\icarus\layout\common\article.jsx
1
2
3
const contentInfoHeaderClass = index ? "article-meta is-size-7 is-uppercase level is-mobile" : "article-meta is-size-7 is-uppercase level-item is-mobile has-text-centered";

return <Fragment> {/* Main content */}

在Metadata的上一層修改class為{contentInfoHeaderClass}。

~\themes\icarus\layout\common\article.jsx
1
2
3
4
{/* Metadata */}
{page.layout !== 'page' ? <div class={contentInfoHeaderClass}>
<div class="level-left">
{/* Creation Date */}

原先樣式為

修改後的樣式為

修改Metadata文字內容

~\themes\icarus\languages\zh-TW.yml
1
2
3
4
5
article:
read_time: '閱讀時長 ≈ %s'
word_count:
one: '本文字數 ≈ %d個字'
other: '本文字數 ≈ %d個字'

增加標題自動計數

~\themes\icarus\include\style\article.styl
1
2
3
4
5
6
7
8
9
10
/* ---------------------------------
* Add Autocount
* --------------------------------- */
.article {counter-reset:section}
.article h2{counter-reset:sub-section}
.article h3{counter-reset:composite}
.article h4{counter-reset:detail}
.article h2:before{content:counter(section) " ";counter-increment:section}
.article h3:before{content:counter(section) "." counter(sub-section) " ";counter-increment:sub-section}
.article h4:before{content:counter(section) "." counter(sub-section) "." counter(composite) " ";counter-increment:composite}

Hightlight

Colorquote

註冊colorquote的 extend tag,這樣之後寫文章時,可以使用這個Tag。

在themes\icarus\scripts\建立一個名為 colorquote 的 JS 檔。

~\themes\icarus\scripts\colorquote.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* Color Quote Block Tag
* @description Color Quote Block
* @example
* <% colorquote [type] %>
* content
* <% endcolorquote %>
*/
hexo.extend.tag.register('colorquote', function (args, content) {
var type = args[0];
var mdContent = hexo.render.renderSync({text: content, engine: 'markdown'});
if (type.includes("step")) {
var num = type.substring(4);
type = type.substring(0, 4);
mdContent = hexo.render.renderSync({text: "Step " + num + ": "+ content, engine: 'markdown'});
}
return '<blockquote class="colorquote ' + type + '">' + mdContent + '</blockquote>';
}, {ends: true});

在themes\icarus\include\style\article.styl增加.colorquote

~\themes\icarus\include\style\article.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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
&.article
.content
.colorquote
position: relative;
padding: 0.1em 1.5em;
color: #4a4a4a;
margin-bottom: 1em;
&:before
content: " ";
position: absolute;

top: 50%;
left: -14.5px;
margin-top: -12px;
width: 24px;
height: 24px;

border-radius: 50%;
text-align: center;

color: white;
background-size: 16px 16px;
background-position: 4px 4px;
background-repeat: no-repeat;
&.info
border-color: hsl(204, 86%, 53%);
background-color: hsl(204, 86%, 93%);
&:before
background-color: hsl(204, 86%, 53%);
background-image: url("../img/info.svg");
&.success
border-color: hsl(141, 71%, 48%);
background-color: hsl(141, 70%, 88%);
&:before
background-color: hsl(141, 71%, 48%);
background-image: url("../img/check.svg");
&.warning
border-color: hsl(48, 100%, 67%);
background-color: hsl(48, 100%, 91%);
&:before
background-color: hsl(48, 100%, 67%);
background-image: url("../img/exclamation.svg");
&.danger
border-color: hsl(348, 100%, 61%);
background-color: hsl(348, 100%, 85%);
&:before
background-color: hsl(348, 100%, 61%);
background-image: url("../img/exclamation.svg");

colorquote前面的圖片是一張圖片,可以從Minos主題這邊抓取。

將下載後的檔案放到~\themes\icarus\source\img\中。

這樣我們就可以在文章中使用colorquote

1
2
<blockquote class="colorquote info"><p>Example: info</p>
</blockquote>

Example: info

但是如果在colorquote中使用markdown語法會失效,因此我們在themes\icarus\scripts\建立一個名為 tag 的 JS 檔。

內容如下:

~\themes\icarus\scripts\tag.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
/**
* Tags Filter
* @description Fix the code block using ```<code>``` will render undefined in Nunjucks
* https://github.com/hexojs/hexo/issues/2400
*/

const rEscapeContent = /<escape(?:[^>]*)>([\s\S]*?)<\/escape>/g;
const placeholder = '\uFFFD';
const rPlaceholder = /(?:<|&lt;)\!--\uFFFD(\d+)--(?:>|&gt;)/g;
const cache = [];
function escapeContent(str) {
return '<!--' + placeholder + (cache.push(str) - 1) + '-->';
}
hexo.extend.filter.register('before_post_render', function(data) {
data.content = data.content.replace(rEscapeContent, function(match, content) {
return escapeContent(content);
});
return data;
});
hexo.extend.filter.register('after_post_render', function(data) {
data.content = data.content.replace(rPlaceholder, function() {
return cache[arguments[1]];
});
return data;
});

Code Block

Dark Theme

修改背景為Dark模式

原先為Code Block背景為白色

Light Theme:

將atom-one-light改為atom-one-dark

~\_config.icarus.yml
1
2
3
4
5
6
article:
# Code highlight settings
highlight:
theme: atom-one-dark
clipboard: true
fold: unfolded

Dark Theme:

相關Code Block樣式,可參考highlightjs

客製化背景色

除了使用theme來更改Code Block的背景色外,我們可透過codeblock.styl來客製化背景色。

Code Block 主體背景色:  
在.highlight-body增加 background

~\themes\icarus\include\style\codeblock.styl
1
2
3
.highlight-body
overflow: auto
background: rgba(1, 6, 46, 0.95)

Code Block Menu Bar 背景色:  
修改$codeblock-caption-bg

~\themes\icarus\include\style\codeblock.styl
1
$codeblock-caption-bg ?= rgba(1, 64, 135, 0.5)

客製化Scrollbar

Scrollbar相關設定檔位於 ~\themes\icarus\include\style\base.styl 中

~\themes\icarus\include\style\base.styl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
+desktop()
::-webkit-scrollbar
width: 8px
height: 8px

::-webkit-scrollbar-track
border-radius: 3px
background: rgba(0,0,0,0.06)
box-shadow: inset 0 0 5px rgba(0,0,0,0.1)

::-webkit-scrollbar-thumb
border-radius: 3px
background: rgba(6, 73, 132,0.60)
box-shadow: inset 0 0 10px rgba(0,0,0,0.2)

::-webkit-scrollbar-thumb:hover
background: rgba(6, 73, 132,0.72)
作者

Nick Lin

發表於

2021-11-30

更新於

2023-01-18

許可協議


評論