Class: Middleman::Sitemap::SearchIndexResource

Inherits:
Resource
  • Object
show all
Defined in:
lib/middleman-search/search-index-resource.rb

Instance Method Summary collapse

Constructor Details

#initialize(store, path, options) ⇒ SearchIndexResource

Returns a new instance of SearchIndexResource.



6
7
8
9
10
11
12
13
14
15
# File 'lib/middleman-search/search-index-resource.rb', line 6

def initialize(store, path, options)
  @resources_to_index = options[:resources]
  @fields = options[:fields]
  @callback = options[:before_index]
  @pipeline = options[:pipeline]
  @cache_index = options[:cache]
  @language = options[:language]
  @lunr_dirs = options[:lunr_dirs] + [File.expand_path("../../../vendor/assets/javascripts/", __FILE__)]
  super(store, path)
end

Instance Method Details

#binary?Boolean

Returns:

  • (Boolean)


110
111
112
# File 'lib/middleman-search/search-index-resource.rb', line 110

def binary?
  false
end

#build_indexObject



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/middleman-search/search-index-resource.rb', line 33

def build_index
  # Build js context
  context = V8::Context.new
  context.load(lunr_resource('lunr.js'))

  if @language != 'en' # English is the default
    context.load(lunr_resource("lunr.stemmer.support.js"))
    context.load(lunr_resource("lunr.#{@language}.js"))
    lunr_lang = context.eval("lunr.#{@language}")
  end

  context.eval('lunr.Index.prototype.indexJson = function () {return JSON.stringify(this.toJSON());}')

  # Register pipeline functions
  pipeline = context.eval('lunr.Pipeline')
  @pipeline.each do |name, function|
    context[name] = context.eval("(#{function})")
    pipeline.registerFunction(context[name], name)
  end

  # Build lunr based on config
  lunr = context.eval('lunr')
  lunr_conf = proc do |this|

    # Use autogenerated id field as reference
    this.ref('id')

    # Add functions to pipeline (just registering them isn't enough)
    @pipeline.each do |name, function|
      this.pipeline.add(context[name])
    end

    # Define fields with boost
    this.use(lunr_lang) if @language != 'en'
    @fields.each do |field, opts|
      next if opts[:index] == false
      this.field(field, {:boost => opts[:boost]})
    end
  end

  # Get lunr index
  index = lunr.call(lunr_conf)

  # Ref to resource map
  store = Hash.new

  # Iterate over all resources and build index
  @app.sitemap.resources.each_with_index do |resource, id|
    begin
      catch(:skip) do
        next if resource.data['index'] == false
        next unless @resources_to_index.any? {|whitelisted| resource.path.start_with? whitelisted }

        to_index = Hash.new
        to_store = Hash.new

        @fields.each do |field, opts|
          value = value_for(resource, field, opts)
          throw(:skip) if value.blank? && opts[:required]
          to_index[field] = value unless opts[:index] == false
          to_store[field] = value if opts[:store]
        end

        @callback.call(to_index, to_store, resource) if @callback

        index.add(to_index.merge(id: id))
        store[id] = to_store
      end
    rescue => ex
      @app.logger.warn "Error processing resource for index: #{resource.path}\n#{ex}\n #{ex.backtrace.join("\n ")}"
    end
  end

  # Generate JSON output
  "{\"index\": #{index.indexJson()}, \"docs\": #{store.to_json}}"
end

#get_source_fileObject



21
22
23
# File 'lib/middleman-search/search-index-resource.rb', line 21

def get_source_file
  path
end

#ignored?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/middleman-search/search-index-resource.rb', line 114

def ignored?
  false
end

#render(opts = {}, locs = {}) ⇒ Object



25
26
27
28
29
30
31
# File 'lib/middleman-search/search-index-resource.rb', line 25

def render(opts={}, locs={})
  if @cache_index
    @index ||= build_index
  else
    build_index
  end
end

#template?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'lib/middleman-search/search-index-resource.rb', line 17

def template?
  false
end

#value_for(resource, field, opts = {}) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/middleman-search/search-index-resource.rb', line 118

def value_for(resource, field, opts={})
  case field.to_s
  when 'content'

    html = resource.render( { :layout => false }, { :current_path => resource.path } )
    Nokogiri::HTML(html).xpath("//text()").text
  when 'url'
    resource.url
  else
    value = resource.data.send(field) || resource..fetch(:options, {}).fetch(field, nil)
    value ? Array(value).compact.join(" ") : nil
  end
end