基於 LunrJS 的 Middleman 搜尋。
將此行新增至應用程式的 Gemfile 中:
gem 'middleman-search'
然後執行:
$ bundle
或自己安裝:
$ gem install middleman-search
您需要啟動config.rb
中的模組,告訴擴充如何索引您的資源:
activate :search do | search |
search . resources = [ 'blog/' , 'index.html' , 'contactus/index.html' ]
search . index_path = 'search/lunr-index.json' # defaults to `search.json`
search . lunr_dirs = [ 'source/vendor/lunr-custom/' ] # optional alternate paths where to look for lunr js files
search . language = 'es' # defaults to 'en'
search . fields = {
title : { boost : 100 , store : true , required : true } ,
content : { boost : 50 } ,
url : { index : false , store : true } ,
author : { boost : 30 }
}
end
其中resources
是要索引的資源的 URL 開頭的列表(使用String#start_with?
進行測試), index_path
是站點中產生的索引文件的相對路徑, fields
是一個哈希值,每個字段有一個條目被索引,並帶有相關選項的雜湊值:
boost
指定搜尋該欄位時 lunr 相關性增強store
是否在文件結構圖中儲存該欄位(見下文),預設為 falseindex
是否對該欄位建立索引,預設為truerequired
如果標記為必填的欄位具有空值或 null 值,則資源不會被索引請注意,會自動包含一個特殊欄位id
,並使用自動產生的識別碼作為文件的ref
。
所有欄位值均從資源data
(即其 frontmatter)或resource.metadata
中的options
(即proxy
頁面中指定的任何選項)中檢索,但下列情況除外:
url
是實際的資源 urlcontent
從渲染資源中提取的文本,不包括其佈局然後,您可以透過lunrIndex
物件從 Javascript 查詢索引(有關更多信息,請參閱索引檔案):
var max_search_entries = 50 ;
var result = [ ] ; //initialize empty array
lunrIndex . search ( request . term ) . forEach ( function ( item , index ) {
if ( index < max_search_entries ) {
result . push ( lunrData . docs [ item . ref ] ) ;
}
} ) ;
(感謝 @Jeepler 改編了我們在 Manas 使用的 lodash v3 代碼)
該 gem 包含 MihaiValentin/lunr-languages 提供的替代語言的資源。請參閱該儲存庫以取得可用語言的清單。
如果您想使用未包含的語言,請在專案的資料夾中設定lunr.yourlang.js
文件,並將該資料夾新增至lunr_dirs
中,以便 gem 知道在哪裡可以找到它。
您可以透過定義before_index
回呼來完全自訂每個資源要索引和儲存的內容:
activate :search do | search |
search . before_index = Proc . new do | to_index , to_store , resource |
if author = resource . data . author
to_index [ :author ] = data . authors [ author ] . name
end
end
end
此選項接受將為每個資源執行的回調,並將在輸出的index
和docs
物件中分別執行要索引的文件和要儲存的地圖(見下文)以及資源正在處理中。您可以使用此回調來修改其中任何一個,或throw(:skip)
來跳過有問題的資源。
在某些情況下,您可能希望為 lunr 管道添加新函數,既用於建立索引,又用於搜尋。您可以透過提供帶有函數名稱和主體的pipeline
雜湊來完成此操作,例如:
activate :search do | search |
search . pipeline = {
tildes : <<-JS
function(token, tokenIndex, tokens) {
return token
.replace('á', 'a')
.replace('é', 'e')
.replace('í', 'i')
.replace('ó', 'o')
.replace('ú', 'u');
}
JS
}
end
這將在 lunr 管道中註冊tildes
函數,並在建立索引時添加它。來自 Lunr 文件:
使用三個參數呼叫管道中的函數:正在處理的當前令牌;此標記在標記數組中的索引,以及正在處理的文件的標記部分的整個清單。這使得能夠對標記進行簡單的一元語法處理以及更複雜的 n 元語法處理。
該函數應傳回文字的處理版本,該版本將依序傳遞給管道中的下一個函數。傳回未定義將阻止對令牌的任何進一步處理,並且該令牌將不會進入索引。
請注意,如果您為管道新增函數,則在反序列化索引時也會載入函數,且 lunr 將會失敗,並出現Cannot load un-registered function: tildes
錯誤(如果尚未重新註冊)。您可以手動註冊它們,也可以簡單地將以下內容包含在要在載入索引之前執行的.js.erb
檔案中:
<%= search_lunr_js_pipeline %>
產生的索引檔案包含一個具有兩個屬性的 JSON 物件:
index
包含序列化的 lunr.js 索引,您可以透過lunr.Index.load(lunrData.index)
載入該索引docs
是從自動產生的文件 ID 到包含配置為儲存的屬性的物件的映射您通常會將index
載入到 lunr 索引實例中,然後使用docs
對應尋找傳回值並將其呈現給使用者。
您還應該require
主鏈輪 JavaScript 檔案中的lunr.min.js
檔案(如果使用資產管道)才能實際載入索引:
//= require lunr.min
如果您使用 lunr 的 i18n 功能,您還應該在此處載入 Stemmer 支援和語言檔案(按順序):
//= require lunr.min
//= require lunr.stemmer.support
//= require lunr.es
Middleman 管道(如果已啟用)預設不包含json
文件,但您可以透過將.json
新增至對應擴充功能的exts
選項(例如gzip
和asset_hash
來輕鬆修改它:
activate :asset_hash do | asset_hash |
asset_hash . exts << '.json'
end
請注意,如果您透過資產雜湊擴充功能運行索引 json 文件,則在瀏覽器中載入文件進行搜尋時,您將需要使用search_index_path
視圖助理來擷取實際的目標 URL:
var lunrIndex = null ;
var lunrData = null ;
// Download index data
$ . ajax ( {
url : "<%= search_index_path %>" ,
cache : true ,
method : 'GET' ,
success : function ( data ) {
lunrData = data ;
lunrIndex = lunr . Index . load ( lunrData . index ) ;
}
} ) ;
非常感謝:
middleman-alias
擴展,我們就是以此為基礎來開發這個擴展的。middleman-lunrjs
和middleman-lunr
擴展,這是製作此擴展的靈感。lunr.js
貢獻者