Class: AlgoliaSearchJekyllPush

Inherits:
Jekyll::Command
  • Object
show all
Defined in:
lib/push.rb

Overview

‘jekyll algolia push` command

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.configObject

Returns the value of attribute config.



12
13
14
# File 'lib/push.rb', line 12

def config
  @config
end

.optionsObject

Returns the value of attribute options.



12
13
14
# File 'lib/push.rb', line 12

def options
  @options
end

Class Method Details

.batch_add_items(items, index) ⇒ Object

Push records to the index



166
167
168
169
170
171
172
173
174
175
176
# File 'lib/push.rb', line 166

def batch_add_items(items, index)
  items.each_slice(1000) do |batch|
    Jekyll.logger.info "Indexing #{batch.size} items"
    begin
      index.add_objects!(batch) unless @is_dry_run
    rescue StandardError => error
      display_error(error)
      exit 1
    end
  end
end

.configure_index(index) ⇒ Object

Get index settings



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/push.rb', line 103

def configure_index(index)
  settings = {
    distinct: true,
    attributeForDistinct: 'url',
    attributesForFaceting: %w(tags type title),
    attributesToIndex: %w(
      title h1 h2 h3 h4 h5 h6
      unordered(text)
      unordered(tags)
    ),
    attributesToRetrieve: nil,
    customRanking: [
      'desc(posted_at)',
      'desc(weight.tag_name)',
      'asc(weight.position)'
    ],
    highlightPreTag: '<span class="algolia__result-highlight">',
    highlightPostTag: '</span>'
  }

  # Merge default settings with user custom ones
  if @config['algolia']
    (@config['algolia']['settings'] || []).each do |key, value|
      settings[key.to_sym] = value
    end
  end

  begin
    index.set_settings(settings)
  rescue StandardError => error
    display_error(error)
    exit 1
  end
end

.create_index(index_name) ⇒ Object

Create an index to push our data



158
159
160
161
162
163
# File 'lib/push.rb', line 158

def create_index(index_name)
  set_user_agent_header
  index = Algolia::Index.new(index_name)
  configure_index(index) unless @is_dry_run
  index
end

.custom_hook_excluded_file?(_file) ⇒ Boolean

User custom method to exclude some files when algolia.excluded_files is not enough

Returns:

  • (Boolean)


74
75
76
# File 'lib/push.rb', line 74

def custom_hook_excluded_file?(_file)
  false
end

.display_error(error) ⇒ Object

Display the error in a human-friendly way if possible



139
140
141
142
143
144
145
146
147
148
149
# File 'lib/push.rb', line 139

def display_error(error)
  error_handler = AlgoliaSearchErrorHandler.new
  readable_error = error_handler.readable_algolia_error(error.message)

  if readable_error
    error_handler.display(readable_error)
  else
    Jekyll.logger.error 'Algolia Error: HTTP Error'
    Jekyll.logger.warn error.message
  end
end

.excluded_file?(file) ⇒ Boolean

Check if the file is in the list of excluded files

Returns:

  • (Boolean)


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/push.rb', line 52

def excluded_file?(file)
  excluded = [
    %r{^page([0-9]*)/index\.html}
  ]
  if @config['algolia']
    excluded += (@config['algolia']['excluded_files'] || [])
  end

  # Exclude files explicitly excluded in _config
  excluded.each do |pattern|
    pattern = /#{Regexp.quote(pattern)}/ if pattern.is_a? String
    return true if file.path =~ pattern
  end

  # Call user custom exclude hook on remaining files
  return true if custom_hook_excluded_file?(file)

  false
end

.indexable?(file) ⇒ Boolean

Check if the specified file should be indexed (we exclude static files, robots.txt and custom defined exclusions).

Returns:

  • (Boolean)


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/push.rb', line 33

def indexable?(file)
  return false if file.is_a?(Jekyll::StaticFile)

  basename = File.basename(file.path)
  extname = File.extname(basename)[1..-1]

  # Keep only markdown and html files
  allowed_extensions = %w(html)
  if @config['markdown_ext']
    allowed_extensions += @config['markdown_ext'].split(',')
  end
  return false unless allowed_extensions.include?(extname)

  return false if excluded_file?(file)

  true
end

.init_options(args = [], options = {}, config = {}) ⇒ Object

Init the command with options passed on the command line ‘jekyll algolia push ARG1 ARG2 –OPTION_NAME1 OPTION_VALUE1` config comes from _config.yml



20
21
22
23
24
25
26
27
28
29
# File 'lib/push.rb', line 20

def init_options(args = [], options = {}, config = {})
  args = [] unless args
  @args = args
  @options = options
  @config = config
  @is_verbose = @config['verbose']
  @is_dry_run = @config['dry_run']

  self
end

.init_with_program(_prog) ⇒ Object



14
15
# File 'lib/push.rb', line 14

def init_with_program(_prog)
end

.jekyll_new(config) ⇒ Object

Return a patched version of a Jekyll instance



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/push.rb', line 79

def jekyll_new(config)
  site = Jekyll::Site.new(config)

  # Patched version of `write` that will push to Algolia instead of writing
  # on disk
  def site.write
    items = []
    is_verbose = config['verbose']
    each_site_file do |file|
      next unless AlgoliaSearchJekyllPush.indexable?(file)
      Jekyll.logger.info "Extracting data from #{file.path}" if is_verbose
      new_items = AlgoliaSearchRecordExtractor.new(file).extract
      next if new_items.nil?
      ap new_items if is_verbose

      items += new_items
    end
    AlgoliaSearchJekyllPush.push(items)
  end

  site
end

.push(items) ⇒ Object



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/push.rb', line 178

def push(items)
  checker = AlgoliaSearchCredentialChecker.new(@config)
  checker.assert_valid

  Jekyll.logger.info '=== DRY RUN ===' if @is_dry_run

  # Add items to a temp index, then rename it
  index_name = checker.index_name
  index_name_tmp = "#{index_name}_tmp"
  batch_add_items(items, create_index(index_name_tmp))
  Algolia.move_index(index_name_tmp, index_name) unless @is_dry_run

  Jekyll.logger.info "Indexing of #{items.size} items " \
                     "in #{index_name} done."
end

.set_user_agent_headerObject

Change the User-Agent header to isolate calls from this plugin



152
153
154
155
# File 'lib/push.rb', line 152

def set_user_agent_header
  version = AlgoliaSearchJekyllVersion.to_s
  Algolia.set_extra_header('User-Agent', "Algolia for Jekyll #{version}")
end