Class: Jekyll::Algolia::Site

Inherits:
Site
  • Object
show all
Defined in:
lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb

Overview

A Jekyll::Site subclass that overrides process from the parent class to create JSON records out of rendered documents and push those records to Algolia instead of writing files to disk.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#collections=(value) ⇒ Object (writeonly)

We expose a way to reset the collection, as it will be needed in the tests



11
12
13
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 11

def collections=(value)
  @collections = value
end

#original_site_filesObject (readonly)

Returns the value of attribute original_site_files.



13
14
15
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 13

def original_site_files
  @original_site_files
end

Instance Method Details

#indexable_item_countObject

Public: Return the number of pages/documents to index



41
42
43
44
45
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 41

def indexable_item_count
  count = @pages.length
  @collections.each_value { |collection| count += collection.docs.length }
  count
end

#indexable_list(items) ⇒ Object

Public: Filtering a list of items to only keep the one that are indexable.

items - List of Pages/Documents

Note: It also sets the layout to nil, to further speed up the rendering



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 68

def indexable_list(items)
  new_list = []
  items.each do |item|
    next unless FileBrowser.indexable?(item)

    item.data = {} if item.data.nil?
    item.data['layout'] = nil
    new_list << item
  end
  new_list
end

#init_rendering_progress_barObject

Public: Init the rendering progress bar, incrementing it for each rendered item

This uses Jekyll post_render hooks, listening to both pages and documents



52
53
54
55
56
57
58
59
60
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 52

def init_rendering_progress_bar
  progress_bar = ProgressBar.create(
    total: indexable_item_count,
    format: 'Rendering to HTML (%j%%) |%B|'
  )
  Jekyll::Hooks.register [:pages, :documents], :post_render do
    progress_bar.increment
  end
end

#keep_only_indexable_filesObject

Public: Removing non-indexable Pages, Posts and Documents from the internals



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 82

def keep_only_indexable_files
  @original_site_files = {
    pages: @pages,
    collections: @collections,
    static_files: @static_files
  }

  @pages = indexable_list(@pages)

  # Applying to each collections
  @collections.each_value do |collection|
    collection.docs = indexable_list(collection.docs)
  end

  # Remove all static files
  @static_files = []
end

#processObject

Public: Overwriting the parent method

This will prepare the website, gathering all files, excluding the one we don’t need to index, then render them (converting to HTML), the finally calling ‘push` to push to Algolia



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 20

def process
  # Default Jekyll preflight
  reset
  read
  generate

  # Removing all files that won't be indexed, so we don't waste time
  # rendering them
  keep_only_indexable_files

  # Starting the rendering progress bar
  init_rendering_progress_bar

  # Converting them to HTML
  render

  # Pushing them Algolia
  push
end

#pushObject

Public: Extract records from every file and index them



101
102
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
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/jekyll/algolia/overwrites/jekyll-algolia-site.rb', line 101

def push
  records = []
  files = []
  progress_bar = ProgressBar.create(
    total: indexable_item_count,
    format: 'Extracting records (%j%%) |%B|'
  )
  each_site_file do |file|
    # Even if we cleared the list of documents/pages beforehand, some
    # files might still sneak up to this point (like static files added to
    # a collection directory), so we check again if they can really be
    # indexed.
    next unless FileBrowser.indexable?(file)

    path = FileBrowser.relative_path(file.path)

    Logger.verbose("I:Extracting records from #{path}")
    file_records = Extractor.run(file)

    files << file
    records += file_records

    progress_bar.increment
  end

  # Applying the user hook on the whole list of records
  records = Hooks.apply_all(records, self)

  # Shrinking records to force them to fit under the max record size
  # limit, or displaying an error message if not possible
  max_record_size = Configurator.algolia('max_record_size')
  # We take into account the objectID that will be added in the form of:
  # "objectID": "16cd998991cc40d92402b0b4e6c55e8a"
  object_id_attribute_length = 46
  max_record_size -= object_id_attribute_length
  records.map! do |record|
    Shrinker.fit_to_size(record, max_record_size)
  end

  # Adding a unique objectID to each record
  records.map! do |record|
    Extractor.add_unique_object_id(record)
  end

  Logger.verbose("I:Found #{files.length} files")

  Indexer.run(records)
end