class Jekyll::Collection
Attributes
Public Class Methods
Source
# File lib/jekyll/collection.rb, line 14 def initialize(site, label) @site = site @label = sanitize_label(label) @metadata = extract_metadata end
Create a new Collection
.
site - the site to which this collection belongs. label - the name of the collection
Returns nothing.
Public Instance Methods
Source
# File lib/jekyll/collection.rb, line 131 def collection_dir(*files) return directory if files.empty? site.in_source_dir(container, relative_directory, *files) end
The full path to the directory containing the collection, with
optional subpaths.
*files - (optional) any other path pieces relative to the
directory to append to the path
Returns a String containing th directory name where the collection
is stored on the filesystem.
Source
# File lib/jekyll/collection.rb, line 117 def directory @directory ||= site.in_source_dir( File.join(container, relative_directory) ) end
The full path to the directory containing the collection.
Returns a String containing th directory name where the collection
is stored on the filesystem.
Source
# File lib/jekyll/collection.rb, line 24 def docs @docs ||= [] end
Fetch the Documents in this collection. Defaults to an empty array if no documents have been read in.
Returns an array of Jekyll::Document
objects.
Source
# File lib/jekyll/collection.rb, line 76 def entries return [] unless exists? @entries ||= begin collection_dir_slash = "#{collection_dir}/" Utils.safe_glob(collection_dir, ["**", "*"], File::FNM_DOTMATCH).map do |entry| entry[collection_dir_slash] = "" entry end end end
All the entries in this collection.
Returns an Array of file paths to the documents in this collection
relative to the collection's directory
Source
# File lib/jekyll/collection.rb, line 151 def entry_filter @entry_filter ||= Jekyll::EntryFilter.new(site, relative_directory) end
The entry filter for this collection. Creates an instance of Jekyll::EntryFilter
.
Returns the instance of Jekyll::EntryFilter
for this collection.
Source
# File lib/jekyll/collection.rb, line 143 def exists? File.directory?(directory) && !entry_filter.symlink?(directory) end
Checks whether the directory “exists” for this collection. The directory must exist on the filesystem and must not be a symlink
if in safe mode.
Returns false if the directory doesn’t exist or if it’s a symlink
and we're in safe mode.
Source
# File lib/jekyll/collection.rb, line 203 def extract_metadata if site.config["collections"].is_a?(Hash) site.config["collections"][label] || {} else {} end end
Extract options for this collection from the site configuration.
Returns the metadata for this collection
Source
# File lib/jekyll/collection.rb, line 50 def files @files ||= [] end
Fetch the static files in this collection. Defaults to an empty array if no static files have been read in.
Returns an array of Jekyll::StaticFile
objects.
Source
# File lib/jekyll/collection.rb, line 92 def filtered_entries return [] unless exists? @filtered_entries ||= Dir.chdir(directory) do entry_filter.filter(entries).reject do |f| path = collection_dir(f) File.directory?(path) || entry_filter.symlink?(f) end end end
Filtered version of the entries in this collection. See ‘Jekyll::EntryFilter#filter` for more information.
Returns a list of filtered entry paths.
Source
# File lib/jekyll/collection.rb, line 158 def inspect "#<#{self.class} @label=#{label} docs=#{docs}>" end
An inspect string.
Returns the inspect string
Source
# File lib/jekyll/collection.rb, line 35 def method_missing(method, *args, &blck) if docs.respond_to?(method.to_sym) Jekyll.logger.warn "Deprecation:", "#{label}.#{method} should be changed to #{label}.docs.#{method}." Jekyll.logger.warn "", "Called by #{caller(0..0)}." docs.public_send(method.to_sym, *args, &blck) else super end end
Override of method_missing
to check in @data for the key.
Source
# File lib/jekyll/collection.rb, line 57 def read filtered_entries.each do |file_path| full_path = collection_dir(file_path) next if File.directory?(full_path) if Utils.has_yaml_header? full_path read_document(full_path) else read_static_file(file_path, full_path) end end site.static_files.concat(files) unless files.empty? sort_docs! end
Read the allowed documents into the collection’s array of docs.
Returns the sorted array of docs.
Source
# File lib/jekyll/collection.rb, line 109 def relative_directory @relative_directory ||= "_#{label}" end
The directory for this Collection
, relative to the site source or the directory containing the collection.
Returns a String containing the directory name where the collection
is stored on the filesystem.
Source
# File lib/jekyll/collection.rb, line 30 def respond_to_missing?(method, include_private = false) docs.respond_to?(method.to_sym, include_private) || super end
Override of normal respond_to? to match method_missing
‘s logic for looking in @data.
Source
# File lib/jekyll/collection.rb, line 169 def sanitize_label(label) label.gsub(%r![^a-z0-9_\-.]!i, "") end
Produce a sanitized label name Label names may not contain anything but alphanumeric characters,
underscores, and hyphens.
label - the possibly-unsafe label
Returns a sanitized version of the label.
Source
# File lib/jekyll/collection.rb, line 179 def to_liquid Drops::CollectionDrop.new self end
Produce a representation of this Collection
for use in Liquid. Exposes two attributes:
- label - docs
Returns a representation of this collection for use in Liquid.
Source
# File lib/jekyll/collection.rb, line 194 def url_template @url_template ||= metadata.fetch("permalink") do Utils.add_permalink_suffix("/:collection/:path", site.permalink_style) end end
The URL
template to render collection’s documents at.
Returns the URL
template to render collection’s documents at.
Source
# File lib/jekyll/collection.rb, line 187 def write? !!metadata.fetch("output", false) end
Whether the collection’s documents ought to be written as individual
files in the output.
Returns true if the ‘write’ metadata is true, false otherwise.
Private Instance Methods
Source
# File lib/jekyll/collection.rb, line 213 def container @container ||= site.config["collections_dir"] end
Source
# File lib/jekyll/collection.rb, line 253 def determine_sort_order(sort_key, apples, olives) apple_property, apple_document = apples olive_property, olive_document = olives if apple_property.nil? && !olive_property.nil? order_with_warning(sort_key, apple_document, 1) elsif !apple_property.nil? && olive_property.nil? order_with_warning(sort_key, olive_document, -1) else apple_property <=> olive_property end end
Source
# File lib/jekyll/collection.rb, line 266 def order_with_warning(sort_key, document, order) Jekyll.logger.warn "Sort warning:", "'#{sort_key}' not defined in #{document.relative_path}" order end
Source
# File lib/jekyll/collection.rb, line 217 def read_document(full_path) doc = Document.new(full_path, :site => site, :collection => self) doc.read docs << doc if site.unpublished || doc.published? end
Source
# File lib/jekyll/collection.rb, line 295 def read_static_file(file_path, full_path) relative_dir = Jekyll.sanitized_path( relative_directory, File.dirname(file_path) ).chomp("/.") files << StaticFile.new( site, site.source, relative_dir, File.basename(full_path), self ) end
Source
# File lib/jekyll/collection.rb, line 276 def rearrange_docs! docs_table = {} custom_order = {} # pre-sort to normalize default array across platforms and then proceed to create a Hash # from that sorted array. docs.sort.each do |doc| docs_table[doc.relative_path] = doc end metadata["order"].each do |entry| custom_order[File.join(relative_directory, entry)] = nil end result = Jekyll::Utils.deep_merge_hashes(custom_order, docs_table).values result.compact! self.docs = result end
Rearrange documents within the ‘docs` array as listed in the `metadata` array.
Involves converting the two arrays into hashes based on relative_paths as keys first, then merging them to remove duplicates and finally retrieving the Document
instances from the merged array.
Source
# File lib/jekyll/collection.rb, line 223 def sort_docs! if metadata["order"].is_a?(Array) rearrange_docs! elsif metadata["sort_by"].is_a?(String) sort_docs_by_key! else docs.sort! end end
Source
# File lib/jekyll/collection.rb, line 235 def sort_docs_by_key! meta_key = metadata["sort_by"] # Modify `docs` array to cache document's property along with the Document instance docs.map! { |doc| [doc.data[meta_key], doc] }.sort! do |apples, olives| order = determine_sort_order(meta_key, apples, olives) # Fall back to `Document#<=>` if the properties were equal or were non-sortable # Otherwise continue with current sort-order if order.nil? || order.zero? apples[-1] <=> olives[-1] else order end # Finally restore the `docs` array with just the Document objects themselves end.map!(&:last) end
A custom sort function based on Schwartzian transform Refer byparker.com/blog/2017/schwartzian-transform-faster-sorting/ for details