Hexo 默認的 Landscape 主題其實已經(jīng)很好了侨把,可以說簡明美觀腌零,網(wǎng)頁上的元素也不難添加莲组。
但是美中不足的就是用了谷歌搜索引擎看疗,谷歌在國內(nèi)打不開就不說了沙峻,而且用外部搜索引擎本來也不如站內(nèi)搜索便捷實用。
后來我發(fā)現(xiàn) NexT 主題是有站內(nèi)搜索功能的两芳,就試著把這個功能移植了進來摔寨。
本地搜索的原理
對于動態(tài)網(wǎng)站來說,可以通過 php 實現(xiàn)(具體見Github Pages(二):個人網(wǎng)站的功能插件)怖辆。
但是是复,GitHub博客是靜態(tài)網(wǎng)站,用不了 php疗隶,導致我在老網(wǎng)站只能把google搜索結(jié)果頁內(nèi)置到了網(wǎng)站里面 (Landscape也用了谷歌)佑笋。
NexT 主題實現(xiàn)這個功能,用了 Hexo 的拓展包 hexo-generator-searchdb
斑鼻,它預先生成了一個文本庫search.xml
蒋纬,然后傳到了網(wǎng)站里面。在本地搜索的時候坚弱,NexT直接用javascript調(diào)用了這個文件蜀备,從而實現(xiàn)了靜態(tài)網(wǎng)站的本地搜索。
準備工作
首先把產(chǎn)生文本庫的包安裝好荒叶,執(zhí)行 npm install hexo-generator-searchdb --save
碾阁。
然后在主配置文件 _config.yml
里面加上
search:
path: search.xml
field: post
format: html
limit: 10000
并且在主題配置文件加上
local_search:
enable: true
trigger: auto
top_n_per_article: 1
其中trigger
表示搜索結(jié)果會不會打字時自動顯示,top_n_per_article
表示每篇文章最多顯示幾條結(jié)果(-1為不限數(shù)字)些楣。
這些只是準備工作脂凶,在把代碼放到Landscape 之前,這些設置不會起任何作用愁茁。
NexT 主題的本地搜索代碼
NexT 主題的 local-search 主要是下面幾個模塊組成的:
- 核心javascript腳本:localsearch.swig
- css配置文件:localsearch.styl
- 搜索框:另一個localsearch.swig
- 在header中添加鏈接:header.swig
Landscape主題的后綴有所不同(不是.swig蚕钦, 而是.ejs),這幾個文件copy過來之后需要稍微改一下語法鹅很,幾個圖標也需要重新定義嘶居,細節(jié)如下。
移植步驟
定義"搜索"促煮,"關閉"邮屁,"無結(jié)果"等圖標
NexT 大量使用了 <i class = "fa abc"> </i>
這樣的方式來引用 FontAwesome 圖標整袁,但是 Landscape 卻不支持這么用。
所以一開始不得不定義一些圖標佑吝,在主題文件夾 themes/landscape/
的 /source/css/
下面找個地方 (比如說_partial/header.styl
)坐昙,定義:
#icon-close:before {
font-family: FontAwesome;
content: "\f146";
font-size: x-large
}
這樣就定義了一個關閉搜索框的圖標。移植的時候重新定義圖標為<span id="icon-close"></span>
就可以了。
新定義的圖標主要是搜索 \f002
,關閉\f146
暴构,和無結(jié)果 \f119
烈拒。
放入調(diào)出搜索框的鏈接
首先進入主題文件夾的/layout/_partial/header.ejs
,那里默認有一個搜索鏈接(id="nav-search-btn" class="nav-icon"
)陋桂。
把這個鏈接擴展為:
<% if(!theme.local_search.enable) { %><a id="nav-search-btn" class="nav-icon" title="<%= __('search') %>"></a><% } %>
<% if(theme.local_search.enable) { %><a href="javascript:;" class="popup-trigger nav-icon" id="nav-search-btn"></a><% } %>
這也就意味著用主題配置中的 local_search.enable
來控制搜索功能了逆趣,打開本地搜索的情況下,搜索鏈接會啟動class="popup-trigger"
嗜历,也就打開了本地搜索引擎宣渗。
放入搜索框
還是著剛才的文件header.ejs
,可以在最后一行</header>
前面加上
<% if(theme.local_search.enable) { %><div class="local-search-inner"><%- partial('search') %></div><% } %>
其中 <%- partial('search') %>
指向了 search.ejs
梨州,這個文件也就是 NexT 的搜索框 另一個localsearch.swig 了痕囱。
把它拷貝成search.ejs
跟 header.ejs
放在一起,但是圖標要全部換成適配Landscape的定義暴匠。另外直接明碼寫上placeholder=" 本地搜索..."
就可以了鞍恢。
放入核心 javascript
把localsearch.swig放入/layout/_partial/
, 并且命名為localsearch.ejs
。
然后在/layout/layout.ejs
的最后每窖,</body>
的上一行引用這個文件 <%- partial('_partial/localsearch') %>
帮掉。
這個目的是在每一個網(wǎng)頁的最下方加入這一段 javascript。
然后就要改這個文件了窒典, 要改的有三項:
- 圖標
跟剛才一樣蟆炊,凡是帶class="fa abc"
的圖標都要重新定義成適配Landscape的。 - 語法
改成localsearch.ejs
之后瀑志,這個腳本里面的兩類語法要改涩搓。 一是if..else..要這樣用:
<% if (theme.local_search.enable){ %><% } %>
二是config要這樣調(diào)用(注意有個等號):
var search_path = "<%= config.search.path %>" ;
大概一共三四處要改,主要是config能讀到就可以了劈猪。
-
搜索框的位置
這個腳本里面有一處容易坑的地方昧甘,就是這一行$('.popup').detach().appendTo('.header-inner');
注意這個
.header-inner
是搜索框的位置,是要根據(jù)情況改的岸霹。比如我剛才在header.ejs
定義的是<div class="local-search-inner"><%- partial('search') %></div>
那就要把
.header-inner
改為.local-search-inner
了疾层。
放入渲染文件,取消陰影背景
渲染文件也是必須的贡避,可以把 localsearch.styl 放入 /source/css/_partial/
然后在主渲染文件/source/css/style.styl
中痛黎,注意加上 @import "_partial/localsearch"
就可以了予弧。
不知道什么原因,這個搜索引擎的陰影背景.local-search-pop-overlay
總是會出現(xiàn)在最上方湖饱,導致搜索框出來之后根本點不到掖蛤。我直接給它設置 z-index: auto
,跳過了這個問題井厌。
這個文件是大部分元素的渲染文件蚓庭,可以用來調(diào)整圖標位置,placeholder文字的大小等等仅仆,這都是細節(jié)了器赞。
把原先的搜索功能關掉
原先的搜索能在 source/js/script.js
里面,把這一段code移到 localsearch.ejs
里面墓拜,然后用一個
<% if (!theme.local_search.enable){ %><% } %>
來控制就可以了港柜。
總結(jié)
最終搜索的效果截圖在這里:
其實直接用 NexT 就好了,不過自己編輯主題可以趁機學習一下咳榜。畢竟還是成功了夏醉。
有一點很重要的是,自己編輯主題是免不了要debug的涌韩,要善用谷歌瀏覽器的檢查功能(以及最簡單的輸出 console.log()
畔柔,或者其他工具的同類功能)。