middleman-search 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 83d2b65441f0766102161c0489cedec031fb34fe
4
- data.tar.gz: 612b8f30867b4695af0b39ead29304360bf1d644
3
+ metadata.gz: 3dc491d945d930fbca061b6e1c93fa4d2f5b2d1e
4
+ data.tar.gz: 63d5f6e7adbe105b1a865f631c8b365151381951
5
5
  SHA512:
6
- metadata.gz: 86b81ea83c06557e4f29e9a7823b88a96260a55dfbc36c268fb436ecd230df85adf7db9a74f2a7255a2ec1e5715ab5c38020e3933e227fc4e85a187c0ab0b12b
7
- data.tar.gz: 8fab755798193a108e834998327d3350995b8f8027bb5476ffbfde35c3efbfa4eeab04e910185f740860dd06e6a551b3ac78bcbdebe488569ac391f4378aacb4
6
+ metadata.gz: ba2d93142dda2dbae2736566e81e5d97e77a05c1fa5ac9acec09a8bf7f37764f2d1e720af4084d0aa980cab197049a32e4ae36c2c8ce83d38c7f23e0f42e2e37
7
+ data.tar.gz: a16b4903505af7c62a79d0936cf09296e211fba49dc6e4557465deb275b8e5f91dac8b306e3555ce3f03e184260d54a1b8cb487e3ead12f841981e09038836a4
data/README.md CHANGED
@@ -22,19 +22,17 @@ You need to activate the module in your `config.rb`, telling the extension how t
22
22
 
23
23
  ```ruby
24
24
  activate :search do
25
+
25
26
  search.resources = ['blog/', 'index.html', 'contactus/index.html']
27
+
26
28
  search.index_path = 'search/lunr-index.json' # defaults to `search.json`
29
+
27
30
  search.fields = {
28
31
  title: {boost: 100, store: true, required: true},
29
32
  content: {boost: 50},
30
33
  url: {index: false, store: true},
31
34
  author: {boost: 30}
32
35
  }
33
- search.before_index = Proc.new do |to_index, to_store, resource|
34
- if author = resource.data.author
35
- to_index[:author] = data.authors[author].name
36
- end
37
- end
38
36
  end
39
37
  ```
40
38
 
@@ -47,18 +45,59 @@ Where `resources` is a list of the beginning of the URL of the resources to inde
47
45
 
48
46
  Note that a special field `id` is included automatically, with an autogenerated identifier to be used as the `ref` for the document.
49
47
 
50
- All fields values are retrieved from the resource `data` (ie its frontmatter), or from the `options` in the `resource.metadata` (i.e., any options specified in a `proxy` page), except for:
48
+ All fields values are retrieved from the resource `data` (i.e. its frontmatter), or from the `options` in the `resource.metadata` (i.e. any options specified in a `proxy` page), except for:
51
49
  - `url` which is the actual resource url
52
50
  - `content` the text extracted from the rendered resource, without including its layout
53
51
 
54
- The `before_index` option accepts a callback that will be executed for each resource, and will be executed with the document to be indexed and the map to be stored, in the `index` and `docs` objects of the output respectively (see below), as well as the resource being processed. You can use this callback to modify either of those, or `throw(:skip)` to skip the resource in question.
52
+ ### Manual index manipulation
55
53
 
56
- You should also `require` the `lunr.min.js` file to your `all.js` file, to actually use the index for search in your website:
54
+ You can fully customise the content to be indexed and stored per resource by defining a `before_index` callback:
57
55
 
