Búsqueda de Middleman basada en LunrJS.
Agregue esta línea al Gemfile de su aplicación:
gem 'middleman-search'
Y luego ejecuta:
$ bundle
O instálelo usted mismo como:
$ gem install middleman-search
Debe activar el módulo en su config.rb
, indicando a la extensión cómo indexar sus recursos:
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
Donde resources
es una lista del comienzo de la URL de los recursos a indexar (probado con String#start_with?
), index_path
es la ruta relativa del archivo de índice generado en su sitio y fields
es un hash con una entrada para cada campo. para ser indexado, con un hash de opciones asociadas:
boost
Especifica un aumento de relevancia lunr al buscar en este campostore
Si se debe almacenar este campo en el mapa del documento (ver más abajo), el valor predeterminado es falsoindex
Si se indexa este campo, el valor predeterminado es verdaderorequired
El recurso no será indexado si un campo marcado como requerido tiene un valor vacío o nulo Tenga en cuenta que se incluye automáticamente una id
de campo especial, con un identificador generado automáticamente que se utilizará como ref
para el documento.
Todos los valores de los campos se recuperan de los data
del recurso (es decir, su contenido inicial) o de las options
en resource.metadata
(es decir, cualquier opción especificada en una página proxy
), excepto:
url
que es la URL real del recurso.content
el texto extraído del recurso renderizado, sin incluir su diseño Luego puede consultar el índice desde Javascript a través del objeto lunrIndex
(consulte el archivo de índice para obtener más información):
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 ] ) ;
}
} ) ;
(Gracias @Jeepler por adaptar el código lodash v3 que solíamos usar en Manas)
Esta joya incluye recursos para idiomas alternativos proporcionados por MihaiValentin/lunr-languages. Consulte ese repositorio para obtener una lista de los idiomas disponibles.
Si desea trabajar con un idioma que no está incluido, configure un archivo lunr.yourlang.js
en una carpeta de su proyecto y agregue esa carpeta a lunr_dirs
para que la gema sepa dónde buscarla.
Puede personalizar completamente el contenido que se indexará y almacenará por recurso definiendo una devolución de llamada 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
Esta opción acepta una devolución de llamada que se ejecutará para cada recurso, y se ejecutará con el documento a indexar y el mapa a almacenar, en los objetos index
y docs
de la salida respectivamente (ver más abajo), así como el recurso. siendo procesado. Puede usar esta devolución de llamada para modificar cualquiera de ellos o throw(:skip)
para omitir el recurso en cuestión.
En algunos casos, es posible que desee agregar una nueva función al canal lunr, tanto para crear la indexación como para realizar la búsqueda. Puede hacer esto proporcionando un hash pipeline
con nombres de funciones y cuerpo, por ejemplo:
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
Esto registrará la función tildes
en la canalización lunr y la agregará al crear el índice. De la documentación de Lunr:
Las funciones en la canalización se llaman con tres argumentos: el token actual que se está procesando; el índice de ese token en la matriz de tokens y la lista completa de tokens que forman parte del documento que se está procesando. Esto permite un procesamiento simple de unigramas de tokens, así como un procesamiento de n-gramas más sofisticado.
La función debe devolver la versión procesada del texto, que a su vez se pasará a la siguiente función en el proceso. Devolver indefinido evitará cualquier procesamiento posterior del token, y ese token no llegará al índice.
Tenga en cuenta que si agrega una función a la canalización, también se cargará al deserializar el índice, y lunr fallará con un error Cannot load un-registered function: tildes
si no se ha vuelto a registrar. Puede registrarlos manualmente o simplemente incluir lo siguiente en un archivo .js.erb
para ejecutarlo antes de cargar el índice:
<%= search_lunr_js_pipeline %>
El archivo de índice generado contiene un objeto JSON con dos propiedades:
index
contiene el índice lunr.js serializado, que puede cargar mediante lunr.Index.load(lunrData.index)
docs
es un mapa de los identificadores de documentos generados automáticamente a un objeto que contiene los atributos configurados para el almacenamiento. Por lo general, cargará el index
en una instancia de índice lunr y luego usará el mapa docs
para buscar el valor devuelto y presentarlo al usuario.
También debe require
el archivo lunr.min.js
en su archivo javascript principal de sprockets (si usa la canalización de activos) para poder cargar el índice:
//= require lunr.min
Si está utilizando las capacidades i18n de lunr, también debe cargar los archivos de idioma y soporte de Stemmer (en ese orden) aquí:
//= require lunr.min
//= require lunr.stemmer.support
//= require lunr.es
La canalización Middleman (si está habilitada) no incluye archivos json
de forma predeterminada, pero puede modificarlo fácilmente agregando .json
a la opción exts
de las extensiones correspondientes, como gzip
y asset_hash
:
activate :asset_hash do | asset_hash |
asset_hash . exts << '.json'
end
Tenga en cuenta que si ejecuta el archivo json de índice a través de la extensión hash de activos, deberá recuperar la URL de destino real al cargar el archivo en el navegador para realizar la búsqueda, utilizando el asistente de vista search_index_path
:
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 ) ;
}
} ) ;
Muchas gracias a:
middleman-alias
, en la que nos basamos para desarrollar esta.middleman-lunrjs
y middleman-lunr
, que sirvieron de inspiración para crear este.lunr.js