抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >
L
O
A
D
I
N
G

读书,是获取有效信息、提升自己成本最低且最好的方式之一,很早之前便想为博客添加一个书单功能,用于分享和记录自己的读书笔记。本文为大家展示Hexo博客如何添加书单页面。

一、前言

之前便想添加此功能了,但一直不知道以什么方式呈现比较好,网上搜索的也大多数都是那种基于插件的豆瓣书单,那不是我想要的,我想要的是自定义而且能够在线预览的那种。偶然间翻到一位大佬的书单,刚好符合我的想法,就拿过来参考了一下 hexo博客增加书单

二、功能实现

1. 添加书单数据

首先,你需要准备书单的相关数据,方便后续使用以及维护。创建一个文本文件,用于记录你的书单内容,它可以是 JSON 或 YANL 格式。
在文件中,你可以列出你喜欢的书籍、推荐的书单主题或者写下对每本书的简评。你也可以添加书籍封面图片或者链接到书籍的购买页面。根据自己的需要和喜好进行书单内容的编写。
博主采用的是 json 来存储书单数据,在 Hexo 的 数据文件夹 下创建 books.json 文件

source/_data/books.json
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
[
{
"enable": true,
"name": "人文社科",
"type": "人文社科",
"description": "类型描述",
"books": [
{
"name": "《人性的弱点》",
"author": "[美]戴尔·卡耐基",
"publish_date": "2017-09-01",
"read_status": "正在阅读...",
"read_note_name": "人性的弱点",
"read_note_url": "https://yywen.top/books/人性的弱点",
"cover": "https://img.yywen.top/hy-blog/img/books/book2.png",
"url": "https://cloud.yywen.top/d/%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/%E6%94%B6%E9%9B%86%E7%AE%B1/%E3%80%8A%E4%BA%BA%E6%80%A7%E7%9A%84%E5%BC%B1%E7%82%B9%E3%80%8B%E6%88%B4%E5%B0%94%C2%B7%E5%8D%A1%E8%80%90%E5%9F%BA.pdf",
"ref_level": "5",
"describe": "《人性的弱点》作为一本实用的人际关系著作,从人性本质的角度,挖掘出潜藏在人们体内的弱点,使人们能够充分认识自己,并不断改造自己,从而能有所长进,直至取得成功。"
},
{
"name": "《软技能:代码之外的生存指南》",
"author": "[美]John Z. Sonmez",
"publish_date": "2016-07",
"read_status": "正在阅读...",
"read_note_name": "代码之外的生存指南",
"read_note_url": "https://yywen.top/books/软技能",
"cover": "https://img.yywen.top/hy-blog/img/books/book3.jpg",
"url": "https://cloud.yywen.top/d/%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/%E6%94%B6%E9%9B%86%E7%AE%B1/%E8%BD%AF%E6%8A%80%E8%83%BD%EF%BC%9A%E4%BB%A3%E7%A0%81%E4%B9%8B%E5%A4%96%E7%9A%84%E7%94%9F%E5%AD%98%E6%8C%87%E5%8D%97.pdf",
"ref_level": "5",
"describe": "这是一本真正从“人”(而非技术也非管理)的角度关注软件开发人员自身发展的书。书中论述的内容既涉及生活习惯,又包括思维方式,凸显技术中“人”的因素,全面讲解软件行业从业人员所需知道的所有“软技能”。"
},
{
"name": "《黑客与画家》",
"author": "[美]Paul Graham",
"publish_date": "2011-04",
"read_status": "正在阅读...",
"read_note_name": "黑客与画家",
"read_note_url": "https://yywen.top/books/黑客与画家",
"cover": "https://img.yywen.top/hy-blog/img/books/book5.jpg",
"url": "https://cloud.yywen.top/d/%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/%E6%94%B6%E9%9B%86%E7%AE%B1/%E8%BD%AF%E6%8A%80%E8%83%BD%EF%BC%9A%E4%BB%A3%E7%A0%81%E4%B9%8B%E5%A4%96%E7%9A%84%E7%94%9F%E5%AD%98%E6%8C%87%E5%8D%97.pdf",
"ref_level": "5",
"describe": "这是一本真正从“人”(而非技术也非管理)的角度关注软件开发人员自身发展的书。书中论述的内容既涉及生活习惯,又包括思维方式,凸显技术中“人”的因素,全面讲解软件行业从业人员所需知道的所有“软技能”。"
}
]
},
{
"enable": true,
"name": "编程",
"type": "编程",
"description": "类型描述",
"books": [
{
"name": "《Code Complete 2》",
"author": "[美]Steve McConnell",
"publish_date": "2022-06-01",
"read_status": "正在阅读...",
"read_note_name": "代码大全2",
"read_note_url": "https://yywen.top/books/代码大全2",
"cover": "https://img.yywen.top/hy-blog/img/books/codecomplete2.png",
"url": "https://wqbook.wqxuetang.com/deep/read/pdf?bid=3237948",
"ref_level": "5",
"describe": "这本书是著名科技类作家史蒂夫·麦康奈尔的经典著作,是一本完整的软件构建手册,涵盖了软件构建过程中的所有细节。它从软件质量和编程思想等方面论述了软件构建的各个问题,并详细论述了紧跟时代潮流的新技术、高屋建瓴的观点、通用的概念,还含有丰富而典型的程序示例。"
},
{
"name": "《架构即未来》",
"author": "Martin L.Abbott / Michael T.Fisher",
"publish_date": "2016-4-15",
"read_status": "正在阅读...",
"read_note_name": "架构即未来",
"read_note_url": "https://yywen.top/books/架构即未来",
"cover": "https://img.yywen.top/hy-blog/img/books/book4.jpg",
"url": "https://book.douban.com/subject/26765979/",
"ref_level": "5",
"describe": "一本介绍可扩展架构(组织架构与技术架构)的书籍。从组织、企业内的流程设计、技术等方面告诉管理者要设计什么样的架构才能可扩展且更好地服务业务。书比较厚,初创公司管理岗位的读者对书中的内容会更有体感。"
}
]
}
]