58
- ```javascript
59
- //= require lunr.min
56
+ ```ruby
57
+ activate :search do
58
+ search.before_index = Proc.new do |to_index, to_store, resource|
59
+ if author = resource.data.author
60
+ to_index[:author] = data.authors[author].name
61
+ end
62
+ end
63
+ end
64
+ ```
65
+
66
+ This option accepts a callback that will be executed for each resource, and will be executed with the document to be indexed and the map to be stored, in the `index` and `docs` objects of the output respectively (see below), as well as the resource being processed. You can use this callback to modify either of those, or `throw(:skip)` to skip the resource in question.
67
+
68
+ ### Lunr pipeline configuration
69
+
70
+ In some cases, you may want to add new function to the lunr pipeline, both for creating the indexing and then for searching. You can do this by providing a `pipeline` hash with function names and body, for example:
71
+
72
+ ```ruby
73
+ activate :search do
74
+ search.pipeline = {
75
+ tildes: <<-JS
76
+ function(token, tokenIndex, tokens) {
77
+ return token
78
+ .replace('á', 'a')
79
+ .replace('é', 'e')
80
+ .replace('í', 'i')
81
+ .replace('ó', 'o')
82
+ .replace('ú', 'u');
83
+ }
84
+ JS
85
+ }
86
+ end
60
87
  ```
61
88
 
89
+ This will register the `tildes` function in the lunr pipeline and add it when building the index. From the Lunr documentation:
90
+
91
+ > Functions in the pipeline are called with three arguments: the current token being processed; the index of that token in the array of tokens, and the whole list of tokens part of the document being processed. This enables simple unigram processing of tokens as well as more sophisticated n-gram processing.
92
+ >
93
+ > The function should return the processed version of the text, which will in turn be passed to the next function in the pipeline. Returning undefined will prevent any further processing of the token, and that token will not make it to the index.
94
+
95
+ Note that if you add a function to the pipeline, it will also be loaded when de-serialising the index, and lunr will fail with an `Cannot load un-registered function: tildes` error if it has not been re-registered. You can either register them manually, or simply include the following in a `.js.erb` file to be executed __before__ loading the index:
96
+ ```erb
97
+ <%= lunr_js_pipeline %>
98
+ ```
99
+
100
+
62
101
  ## Index file
63
102
 
64
103
  The generated index file contains a JSON object with two properties:
@@ -67,6 +106,13 @@ The generated index file contains a JSON object with two properties:
67
106
 
68
107
  You will typically load the `index` into a lunr index instance, and then use the `docs` map to look up the returned value and present it to the user.
69
108
 
109
+ You should also `require` the `lunr.min.js` file in your main sprockets javascript file to be able to actually load the index:
110
+
111
+ ```javascript
112
+ //= require lunr.min
113
+ ```
114
+
115
+
70
116
  ## Acknowledgments
71
117
 
72
118
  A big thank you to:
@@ -5,12 +5,22 @@ module Middleman
5
5
  class SearchExtension < Middleman::Extension
6
6
  option :resources, [], 'Paths of resources to index'
7
7
  option :fields, {}, 'Fields to index, with their options'
8
- option :before_index, nil, 'Callback receiving (to_index, to_store, resource) to execute before indexing a document'
8
+ option :before_index, nil, 'Callback to execute before indexing a document'
9
9
  option :index_path, 'search.json', 'Index file path'
10
+ option :pipeline, {}, 'Javascript pipeline functions to use in lunr index'
10
11
 
11
12
  def manipulate_resource_list(resources)
12
13
  resources.push Middleman::Sitemap::SearchIndexResource.new(@app.sitemap, @options[:index_path], @options)
13
14
  resources
14
15
  end
16
+
17
+ helpers do
18
+ def lunr_js_pipeline
19
+ # Thanks http://stackoverflow.com/a/20187415/12791
20
+ extensions[:search].options[:pipeline].map do |name, function|
21
+ "lunr.Pipeline.registerFunction(#{function}, '#{name}');"
22
+ end.join("\n")
23
+ end
24
+ end
15
25
  end
16
26
  end
@@ -1,3 +1,5 @@
1
+ # encoding: UTF-8
2
+
1
3
  module Middleman
2
4
  module Sitemap
3
5
  class SearchIndexResource < ::Middleman::Sitemap::Resource
@@ -5,6 +7,7 @@ module Middleman
5
7
  @resources_to_index = options[:resources]
6
8
  @fields = options[:fields]
7
9
  @callback = options[:before_index]
10
+ @pipeline = options[:pipeline]
8
11
  super(store, path)
9
12
  end
10
13
 
@@ -20,12 +23,28 @@ module Middleman
20
23
  # Build js context
21
24
  context = V8::Context.new
22
25
  context.load(File.expand_path('../../../vendor/assets/javascripts/lunr.min.js', __FILE__))
23
- context.eval('lunr.Index.prototype.indexJson = function () {return JSON.stringify(this);}')
26
+ context.eval('lunr.Index.prototype.indexJson = function () {return JSON.stringify(this.toJSON());}')
27
+
28
+ # Register pipeline functions
29
+ pipeline = context.eval('lunr.Pipeline')
30
+ @pipeline.each do |name, function|
31
+ context[name] = context.eval("(#{function})")
32
+ pipeline.registerFunction(context[name], name)
33
+ end
24
34
 
25
35
  # Build lunr based on config
26
36
  lunr = context.eval('lunr')
27
37
  lunr_conf = proc do |this|
38
+
39
+ # Use autogenerated id field as reference
28
40
  this.ref('id')
41
+
42
+ # Add functions to pipeline (just registering them isn't enough)
43
+ @pipeline.each do |name, function|
44
+ this.pipeline.add(context[name])
45
+ end
46
+
47
+ # Define fields with boost
29
48
  @fields.each do |field, opts|
30
49
  next if opts[:index] == false
31
50
  this.field(field, {:boost => opts[:boost]})
@@ -1,3 +1,3 @@
1
1
  module MiddlemanSearch
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: middleman-search
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matías García Isaía