Tipue search 是一個 Javascript 程式庫,可以在客戶端進行資料搜尋,對於像本站一樣的靜態網站,是一個可行的選擇。 山姆鍋為了讓網站內容可以快取在客戶端,使用了 HTML5 application cache 的技術。透過這樣的技術,網站大部份內容都可以離線觀看,但是卻發現 Tipue search 無法在離線狀態下運作。
對於像 Tipue search 這種 Javascript 搜尋引擎,要離線運作理應不難。根據文件建議,採用它的 static 模式作為離線搜尋的基礎。 Pelican 有個 Tipue search 的插件,可以用來產生所需要的索引檔案,但它只支援 Tipue search 的 JSON 模式。 先不考慮過程遇到的問題,大致上,只要按照下列步驟即可:
設定 Tipue search 插件產生 static 模式需要的索引檔
修改 Tipue search Pelican 插件,找到 generate_output
方法,將其中 ‘tipuesearch_content.json’ 改為
‘tipuesearch_content.js’,以及
with open(path, 'w', encoding='utf-8') as fd:
json.dump(root_node, fd, separators=(',', ':'), ensure_ascii=False)
改成
with open(path, 'w', encoding='utf-8') as fd:
search_text = json.dumps(root_node, separators=(',', ':'), ensure_ascii=False)
fd.write('var tipuesearch = ')
fd.write(search_text)
fd.write(';')
這樣的修改目的在使用索引資料建立 tipuesearch
JavaScript 物件。這個物件是 Tipue search 的 static 模式下所需要的。
將 Tipue search 相關的資源檔案加入 Application cache
Tipue search 自帶的檔案有下列這些:
- tipuesearch.css
- tipuesearch.min.js
- tipuesearch_set.js
- img/search.png
這些檔案放置的位置跟如何設定 Tipue search 與使用的主題有關。像山姆鍋使用的 Pelican 插件所產生的索引檔放在 /tipuesearch_content.js
, 其他檔案則放在 /theme/tipuesearch/
目錄中。 您也可以參考 本站的快取描述檔 ⎘。
修改搜尋網頁樣板
山姆鍋的網站使用的樣板,需要修改的檔案名稱是 search.html
,讀者需要根據使用的樣板調整。將模式從’json’改為’static’。
把’contentLocation’的值改為 ‘tipuesearch_content.js’(這是插件產生的索引檔)。 在原先的 JavaScript 之前,加入 <script type=\"text/javascript\" src=\"{{ SITEURL }}/tipuesearch\_content.js\"\>\</script\>
,這樣 Tipue search 才能使用 tipuesearch
這個物件內的索引資料。修改後的部分內容應該類似這樣:
<script type="text/javascript" src="{{ SITEURL }}/tipuesearch_content.js"></script>
<script type="text/javascript" src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/tipuesearch_set.js"></script>
<script type="text/javascript" src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/tipuesearch.js"></script>
完成以上步驟,Tipue search 已經可以支援 static 模式,Pelican 也可以產生所需要的索引檔,該快取的檔案也都指定在描述檔中了。 直覺上,應該算是大功告成了!
可惜,事情往往沒有想像中的單純。實際測試,發現還是無法在離線模式下運作,膜拜 Google 大神的結果,發現只要網址中出現查詢字串(query
string), 也就是 ?
之後的那部分,瀏覽器便會試圖從網路上重新抓取 search.html
檔案。但因為在離線模式下,這個動作一定會失敗。 Tipue
search 運作的方式便是從查詢字串中找到 q
這個參數作爲搜尋關鍵字。
要讓 Tipue search 可以在離線模式下正常運作,看來只能讓它使用網址中的 hashtag(#)來獲取搜尋關鍵字。按照規格,這樣的網址變更,瀏覽器不會試圖從網路重新下載網頁。 這部分的修改需要改到 Tipue search 的程式碼,對於後續更新會有些麻煩。
在 Tipue search 的 ‘tipuesearch.js’ 檔案,將下列片段,
if (getURLP('q'))
{
$('#tipue_search_input').val(getURLP('q'));
getTipueSearch(0, true);
}
改為
if (window.location.hash)
{
q = window.location.hash.substr(1)
$('#tipue_search_input').val(q);
getTipueSearch(0, true);
}
這樣的修改是要讓 Tipue search 從網址的 hashtag 取得參數,並去掉’#‘字元。
樣板中跟搜尋相關的界面,會在網址後面加上 ?q=關鍵字
,
要修改這樣的行為,需要用到 JavaScript 了。底下是本站使用的代碼:
<script type="text/javascript">
$('#tipue_search_bar').submit(function(ev) {
ev.preventDefault();
q = $('#tipue_search_input').val()
url = window.location.href
pathArray = location.href.split( '/' );
protocol = pathArray[0];
host = pathArray[2];
url = protocol + '//' + host;
window.location = url + '/search.html#' + q
});
</script>
山姆鍋假設網頁放在根目錄,如果放在子目錄,請將 url + '/search.html#' + q
改為 url + '/<子目錄>/search.html#' + q
。
結語
山姆鍋手癢試著讓部落格可以快取在客戶端,衍生出離線搜尋的需求。拼拼湊湊下,也完成了一個可行的方案。在一般情況下,山姆鍋不建議直接修改程式, 因為會造成後續維護的困難。不管如何,一個可以離線搜尋內容的部落格,就這樣完成了!