mirror of
https://github.com/jekyll/jekyll.git
synced 2026-02-15 00:55:16 -05:00
This updates the default permalink style for pages and collections to match the site-wide 'permalink' setting. If the permalink setting contains a trailing slash, either explicitly or by being set to ':pretty', then pages and collections permalinks will contain trailing slashes by default as well. Similarly, if the permalink setting contains a trailing ':output_ext', so will pages and collections. If the permalink setting contains neither a trailing slash or extension, neither will pages or collections. This impacts only the default permalink structure for pages and collections. Permalinks set in the frontmatter of an individual page take precedence, as does the permalink setting for a specific collection. Fixes #2691
190 lines
5.7 KiB
Ruby
190 lines
5.7 KiB
Ruby
module Jekyll
|
|
class Collection
|
|
attr_reader :site, :label, :metadata
|
|
|
|
# Create a new Collection.
|
|
#
|
|
# site - the site to which this collection belongs.
|
|
# label - the name of the collection
|
|
#
|
|
# Returns nothing.
|
|
def initialize(site, label)
|
|
@site = site
|
|
@label = sanitize_label(label)
|
|
@metadata = extract_metadata
|
|
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.
|
|
def docs
|
|
@docs ||= []
|
|
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.
|
|
def files
|
|
@files ||= []
|
|
end
|
|
|
|
# Read the allowed documents into the collection's array of docs.
|
|
#
|
|
# Returns the sorted array of docs.
|
|
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
|
|
doc = Jekyll::Document.new(full_path, { site: site, collection: self })
|
|
doc.read
|
|
docs << doc if site.publisher.publish?(doc)
|
|
else
|
|
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
|
|
end
|
|
docs.sort!
|
|
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
|
|
def entries
|
|
return Array.new unless exists?
|
|
@entries ||=
|
|
Dir.glob(collection_dir("**", "*.*")).map do |entry|
|
|
entry["#{collection_dir}/"] = ''; entry
|
|
end
|
|
end
|
|
|
|
# Filtered version of the entries in this collection.
|
|
# See `Jekyll::EntryFilter#filter` for more information.
|
|
#
|
|
# Returns a list of filtered entry paths.
|
|
def filtered_entries
|
|
return Array.new unless exists?
|
|
@filtered_entries ||=
|
|
Dir.chdir(directory) do
|
|
entry_filter.filter(entries).reject do |f|
|
|
path = collection_dir(f)
|
|
File.directory?(path) || (File.symlink?(f) && site.safe)
|
|
end
|
|
end
|
|
end
|
|
|
|
# The directory for this Collection, relative to the site source.
|
|
#
|
|
# Returns a String containing the directory name where the collection
|
|
# is stored on the filesystem.
|
|
def relative_directory
|
|
@relative_directory ||= "_#{label}"
|
|
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.
|
|
def directory
|
|
@directory ||= site.in_source_dir(relative_directory)
|
|
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.
|
|
def collection_dir(*files)
|
|
return directory if files.empty?
|
|
site.in_source_dir(relative_directory, *files)
|
|
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.
|
|
def exists?
|
|
File.directory?(directory) && !(File.symlink?(directory) && site.safe)
|
|
end
|
|
|
|
# The entry filter for this collection.
|
|
# Creates an instance of Jekyll::EntryFilter.
|
|
#
|
|
# Returns the instance of Jekyll::EntryFilter for this collection.
|
|
def entry_filter
|
|
@entry_filter ||= Jekyll::EntryFilter.new(site, relative_directory)
|
|
end
|
|
|
|
# An inspect string.
|
|
#
|
|
# Returns the inspect string
|
|
def inspect
|
|
"#<Jekyll::Collection @label=#{label} docs=#{docs}>"
|
|
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.
|
|
def sanitize_label(label)
|
|
label.gsub(/[^a-z0-9_\-\.]/i, '')
|
|
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.
|
|
def to_liquid
|
|
metadata.merge({
|
|
"label" => label,
|
|
"docs" => docs,
|
|
"files" => files,
|
|
"directory" => directory,
|
|
"output" => write?,
|
|
"relative_directory" => relative_directory
|
|
})
|
|
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.
|
|
def write?
|
|
!!metadata['output']
|
|
end
|
|
|
|
# The URL template to render collection's documents at.
|
|
#
|
|
# Returns the URL template to render collection's documents at.
|
|
def url_template
|
|
metadata.fetch('permalink') do
|
|
Utils.add_permalink_suffix("/:collection/:path", site.permalink_style)
|
|
end
|
|
end
|
|
|
|
# Extract options for this collection from the site configuration.
|
|
#
|
|
# Returns the metadata for this collection
|
|
def extract_metadata
|
|
if site.config['collections'].is_a?(Hash)
|
|
site.config['collections'][label] || Hash.new
|
|
else
|
|
{}
|
|
end
|
|
end
|
|
end
|
|
end
|