290 lines
9.1 KiB
Ruby
290 lines
9.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Jekyll
|
|
module Algolia
|
|
# Single source of truth for access to configuration variables
|
|
module Configurator
|
|
include Jekyll::Algolia
|
|
|
|
@config = {}
|
|
|
|
# Algolia default values
|
|
ALGOLIA_DEFAULTS = {
|
|
'extensions_to_index' => nil,
|
|
'files_to_exclude' => nil,
|
|
'nodes_to_index' => 'p',
|
|
'indexing_batch_size' => 1000,
|
|
'max_record_size' => 10_000,
|
|
'settings' => {
|
|
# Searchable attributes
|
|
'searchableAttributes' => %w[
|
|
title
|
|
headings
|
|
unordered(content)
|
|
collection,categories,tags
|
|
],
|
|
# Custom Ranking
|
|
'customRanking' => [
|
|
'desc(date)',
|
|
'desc(custom_ranking.heading)',
|
|
'asc(custom_ranking.position)'
|
|
],
|
|
'unretrievableAttributes' => [
|
|
'custom_ranking'
|
|
],
|
|
# Highlight
|
|
'attributesToHighlight' => %w[
|
|
title
|
|
headings
|
|
content
|
|
html
|
|
collection
|
|
categories
|
|
tags
|
|
],
|
|
'highlightPreTag' => '<em class="ais-Highlight">',
|
|
'highlightPostTag' => '</em>',
|
|
# Snippet
|
|
'attributesToSnippet' => %w[
|
|
content:55
|
|
],
|
|
'snippetEllipsisText' => '…',
|
|
# Distinct
|
|
'distinct' => true,
|
|
'attributeForDistinct' => 'url',
|
|
# Faceting
|
|
'attributesForFaceting' => %w[
|
|
type
|
|
searchable(collection)
|
|
searchable(categories)
|
|
searchable(tags)
|
|
searchable(title)
|
|
]
|
|
}
|
|
}.freeze
|
|
|
|
# Public: Init the configurator with the Jekyll config
|
|
#
|
|
# config - The config passed by the `jekyll algolia` command. Default to
|
|
# the default Jekyll config
|
|
def self.init(config = nil)
|
|
# Use the default Jekyll configuration if none specified. Silence the
|
|
# warning about no config set
|
|
Logger.silent { config = Jekyll.configuration } if config.nil?
|
|
|
|
@config = config
|
|
|
|
@config = disable_other_plugins(@config)
|
|
|
|
self
|
|
end
|
|
|
|
# Public: Access to the global configuration object
|
|
#
|
|
# This is a method around @config so we can mock it in the tests
|
|
def self.config
|
|
@config
|
|
end
|
|
|
|
# Public: Get the value of a specific Jekyll configuration option
|
|
#
|
|
# key - Key to read
|
|
#
|
|
# Returns the value of this configuration option, nil otherwise
|
|
def self.get(key)
|
|
config[key]
|
|
end
|
|
|
|
# Public: Get the value of a specific Algolia configuration option, or
|
|
# revert to the default value otherwise
|
|
#
|
|
# key - Algolia key to read
|
|
#
|
|
# Returns the value of this option, or the default value
|
|
def self.algolia(key)
|
|
config = get('algolia') || {}
|
|
value = config[key] || ALGOLIA_DEFAULTS[key]
|
|
|
|
# No value found but we have a method to define the default value
|
|
if value.nil? && respond_to?("default_#{key}")
|
|
value = send("default_#{key}")
|
|
end
|
|
|
|
value
|
|
end
|
|
|
|
# Public: Return the application id
|
|
#
|
|
# Will first try to read the ENV variable, and fallback to the one
|
|
# configured in Jekyll config
|
|
def self.application_id
|
|
ENV['ALGOLIA_APPLICATION_ID'] || algolia('application_id')
|
|
end
|
|
|
|
# Public: Return the api key
|
|
#
|
|
# Will first try to read the ENV variable. Will otherwise try to read the
|
|
# _algolia_api_key file in the Jekyll folder
|
|
def self.api_key
|
|
# Alway taking the ENV variable first
|
|
return ENV['ALGOLIA_API_KEY'] if ENV['ALGOLIA_API_KEY']
|
|
|
|
# Reading from file on disk otherwise
|
|
source_dir = get('source')
|
|
if source_dir
|
|
api_key_file = File.join(source_dir, '_algolia_api_key')
|
|
if File.exist?(api_key_file) && File.size(api_key_file).positive?
|
|
return File.open(api_key_file).read.strip
|
|
end
|
|
end
|
|
|
|
nil
|
|
end
|
|
|
|
# Public: Return the index name
|
|
#
|
|
# Will first try to read the ENV variable, and fallback to the one
|
|
# configured in Jekyll config
|
|
def self.index_name
|
|
ENV['ALGOLIA_INDEX_NAME'] || algolia('index_name')
|
|
end
|
|
|
|
# Public: Return the name of the index used to store the object ids
|
|
def self.index_object_ids_name
|
|
"#{index_name}_object_ids"
|
|
end
|
|
|
|
# Public: Get the index settings
|
|
#
|
|
# This will be a merge of default settings and the one defined in the
|
|
# _config.yml file
|
|
def self.settings
|
|
user_settings = algolia('settings') || {}
|
|
ALGOLIA_DEFAULTS['settings'].merge(user_settings)
|
|
end
|
|
|
|
# Public: Check that all credentials are set
|
|
#
|
|
# Returns true if everything is ok, false otherwise. Will display helpful
|
|
# error messages for each missing credential
|
|
def self.assert_valid_credentials
|
|
checks = %w[application_id index_name api_key]
|
|
checks.each do |check|
|
|
if send(check.to_sym).nil?
|
|
Logger.known_message("missing_#{check}")
|
|
return false
|
|
end
|
|
end
|
|
|
|
true
|
|
end
|
|
|
|
# Public: Setting a default values to index only html and markdown files
|
|
#
|
|
# Markdown files can have many different extensions. We keep the one
|
|
# defined in the Jekyll config
|
|
def self.default_extensions_to_index
|
|
markdown_ext = get('markdown_ext') || ''
|
|
['html'] + markdown_ext.split(',')
|
|
end
|
|
|
|
# Public: Setting a default value to ignore index.html/index.md files in
|
|
# the root
|
|
#
|
|
# Chances are high that the main page is not worthy of indexing (it can be
|
|
# the list of the most recent posts or some landing page without much
|
|
# content). We ignore it by default.
|
|
#
|
|
# User can still add it by manually specifying a `files_to_exclude` to an
|
|
# empty array
|
|
def self.default_files_to_exclude
|
|
extensions_to_index.map do |extension|
|
|
"index.#{extension}"
|
|
end
|
|
end
|
|
|
|
# Public: Returns true if the command is run in verbose mode
|
|
#
|
|
# When set to true, more logs will be displayed
|
|
def self.verbose?
|
|
value = get('verbose')
|
|
return true if value == true
|
|
false
|
|
end
|
|
|
|
# Public: Returns true if the command is run in verbose mode
|
|
#
|
|
# When set to true, no indexing operations will be sent to the API
|
|
def self.dry_run?
|
|
value = get('dry_run')
|
|
return true if value == true
|
|
false
|
|
end
|
|
|
|
# Public: Returns true if the command should always update the settings
|
|
#
|
|
# When set to true, the index settings will always be updated, no matter
|
|
# if they've been modified or not
|
|
def self.force_settings?
|
|
value = get('force_settings')
|
|
return true if value == true
|
|
false
|
|
end
|
|
|
|
# Public: Returns a list of extensions to index
|
|
#
|
|
# Will use default values or read the algolia.extensions_to_index key.
|
|
# Accepts both an array or a comma-separated list
|
|
def self.extensions_to_index
|
|
extensions = algolia('extensions_to_index')
|
|
return [] if extensions.nil?
|
|
extensions = extensions.split(',') if extensions.is_a? String
|
|
extensions
|
|
end
|
|
|
|
# Public: Disable features from other Jekyll plugins that might interfere
|
|
# with the indexing
|
|
# Note that if other jekyll plugins are defined as part of the
|
|
# :jekyll_plugins group in the Gemfile, we might be able to override them
|
|
# using .load_overwrites in .load_overwrites in jekyll-algolia.rb.
|
|
# If they are simply required in Gemfile, then we might need to revert
|
|
# their values to nil values from here
|
|
def self.disable_other_plugins(config)
|
|
# Disable archive pages from jekyll-archives
|
|
config['jekyll-archives'] = nil
|
|
|
|
# Disable pagination from jekyll-paginate
|
|
config['paginate'] = nil
|
|
|
|
# Disable pagination for jekyll-paginate-v2
|
|
config['pagination'] = {} unless config['pagination'].is_a?(Hash)
|
|
config['pagination']['enabled'] = false
|
|
|
|
# Disable autopages for jekyll-paginate-v2
|
|
config['autopages'] = {} unless config['autopages'].is_a?(Hash)
|
|
config['autopages']['enabled'] = false
|
|
|
|
# Disable tags from jekyll-tagging
|
|
config['tag_page_dir'] = nil
|
|
config['tag_page_layout'] = nil
|
|
|
|
config
|
|
end
|
|
|
|
# Public: Check for any deprecated config option and warn the user
|
|
def self.warn_of_deprecated_options
|
|
# indexing_mode is no longer used
|
|
return if algolia('indexing_mode').nil?
|
|
|
|
# rubocop:disable Metrics/LineLength
|
|
Logger.log('I:')
|
|
Logger.log('W:[jekyll-algolia] You are using the algolia.indexing_mode option which has been deprecated in v1.1')
|
|
Logger.log('I: Indexing is now always using an atomic diff algorithm.')
|
|
Logger.log('I: This option is no longer necessary, you can remove it from your _config.yml')
|
|
Logger.log('I:')
|
|
# rubocop:enable Metrics/LineLength
|
|
end
|
|
end
|
|
end
|
|
end
|