class Jekyll::Archives::Archives
Constants
- DATE_ATTRS
- DEFAULTS
- LEGACY_ATTRS
Map between the front matter attribute and names used by jekyll-archive
Public Class Methods
# File lib/jekyll-archives.rb, line 35 def initialize(config = {}) archives_config = config.fetch("jekyll-archives", {}) if archives_config.is_a?(Hash) @config = Utils.deep_merge_hashes(DEFAULTS, archives_config) else @config = nil Jekyll.logger.warn "Archives:", "Expected a hash but got #{archives_config.inspect}" Jekyll.logger.warn "", "Archives will not be generated for this site." end @enabled = @config && @config["enabled"] @post_attr_hash = {} end
Public Instance Methods
If the permalink is a hash of value => template, check if it isn't disabled.
# File lib/jekyll-archives.rb, line 93 def attr_title_enabled?(attr, value) permalinks = @config.dig('permalinks', attr) if permalinks.is_a?(Hash) !!permalinks.dig(value) else true end end
Return the front matter attributes to archive by, using the legacy names unless specified and leaving out the date attributes.
# File lib/jekyll-archives.rb, line 188 def attrs return LEGACY_ATTRS.keys unless @enabled.is_a? Array @attrs ||= @enabled - DATE_ATTRS end
Check if we have combined archives
# File lib/jekyll-archives.rb, line 205 def combined? @config['combined'].is_a?(Hash) end
Custom `post_attr_hash` method for days
# File lib/jekyll-archives.rb, line 220 def days(month_posts) date_attr_hash(month_posts, "%d") end
Checks if archive type is enabled in config
# File lib/jekyll-archives.rb, line 195 def enabled?(archive) @enabled == true || @enabled == "all" || (@enabled.is_a?(Array) && @enabled.include?(archive)) end
# File lib/jekyll-archives.rb, line 48 def generate(site) return if @config.nil? @site = site @posts = site.posts @archives = [] @site.config["jekyll-archives"] = @config read @site.pages.concat(@archives) @site.config["archives"] = @archives unless group? end
Checks if we want grouped archives
# File lib/jekyll-archives.rb, line 200 def group? @config['group'] end
Custom `post_attr_hash` method for months
# File lib/jekyll-archives.rb, line 215 def months(year_posts) date_attr_hash(year_posts, "%m") end
Read archive data from posts
# File lib/jekyll-archives.rb, line 64 def read read_combined if combined? read_attrs read_dates read_types if group? end
Read and group by attributes, using the legacy names when needed.
# File lib/jekyll-archives.rb, line 73 def read_attrs attrs.each do |attr| post_attr_hash(attr).each do |title, posts| attr = LEGACY_ATTRS[attr] if LEGACY_ATTRS[attr] next unless attr_title_enabled? attr, title @archives << Archive.new(@site, title, attr, posts) next unless group? @site.config['archives'] ||= {} @site.config['archives'][attr] ||= [] @site.config['archives'][attr] << @archives.last end end end
Archive
posts by a combination of attributes.
# File lib/jekyll-archives.rb, line 104 def read_combined # We can have many combination archives @config['combined'].each do |type, combined| # This is an empty map so we can have all keys on the result empty_combination = Hash[combined.map{|k| [k,nil]}] # We collect all posts @posts.docs.map do |post| # Array of Jekyll::Document and Hash of values, some may be # empty. [ post, empty_combination.merge(**post.data.slice(*combined)) ] end.select do |combination| # We skip Documents that don't have any of the attributes combination.last.none? do |_, e| # TODO: Move to its own method e.nil? || (e.respond_to?(:empty?) && e.empty?) || (e.respond_to?(:blank?) && e.blank?) || (e.respond_to?(:zero?) && e.zero?) end end.map do |post, data| # Since the values can be Arrays, we'll generate all # combinations data.values.reduce do |memo, value| # XXX: Ensure value is an Array, it could be a String or other # value. (memo.is_a?(Array) ? memo : [memo]).product([value].flatten) end.map(&:flatten).map do |v| # Recreate a Hash of attribute and single value for each # combination data.keys.zip(v) end.map do |hash| # Recreate the first collection of Document and Hash for # each combination. [ post, Hash[hash] ] end end.flatten(1).group_by(&:last).transform_values(&:flatten).transform_values do |v| # Create groups by value combinations and select only # Documents v.select do |p| p.is_a? Jekyll::Document end end.each do |combination, posts| # Then create Archives for them. archive = Archive.new(@site, combination, type, posts) @archives << archive next unless group? @site.config['archives'] ||= {} @site.config['archives'][type] ||= [] @site.config['archives'][type] << archive end end end
# File lib/jekyll-archives.rb, line 158 def read_dates years.each do |year, y_posts| append_enabled_date_type({ :year => year }, "year", y_posts) months(y_posts).each do |month, m_posts| append_enabled_date_type({ :year => year, :month => month }, "month", m_posts) days(m_posts).each do |day, d_posts| append_enabled_date_type({ :year => year, :month => month, :day => day }, "day", d_posts) end end end end
Generates Archives
by Archive
type
# File lib/jekyll-archives.rb, line 171 def read_types @config['enabled'].each do |type| type = LEGACY_ATTRS[type] if LEGACY_ATTRS[type] @archives << Archive.new(@site, type, 'group', @site.config['archives'][type].map(&:posts).flatten.uniq) end return unless combined? @config['combined'].each do |type, _| @archives << Archive.new(@site, type, 'group', @site.config['archives'][type].map(&:posts).flatten.uniq) end end
Custom `post_attr_hash` method for years
# File lib/jekyll-archives.rb, line 210 def years date_attr_hash(@posts.docs, "%Y") end
Private Instance Methods
Initialize a new Archive
page and append to base array if the associated date `type` has been enabled by configuration.
meta - A Hash of the year / month / day as applicable for date. type - The type of date archive. posts - The array of posts that belong in the date archive.
# File lib/jekyll-archives.rb, line 232 def append_enabled_date_type(meta, type, posts) @archives << Archive.new(@site, meta, type, posts) if enabled?(type) end
Custom `post_attr_hash` for date type archives.
posts - Array of posts to be considered for archiving. id - String used to format post date via `Time.strptime` e.g. %Y, %m, etc.
# File lib/jekyll-archives.rb, line 240 def date_attr_hash(posts, id) hash = Hash.new { |hsh, key| hsh[key] = [] } posts.each { |post| hash[post.date.strftime(id)] << post } hash.each_value { |posts| posts.sort!.reverse! } hash end
Custom `post_attr_hash` to group by any attribute
# File lib/jekyll-archives.rb, line 248 def post_attr_hash(post_attr) @post_attr_hash[post_attr] ||= begin hash = Hash.new { |h, key| h[key] = [] } @site.posts.docs.each do |p| d = p.data[post_attr] next if d.nil? if d.respond_to? :each d.each { |t| hash[t] << p } else hash[d.to_s] << p end end hash.each_value { |posts| posts.sort!.reverse! } hash end end