2. 编写书单模板

在上面的 index.md 中可以看到,博主用的并不是 Hexo 的模板,而是使用 Volantis主题的标题Tags,不过也差不了多少,都是要自定义模板

在themes/volantis/scripts/tags 文件夹下创建books.js文件并加入以下代码:

tags/books.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
'use strict';

function bookNote(args) {
if (args.length > 1) {
const cls = args[0].trim();
const text = args[1].trim();
return `<div class="note ${cls}">${hexo.render.renderSync({text: text, engine: 'markdown'}).split('\n').join('')}</div>`;
} else if (args.length > 0) {
const text = args[0].trim();
return `<div class="note">${hexo.render.renderSync({text: text, engine: 'markdown'}).split('\n').join('')}</div>`;
}
}

function getCurrentBooksAtType(book_dom,type_name) {
for (let i = 0; i < book_dom.length; i++) {
if (book_dom[i]['name'] == type_name && book_dom[i]['enable'] == true) {
return book_dom[i];
}
}
return undefined;
}

function buidBook(args) {
var book_dom = hexo.locals.get('data').books;
if (book_dom == undefined) {
return '';
}
var type_name = args[args.length-1];
var book_note = getCurrentBooksAtType(book_dom,type_name);
if (book_note == undefined) {
return '';
}
var books = book_note.books;
let ret = '';
for (let index = 0; index < books.length; index++) {
const book = books[index];
ret += '<li><div class="name">'+ book.name +'</div><div class="info">';
ret += '<a href="' + book.url + '" target="_blank" rel="noreferrer noopener" class="book-container">';
ret += '<div class="book"><img src="' + book.cover +'" alt="'+ book.name +'" /></div></a>';
ret += '<div><p>作者:'+ book.author +'</p>';
ret += '<p>出版时间:'+ book.publish_date +'</p>';
ret += '<p>阅读进度:'+ book.read_status +'</p>';
ret += '<p><span>读书笔记:</span><a href="'+ book.read_note_url+'" target="_blank" rel="noopener noreferrer">' + book.read_note_name + '</a></p>'
ret += '<p><span>推荐指数:</span><span></span>';
let ref_level = Number(book.ref_level) || 1;
ref_level = ref_level > 5 ? 5 : ref_level;
for (let index = 0; index < ref_level; index++) {
ret += '<i class="fa fa-star"></i>';
}
ret += '</p></div></div>';
ret += '<p class="description">' + book.describe + '</p></li>'
}
return ret;
}

function book(args) {
if(/::/g.test(args)){
args = args.join(' ').split('::');
}
else{
args = args.join(' ').split(',');
}
return `<div id="book">
<div class="page">
${bookNote(args)}
<ul class="content">
${buidBook(args)}
</ul>
</div>
</div>`;
}

