使 hexo icarus 主题支持拼音搜索

:::success
在最新的 5.0 版本已经支持拼音搜索,请升级体验


本篇文章直击如何使到 icarus 升级到可以支持拼音搜索

前期准备

  • Icarus 主题版本 3.0 以上
  • 搜索插件使用的是 Insight

操作方法

  1. 另存为下面的文件到  themes/icarus/source/js

pinyin.js

  1. 另存为下面的文件到  themes/icarus/layout/search

insight.jsx

  1. 另存为下面的文件到  themes/icarus/source/js

insight.js


  1. 修改  themes/icarus/layout/search/insight.jsx,加入拼音检索开关和依赖的 pinyin.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
/**
* Insight search plugin JSX component.
* @module view/search/insight
*/
--- a/src/view/search/insight.jsx
+++ b/src/view/search/insight.jsx
@@ -3,7 +3,7 @@
const { Component, Fragment } = require('inferno');
-const { cacheComponent } = require('../../util/cache');
+const { cacheComponent } = require('hexo-component-inferno/lib/util/cache');

/**
* Algolia search engine JSX component.
@@ -36,11 +36,18 @@ class Insight extends Component {
<div class="searchbox-input-container">
<input type="text" class="searchbox-input" placeholder={translation.hint}/>
</div>
+ <div class="searchbox-pinyin">
+ <label class="checkbox">
+ <input id="search-by-pinyin" type="checkbox" checked="checked"/>
+ <span> 拼音检索</span>
+ </label>
+ </div>
<a class="searchbox-close" href="javascript:;">×</a>
</div>
<div class="searchbox-body"></div>
</div>
</div>
+ <script src="/js/pinyin.js" defer={true}></script>
<script src={jsUrl} defer={true}></script>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
</Fragment>;
  1. 修改  themes/icarus/source/js/insight.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
diff --git a/asset/js/insight.js b/asset/js/insight.js
index 33150b3..205a096 100644
--- a/asset/js/insight.js
+++ b/asset/js/insight.js
@@ -6,6 +6,19 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
const $main = $('.searchbox');
const $input = $main.find('.searchbox-input');
const $container = $main.find('.searchbox-body');
+ const $searchByPinyin = $main.find('#search-by-pinyin');
+
+ /**
+ * 查询匹配拼音的数据。性能低于普通匹配,如果未启用拼音检索模式,直接返回 false。
+ * https://github.com/xmflswood/pinyin-match
+ * @param input {string} 目标字符串
+ * @param keyword {string} 输入的拼音或其他关键词
+ * @returns {[Array]|{Boolean}} 找到返回出现位置,未找到 / 未启用返回 false
+ */
+ function pinyinMatch(input, keyword) {
+ if (!$searchByPinyin.prop("checked")) return false;
+ return PinyinMatch.match(input, keyword);
+ }

function section(title) {
return $('<section>').addClass('searchbox-result-section').append($('<header>').text(title));
@@ -33,10 +46,12 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
const testText = text.toLowerCase();
const indices = matches.map(match => {
const index = testText.indexOf(match.toLowerCase());
- if (!match || index === -1) {
- return null;
+ if (match && index !== -1) {
+ return [index, index + match.length];
}
- return [index, index + match.length];
+ // Search by pinyin
+ const pinyinIndex = pinyinMatch(testText, match.toLowerCase());
+ return pinyinIndex ? [pinyinIndex[0], pinyinIndex[1] + 1] : null;
}).filter(match => {
return match !== null;
}).sort((a, b) => {
@@ -140,6 +155,8 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
}
if (obj[field].toLowerCase().indexOf(keyword) > -1) {
return true;
+ } else if (pinyinMatch(obj[field].toLowerCase(), keyword)) {
+ return true;
}
return false;
});
@@ -266,10 +283,12 @@ function loadInsight(config, translation) { // eslint-disable-line no-unused-var
if (location.hash.trim() === '#insight-search') {
$main.addClass('show');
}
- $input.on('input', function() {
- const keywords = $(this).val();
+ function onInputChange() {
+ const keywords = $input.val();
searchResultToDOM(keywords, search(json, keywords));
- });
+ }
+ $input.on('input', onInputChange);
+ $searchByPinyin.on('change', onInputChange);
$input.trigger('input');
});
  1. 修改  themes/icarus/include/style/search.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
diff --git a/include/style/search.styl b/include/style/search.styl
index 0cdedd9..02d9b5e 100644
--- a/include/style/search.styl
+++ b/include/style/search.styl
@@ -96,6 +96,16 @@ $searchbox-bg-pagination-item-disabled ?= $searchbox-bg-container
.searchbox-input
flex-grow: 1
color: inherit
box-sizing: border-box
padding: .75em 0 .75em 1.25em
background: $searchbox-bg-input

+ .searchbox-pinyin
+ display: flex
+ align-items: center
+ user-select: none
+ input
+ vertical-align: middle
+ span
+ position: relative
+ top: 1px
+
.searchbox-close
display: inline-block
font-size: 1.5em
padding: .5em .75em
cursor: pointer

致谢

感谢来自 ppoffice 的hexo-component-inferno 项目
以及 xmflswood 的  pinyin-match 项目提供支撑

作者

Catooilg

发布于

2020-08-05

更新于

2023-02-05

许可协议

评论