This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
module AllCollectionsHooks
|
||||
class APage
|
||||
attr_reader :content, :data, :date, :description, :destination, :draft, :excerpt, :ext, :extname, :href,
|
||||
:label, :last_modified, :layout, :origin, :path, :relative_path, :tags, :title, :type, :url
|
||||
|
||||
def initialize(obj, origin)
|
||||
@origin = origin
|
||||
data_field_init obj
|
||||
obj_field_init obj
|
||||
@draft = Jekyll::Draft.draft? obj
|
||||
@href = @url if @href.nil?
|
||||
# @href = "/#{@href}" if @origin == 'individual_page'
|
||||
@href = "#{@href}index.html" if @href.end_with? '/'
|
||||
@name = File.basename(@href)
|
||||
@title = if @data&.key?('title')
|
||||
@data['title']
|
||||
elsif obj.respond_to?(:title)
|
||||
obj.title
|
||||
else
|
||||
"<code>#{@href}</code>"
|
||||
end
|
||||
rescue StandardError => e
|
||||
JekyllSupport.error_short_trace(@logger, e)
|
||||
# JekyllSupport.warn_short_trace(@logger, e)
|
||||
end
|
||||
|
||||
def to_s
|
||||
@label || @date.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def data_field_init(obj)
|
||||
return unless obj.respond_to? :data
|
||||
|
||||
@data = obj.data
|
||||
|
||||
@categories = @data['categories'] if @data.key? 'categories'
|
||||
@date = (@data['date'].to_date if @data&.key?('date')) || Date.today
|
||||
@description = @data['description'] if @data.key? 'description'
|
||||
@excerpt = @data['excerpt'] if @data.key? 'excerpt'
|
||||
@ext ||= @data['ext'] if @data.key? 'ext'
|
||||
@last_modified = @data['last_modified'] || @data['last_modified_at'] || @date
|
||||
@last_modified_field = case @data
|
||||
when @data.key?('last_modified')
|
||||
'last_modified'
|
||||
when @data.key?('last_modified_at')
|
||||
'last_modified_at'
|
||||
end
|
||||
@layout = @data['layout'] if @data.key? 'layout'
|
||||
@tags = @data['tags'] if @data.key? 'tags'
|
||||
end
|
||||
|
||||
def obj_field_init(obj)
|
||||
@content = obj.content if obj.respond_to? :content
|
||||
|
||||
# TODO: What _config.yml setting should be passed to destination()?
|
||||
@destination = obj.destination('') if obj.respond_to? :destination
|
||||
@ext = obj.extname
|
||||
@extname = @ext # For compatibility with previous versions of all_collections
|
||||
@label = obj.collection.label if obj.respond_to?(:collection) && obj.collection.respond_to?(:label)
|
||||
@path = obj.path if obj.respond_to? :path
|
||||
@relative_path = obj.relative_path if obj.respond_to? :relative_path
|
||||
@type = obj.type if obj.respond_to? :type
|
||||
@url = obj.url
|
||||
@url = "#{@url}index.html" if @url.end_with? '/'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
module JekyllAllCollections
|
||||
module AllCollectionsHooks
|
||||
class << self
|
||||
attr_accessor :logger
|
||||
end
|
||||
@logger = PluginMetaLogger.instance.new_logger(self, PluginMetaLogger.instance.config)
|
||||
|
||||
# No, all_collections is not defined for this hook
|
||||
# Jekyll::Hooks.register(:site, :after_init, priority: :normal) do |site|
|
||||
# defined_msg = ::AllCollectionsHooks.all_collections_defined?(site)
|
||||
# @logger.debug { "Jekyll::Hooks.register(:site, :after_init: #{defined_msg}" }
|
||||
# end
|
||||
|
||||
# Creates a `Array[APage]` property called site.all_collections if it does not already exist.
|
||||
# The array is available from :site, :pre_render onwards
|
||||
# Each `APage` entry is one document or page.
|
||||
Jekyll::Hooks.register(:site, :post_read, priority: :normal) do |site|
|
||||
@site = site
|
||||
unless site.class.method_defined? :all_collections
|
||||
defined_msg = ::AllCollectionsHooks.all_collections_defined? site
|
||||
@logger.debug { "Jekyll::Hooks.register(:site, :post_read, :normal: #{defined_msg}" }
|
||||
::AllCollectionsHooks.compute(site) if !@site.class.method_defined?(:all_documents) || @site.all_documents.nil?
|
||||
end
|
||||
rescue StandardError => e
|
||||
JekyllSupport.error_short_trace(@logger, e)
|
||||
# JekyllSupport.warn_short_trace(@logger, e)
|
||||
end
|
||||
|
||||
# Yes, all_collections is defined for this hook
|
||||
# Jekyll::Hooks.register(:site, :post_read, priority: :low) do |site|
|
||||
# defined_msg = ::AllCollectionsHooks.all_collections_defined?(site)
|
||||
# @logger.debug { "Jekyll::Hooks.register(:site, :post_read, :low: #{defined_msg}" }
|
||||
# rescue StandardError => e
|
||||
# JekyllSupport.error_short_trace(@logger, e)
|
||||
# # JekyllSupport.warn_short_trace(@logger, e)
|
||||
# end
|
||||
|
||||
# Yes, all_collections is defined for this hook
|
||||
# Jekyll::Hooks.register(:site, :post_read, priority: :normal) do |site|
|
||||
# defined_msg = ::AllCollectionsHooks.all_collections_defined?(site)
|
||||
# @logger.debug { "Jekyll::Hooks.register(:site, :post_read, :normal: #{defined_msg}" }
|
||||
# rescue StandardError => e
|
||||
# JekyllSupport.error_short_trace(@logger, e)
|
||||
# # JekyllSupport.warn_short_trace(@logger, e)
|
||||
# end
|
||||
|
||||
# Yes, all_collections is defined for this hook
|
||||
# Jekyll::Hooks.register(:site, :pre_render, priority: :normal) do |site, _payload|
|
||||
# defined_msg = ::AllCollectionsHooks.all_collections_defined?(site)
|
||||
# @logger.debug { "Jekyll::Hooks.register(:site, :pre_render: #{defined_msg}" }
|
||||
# rescue StandardError => e
|
||||
# JekyllSupport.error_short_trace(@logger, e)
|
||||
# # JekyllSupport.warn_short_trace(@logger, e)
|
||||
# end
|
||||
end
|
||||
end
|
||||
|
||||
PluginMetaLogger.instance.logger.info do
|
||||
"Loaded AllCollectionsHooks v#{JekyllPluginSupportVersion::VERSION} :site, :pre_render, :normal hook plugin."
|
||||
end
|
||||
Liquid::Template.register_filter(JekyllAllCollections::AllCollectionsHooks)
|
||||
@@ -0,0 +1,48 @@
|
||||
# Insert the url of a Jekyll::Page into each LruFile instance,
|
||||
# along with the Page reference
|
||||
# todo: replace references to url and :url with reverse_url and :reverse_url
|
||||
LruFile = Struct.new(:url, :page) do
|
||||
include SendChain
|
||||
|
||||
def <=>(other)
|
||||
url <=> other.url
|
||||
end
|
||||
|
||||
def href
|
||||
url.reverse
|
||||
end
|
||||
end
|
||||
|
||||
# Matches suffixes of an array of urls
|
||||
# Converts suffixes to prefixes
|
||||
class SortedLruFiles
|
||||
attr_reader :msbs
|
||||
|
||||
def initialize
|
||||
@msbs = MSlinnBinarySearch.new %i[url start_with?]
|
||||
end
|
||||
|
||||
# @param apages [Array[APage]]
|
||||
def add_pages(apages)
|
||||
apages.each { |apage| insert apage.href, apage }
|
||||
@msbs.enable_search
|
||||
end
|
||||
|
||||
def enable_search
|
||||
@msbs.enable_search
|
||||
end
|
||||
|
||||
def find(suffix)
|
||||
@msbs.find suffix
|
||||
end
|
||||
|
||||
def insert(url, file)
|
||||
lru_file = LruFile.new(url.reverse, file)
|
||||
lru_file.new_chain [:url, %i[start_with? placeholder]]
|
||||
@msbs.insert(lru_file)
|
||||
end
|
||||
|
||||
def select(suffix)
|
||||
@msbs.select_pages suffix
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,50 @@
|
||||
module AllCollectionsHooks
|
||||
class << self
|
||||
attr_accessor :all_collections, :all_documents, :everything, :sorted_lru_files
|
||||
end
|
||||
|
||||
# @sort_by = ->(apages, criteria) { [apages.sort(criteria)] } # todo delete this
|
||||
|
||||
# @return [String] indicating if :all_collections is defined or not
|
||||
def self.all_collections_defined?(site)
|
||||
"site.all_collections #{site.class.method_defined?(:all_collections) ? 'IS' : 'IS NOT'} defined"
|
||||
end
|
||||
|
||||
# Create Array of AllCollectionsHooks::APage from objects
|
||||
# @param objects [Array] An array of Jekyll::Document, Jekyll::Page or file names
|
||||
# @param origin [String] Indicates type of objects being passed
|
||||
def self.apages_from_objects(objects, origin)
|
||||
pages = []
|
||||
objects.each do |object|
|
||||
page = APage.new(object, origin)
|
||||
pages << page unless page.data['exclude_from_all'] || page.path == 'redirect.html'
|
||||
end
|
||||
pages
|
||||
end
|
||||
|
||||
# Called by early, high-priority hook.
|
||||
# Computes site.all_collections, site.all_documents, site.everything, and site.sorted_lru_files
|
||||
def self.compute(site)
|
||||
site.class.module_eval { attr_accessor :all_collections, :all_documents, :everything, :sorted_lru_files }
|
||||
|
||||
documents = site.collections
|
||||
.values
|
||||
.map { |x| x.class.method_defined?(:docs) ? x.docs : x }
|
||||
.flatten
|
||||
.compact
|
||||
@all_collections = AllCollectionsHooks.apages_from_objects(documents, 'collection')
|
||||
@all_documents = @all_collections +
|
||||
AllCollectionsHooks.apages_from_objects(site.pages, 'individual_page')
|
||||
@everything = @all_documents +
|
||||
AllCollectionsHooks.apages_from_objects(site.static_files, 'static_file')
|
||||
@sorted_lru_files = SortedLruFiles.new.add_pages @everything
|
||||
|
||||
site.all_collections = @all_collections
|
||||
site.all_documents = @all_documents
|
||||
site.everything = @everything
|
||||
site.sorted_lru_files = @sorted_lru_files
|
||||
rescue StandardError => e
|
||||
JekyllSupport.error_short_trace(::JekyllAllCollections::AllCollectionsHooks.logger, e)
|
||||
# JekyllSupport.warn_short_trace(::JekyllAllCollections::AllCollectionsHooks.logger, e)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user