hexo.extend.tag.register('book', book);

3. 创建书单页面

再创建一个书单显示页面

1
hexo new page books

编写书单页面内容如下:

books/index.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
---
seo_title: 明君书苑
date: 2023-02-09 16:15:20
sidebar: []
cover: true
headimg: https://img.yywen.top/hy-blog/img/books/bookbg.jpg
comments: false
---

{% span purple center logo large::明 君 书 苑 %}
{% span center small::孤独寂寞时,阅读可以消遣。高谈阔论时,知识可供装饰。处世行事时,知识意味着才干。 %}

<!-- 引入书单模块css样式 -->
<head>
<link rel="stylesheet" type="text/css" href="https://img.yywen.top/hy-blog/css/book.css">
</head>

<!-- 书单模块开始 -->

{% book guide clear::人文社科 %}

{% book guide clear::编程 %}

<!-- 书单模块结束 -->

现在基本上已经完成了,最后使用hexo一键三连(hexo clean && hexo g && hexo d
最后访问books页面就可以看到效果啦!

后续更新

用了一段时间之后发觉在添加书籍数据的时候有点繁琐,想改进优化一下但又不知如何是好 (v)
于是乎,改了一下数据格式和标签代码,具体如下:
1.将之前的书籍书籍从json换成了yml

books.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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
books_A1: # 书单分组
title: 人文社科 # 分组标题
description: 类型描述 # 分组描述
items:
- name: 《人性的弱点》 # 书名
author: '[美]戴尔·卡耐基' # 作者
date: '2022-06-01'
cover: https://img.yywen.top/hy-blog/img/books/book2.png # 封面
url: https://cloud.yywen.top/d/%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/%E6%94%B6%E9%9B%86%E7%AE%B1/%E3%80%8A%E4%BA%BA%E6%80%A7%E7%9A%84%E5%BC%B1%E7%82%B9%E3%80%8B%E6%88%B4%E5%B0%94%C2%B7%E5%8D%A1%E8%80%90%E5%9F%BA.pdf # 链接
readstate: 正在阅读
readname: 人性的弱点
readnote: https://yywen.top/books/人性的弱点 # 读书笔记
reflevel: 5 # 推荐指数
description: 《人性的弱点》作为一本实用的人际关系著作,从人性本质的角度,挖掘出潜藏在人们体内的弱点,使人们能够充分认识自己,并不断改造自己,从而能有所长进,直至取得成功。 # 书评
- name: 《软技能:代码之外的生存指南》
author: '[美]John Z. Sonmez'
date: '2022-06-01'
cover: https://img.yywen.top/hy-blog/img/books/book3.jpg
url: https://cloud.yywen.top/d/%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/%E6%94%B6%E9%9B%86%E7%AE%B1/%E8%BD%AF%E6%8A%80%E8%83%BD%EF%BC%9A%E4%BB%A3%E7%A0%81%E4%B9%8B%E5%A4%96%E7%9A%84%E7%94%9F%E5%AD%98%E6%8C%87%E5%8D%97.pdf
readstate: 正在阅读
readname: 代码之外的生存指南
readnote: https://yywen.top/books/软技能
reflevel: 5
description: 这是一本真正从“人”(而非技术也非管理)的角度关注软件开发人员自身发展的书。书中论述的内容既涉及生活习惯,又包括思维方式,凸显技术中“人”的因素,全面讲解软件行业从业人员所需知道的所有“软技能”。
- name: 《黑客与画家》
author: '[美]Paul Graham'
date: '2022-06-01'
cover: https://img.yywen.top/hy-blog/img/books/book5.jpg
url: https://cloud.yywen.top/d/%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%96%99/%E6%94%B6%E9%9B%86%E7%AE%B1/%E8%BD%AF%E6%8A%80%E8%83%BD%EF%BC%9A%E4%BB%A3%E7%A0%81%E4%B9%8B%E5%A4%96%E7%9A%84%E7%94%9F%E5%AD%98%E6%8C%87%E5%8D%97.pdf
readstate: 正在阅读
readname: 黑客与画家
readnote: https://yywen.top/books/黑客与画家
reflevel: 5
description: 《人性的弱点》作为一本实用的人际关系著作,从人性本质的角度,挖掘出潜藏在人们体内的弱点,使人们能够充分认识自己,并不断改造自己,从而能有所长进,直至取得成功。

books_B1: # 书单分组
title: 编程 # 分组标题
description: 类型描述 # 分组描述
items:
- name: 《Code Complete 2 # 书名
author: '[美]Steve McConnell' # 作者
date: '2022-06-01' # 出版日期
cover: https://img.yywen.top/hy-blog/img/books/codecomplete2.png # 封面
url: https://wqbook.wqxuetang.com/deep/read/pdf?bid=3237948 # 链接
readstate: 正在阅读 # 阅读进度
readname: 人性的弱点 # 读书笔记
readnote: https://yywen.top/books/人性的弱点 # 笔记链接
reflevel: 5 # 推荐指数
description: 《人性的弱点》作为一本实用的人际关系著作,从人性本质的角度,挖掘出潜藏在人们体内的弱点,使人们能够充分认识自己,并不断改造自己,从而能有所长进,直至取得成功。 # 书评
- name: 《架构即未来》
author: 'Martin L.Abbott / Michael T.Fisher'
date: '2022-06-01'
cover: https://img.yywen.top/hy-blog/img/books/book4.jpg
url: https://book.douban.com/subject/26765979/
readstate: 正在阅读
readname: 架构即未来
readnote: https://yywen.top/books/人性的弱点
reflevel: 5
description: 《人性的弱点》作为一本实用的人际关系著作,从人性本质的角度,挖掘出潜藏在人们体内的弱点,使人们能够充分认识自己,并不断改造自己,从而能有所长进,直至取得成功。

看起来好像比之前的JSON格式有舒服多了,数据分类明确有限,也比较紧凑(仅代表个人观点)

2.与之对应的标签也略作修改

tags/books.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
'use strict';

hexo.extend.tag.register('books', function (args) {
args = hexo.args.map(args, ['only', 'not', 'api']);
if (args.only) {
if (/::/g.test(args.only)) {
args.only = args.only.split('::');
} else {
args.only = args.only.split(',');
}
}
if (args.not) {
if (/::/g.test(args.not)) {
args.not = args.not.split('::');
} else {
args.not = args.not.split(',');
}
}
var books = hexo.locals.get('data').books1;
if (books == undefined) {
books = {};
}
var el = '<div class="container">';
function groupHeader(group) {
if (group.title) {
const text = group.title;
return `<div class="note">${hexo.render.renderSync({ text: text, engine: 'markdown' }).split('\n').join('')}</div>`;
}
}
function cell(book) {
if (book.name && book.cover) {
var cell = '<li><div class="name">' + book.name + '</div><div class="info">';
cell += '<a href="' + book.url + '" target="_blank" rel="noreferrer noopener" class="book-container">';
cell += '<div class="book"><img src="' + book.cover + '" alt="' + book.name + '" /></div></a>';
cell += '<div><p>作者:' + book.author + '</p>';
cell += '<p>出版时间:' + book.date + '</p>';
cell += '<p>阅读进度:' + book.readstate + '</p>';
cell += '<p><span>读书笔记:</span><a href="' + book.readnote + '" target="_blank" rel="noopener noreferrer">' + book.readname + '</a></p>';
cell += '<p><span>推荐指数:</span><span></span>';
let ref_level = Number(book.reflevel) || 1;
ref_level = ref_level > 5 ? 5 : ref_level;
for (let index = 0; index < ref_level; index++) {
cell += '<i class="fa fa-star"></i>';
}
cell += '</p></div></div>';
cell += '<p class="description">' + book.description + '</p></li>'
return cell;
} else {
return '';
}
}
for (let groupId of Object.keys(books)) {
function f() {
if (args.not && args.not.includes(groupId)) {
return;
}
if (groupId in books) {
let group = books[groupId];
el += '<div id="book"><div class="page">';
if (group.title || group.description) {
el += groupHeader(group);
}
if (group.items) {
el += '<ul class="content">';
group.items.forEach((book, i) => {
el += cell(book);
});
el += '</ul>';
}
el += '</div></div>';
}
}
if (args.only) {
if (args.only.includes(groupId)) {
f();
}
} else {
f();
}
}
el += '</div>';
return el;
});

3.在markdown书单在应用该标签即可,写法如下:

1
2
3
4
5
6
7
8
9
10
11
// 全部显示
{% books not: %}

// 除了 books_A1 别的都显示
{% books not:books_A1 %}

// 仅显示 books_A1
{% books only:books_A1 %}

// 仅显示 books_A1 和 books_B1
{% books only:books_A1,books_B1 %}

最后使用hexo一键三连(hexo clean && hexo g && hexo d

评论