Hexo博客icarus主题定制

版权申明:本文为原创文章,转载请注明原文出处

原文链接:https://blog.it-follower.com/posts/2085550418.html

本文基于Hexo和Icarus4.1.1版本,对博客主题定制过程做一个记录。在icarus4.0版本中,主题npm方式安装的话,本地将不会有主题相关的文件,需要定制的话,可以通过修改node_modules中的对应文件来完成。虽然方法不是很优雅,但是暂时也找不到解决方法。

定制CDN

由于总所周知的原因,默认的CDN可能会被墙掉,造成网站打开速度极慢。我们可以找到_config.icarus.yml,将CDN改成如下:

1
2
3
4
providers:
cdn: loli
fontcdn: loli
iconcdn: loli

定制布局

首页采用三栏布局,文章页采用2栏布局。另外,页面整体太窄,文章在阅读起来不够大气,我们需要把宽度调大一点。

  1. 首页三栏、文章页两栏

    _config.icarus.yml:将widgets放在左右两边,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    widgets:
    -
    position: left
    type: profile
    author: ye17186
    author_title: 简简单单的IT小跟班
    -
    position: right
    type: toc
    index: true
    collapsed: true
    depth: 3
    -
    position: right
    type: categories
    -
    position: right
    type: recent_posts

    _config.post.yml:将widgets全都放在左边,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    widgets:
    -
    position: left
    type: profile
    author: ye17186
    author_title: 简简单单的IT小跟班
    -
    position: right
    type: toc
    -
    position: right
    type: categories
    -
    position: right
    type: recent_posts
  2. 调整整体宽度

    node_modules\hexo-theme-icarus\include\style目录下,找到responsive.styl,将widescreen样式中:

    1
    2
    3
    4
    +widescreen()
    .is-1-column .container, .is-2-column .container
    max-width: $desktop - 2 * $gap
    width: $desktop - 2 * $gap

    改成:

    1
    2
    3
    4
    +widescreen()
    .is-1-column .container, .is-2-column .container
    max-width: $widescreen - 2 * $gap
    width: $widescreen - 2 * $gap

    定制原创标记

找到文件node_modules\hexo-theme-icarus\layout\common\article.jsx,在注释{/* Creation Date */}上面添加以下代码:

1
2
3
{/* 原创or转载 */}
<span class={`level-item copyright article-title type-${copy ? '1' : '2'}`}>{copy ? '转载' : '原创'}</span>
{/* Creation Date */}

在文章标题下,添加如下代码:

1
2
3
4
5
{/* 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>
{ /* 版权声明 */}
{is_post() ? <CopyRight config={config} page={page} helper={helper} /> : null}

引入is_post方法

1
2
3
const { url_for, date, date_xml, __, _p } = helper;
{ /* 改成 */}
const { url_for, date, date_xml, __, _p, is_post } = helper;

article.jsx的同级目录下,新建文件copyright.jsx,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const { Component } = require('inferno');

module.exports = class extends Component {
render() {
const { page, config } = this.props;
const { article } = config;

const isCopy = page.copy_from // 是否为转载的文章
const url = isCopy ? page.copy_from : page.permalink // 来源链接地址

if (article.copyright == 'false') {
return null;
}
return <div class={'copyright article-block ' + (isCopy ? 'type-1' : 'type-2') }>
{ !isCopy ? <p>版权申明:本文为原创文章,转载请注明原文出处</p> : null }
<p>原文链接:<a href={ url } target="_blank">{ url }</a></p>
</div>;
}
};

引入版权文件copyright.jsx

1
2
3
4
5
6
7
8
const moment = require('moment');
const { Component, Fragment } = require('inferno');
const Share = require('./share');
const Donates = require('./donates');
const Comment = require('./comment');
const ArticleLicensing = require('hexo-component- inferno/lib/view/misc/article_licensing');
{ /* 添加下面这行代码 */}
const CopyRight = require('./copyright');

在目录node_modules\hexo-theme-icarus\include\style\下新建版权样式文件copyright.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
$copyright-color-1 ?= #74cf59
$copyright-color-2 ?= #ca0c16
$copyright-background-color-1 ?= #eaf9e3
$copyright-background-color-2 ?= #f9ecec

