class Bridgetown::Paginate::PaginationIndexer
Performs indexing of the posts or collection documents as well as filtering said collections when requested by the defined filters.
Attributes
cached_index[RW]
Public Class Methods
index_documents_by(all_documents, index_key)
click to toggle source
Create a hash index for all documents based on a key in the document.data table
# File lib/bridgetown-paginate/pagination_indexer.rb, line 20 def self.index_documents_by(all_documents, index_key) # rubocop:todo Metrics/AbcSize return nil if all_documents.nil? return all_documents if index_key.nil? # Where queries are a key/value pair, so grab the first key element index_key = index_key[0] if index_key.is_a?(Array) if (found_index = cached_index.dig(all_documents.object_id, index_key)) return found_index end index = {} all_documents.each do |document| next if document.data.nil? next unless document.data.key?(index_key) next if document.data[index_key].nil? next if document.data[index_key].size <= 0 next if document.data[index_key].to_s.strip.empty? # Only tags and categories come as premade arrays, locale does not, # so convert any data elements that are strings into arrays document_data = document.data[index_key] document_data = document_data.split(%r!;|,!) if document_data.is_a?(String) document_data.each do |key| key = key.to_s.downcase.strip # If the key is a delimetered list of values # (meaning the user didn't use an array but a string with commas) key.split(%r!;|,!).each do |k_split| k_split = k_split.to_s.downcase.strip # Clean whitespace and junk index[k_split.to_s] = [] unless index.key?(k_split) index[k_split.to_s] << document end end end unless cached_index[all_documents.object_id].is_a?(Hash) cached_index[all_documents.object_id] = {} end cached_index[all_documents.object_id][index_key] = index index end
intersect_arrays(first, *rest)
click to toggle source
Creates an intersection (only returns common elements) between multiple arrays
# File lib/bridgetown-paginate/pagination_indexer.rb, line 67 def self.intersect_arrays(first, *rest) return nil if first.nil? return nil if rest.nil? intersect = first rest.each do |item| return [] if item.nil? intersect &= item end intersect end
read_config_value_and_filter_documents( config, config_key, documents, source_documents )
click to toggle source
Filters documents based on a keyed source_documents hash of indexed documents and performs a intersection of the two sets. Returns only documents that are common between all collections
# File lib/bridgetown-paginate/pagination_indexer.rb, line 84 def self.read_config_value_and_filter_documents( config, config_key, documents, source_documents ) return nil if documents.nil? # If the source is empty then simply don't do anything return nil if source_documents.nil? return documents if config.nil? return documents unless config.key?(config_key) return documents if config[config_key].nil? # Get the filter values from the config (this is the cat/tag/locale # values that should be filtered on) config_value = config[config_key] # Use the second key/value element if it's a "where query" config_value = config_value[1] if config_key == "where_query" # If we're dealing with a delimitered string instead of an array then # let's be forgiving config_value = config_value.split(%r!;|,!) if config_value.is_a?(String) # Now for all filter values for the config key, let's remove all items # from the documents that aren't common for all collections that the # user wants to filter on # TODO: right now this is an "AND" operation if multiple keys are present. # Should offer the ability to do an OR operation instead. config_value.each do |key| key = key.to_s.downcase.strip documents = PaginationIndexer.intersect_arrays(documents, source_documents[key]) end # The fully filtered final document list documents end