.copyright
&.article-title
padding: 2px 5px
border-radius: 3px
&.type-1
color: $copyright-color-1
background-color: $copyright-background-color-1
&.type-2
color: $copyright-color-2
background-color: $copyright-background-color-2
&.article-block
padding: 0.4em 0.8em
margin-bottom: 1em
border-radius: 0.3rem
border-left: 5px solid #ca0c16
P
word-wrap: break-word
word-break: break-all
overflow: hidden
&.type-1
border-left: 5px solid $copyright-color-1
background-color: $copyright-background-color-1
&.type-2
border-left: 5px solid $copyright-color-2
background-color: $copyright-background-color-2

引入版权样式文件,找到hexo-theme-icarus\source\css\style.styl

1
2
3
@import '../../include/style/responsive'
// 新增版权样式引入
@import '../../include/style/copyright'

使用方式:

文章MD中,指定copy_from即是转载,不指定则为原创

到此,版权改造完成,效果可以参考我的博客。

定制备案

icarus主题目前没有备案的扩展点,官方后续应该后支持这个功能,我先自己扩展一个用用。

编辑文件node_modules\hexo-theme-icarus\layout\common\footer.jsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const {
logo,
logoUrl,
siteUrl,
siteTitle,
siteYear,
author,
links,
showVisitorCounter,
visitorCounterTitle,
/* 添加下面这行代码 */
beian
} = this.props;


<a href="https://github.com/ppoffice/hexo-theme-icarus" target="_blank" rel="noopener">Icarus</a>
{/* 添加下面这行代码 */}
<br /><a href={beian.url}>{beian.title}</a>

配置_config.icarus.yml

1
2
3
beian:
title: xxxxxx备案号
url: xxxurl

定制PV、UV

icarus主题在启用busuanzi插件后,只会显示网站的UV数据,没有显示PV。需要显示的话,可以

编辑文件node_modules\hexo-theme-icarus\layout\common\footer.jsx,找到文件末尾的visitorCounterTitle

1
2
3
4
visitorCounterTitle: _p('plugin.visitor_count', '<span id="busuanzi_value_site_uv">0</span>'))

改成
visitorCounterTitle: _p('plugin.visitor_count', '<span id="busuanzi_value_site_uv">0</span>') + _p('plugin.visit_count', ', <span id="busuanzi_value_site_pv">0</span>')

由于我的站点是最近才启用busuanzi的,pv、uv数据都是从0开始,为了保持客观,根据我的CSDN – IT小跟班的技术博客 的访问量,做一个初始化的定制。

编辑文件node_modules\hexo-theme-icarus\layout\common\scripts.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
// 加上这个
const busuanzi_init = `if (${config.plugins.busuanzi} == true) {
$(document).ready(function () {
var int = setInterval(fixCount, 100);
var uvOffSet = parseInt(${config.busuanzi.site_uv_offset | 0});
var pvOffSet = parseInt(${config.busuanzi.site_pv_offset | 0});

function fixCount() {
var realUv = parseInt($("#busuanzi_value_site_uv").html())
var realPv = parseInt($("#busuanzi_value_site_pv").html())
if ($("#busuanzi_container_site_uv").css("display") != "none" && realUv > 0) {
clearInterval(int);
$("#busuanzi_value_site_uv").html(realUv + uvOffSet);
$("#busuanzi_value_site_pv").html(realPv + pvOffSet);
}
}
});
}`;

return <Fragment>
<script src={cdn('jquery', '3.3.1', 'dist/jquery.min.js')}></script>
<script src={cdn('moment', '2.22.2', 'min/moment-with-locales.min.js')}></script>
{clipboard && <script src={cdn('clipboard', '2.0.4', 'dist/clipboard.min.js')} async></script>}
<script dangerouslySetInnerHTML={{ __html: `moment.locale("${language}");` }}></script>
<script dangerouslySetInnerHTML={{ __html: embeddedConfig }}></script>
{/* 加上这句 */}
<script dangerouslySetInnerHTML={{ __html: busuanzi_init }}></script>
<script src={url_for('/js/column.js')}></script>
<Plugins site={site} config={config} page={page} helper={helper} head={false} />
<script src={url_for('/js/main.js')} defer></script>
</Fragment>;

然后在_config.icarus.yml中设置uv、pv的初始值

1
2
3
busuanzi:
site_uv_offset: 100
site_pv_offset: 200

评论