Adapt StaticFile for collections, config defaults

This enables files such as images and PDFs to show up in the same relative
output directory as other HTML and Markdown documents in the same collection.

It also enables static files to be hidden using defaults from _config.yml in
the same way that other documents in the same collection and directories may
be hidden using `published: false`.
This commit is contained in:
Mike Bland 2015-06-25 12:49:24 -04:00
parent 0125af80a3
commit 250b6ebb7e
2 changed files with 88 additions and 4 deletions

View File

@ -37,7 +37,7 @@ module Jekyll
def destination_rel_dir def destination_rel_dir
if @collection if @collection
@dir.gsub(/\A_/, '') File.dirname(url)
else else
@dir @dir
end end
@ -61,9 +61,10 @@ module Jekyll
# Whether to write the file to the filesystem # Whether to write the file to the filesystem
# #
# Returns true. # Returns true unless the defaults for the destination path from
# _config.yml contain `published: false`.
def write? def write?
true defaults.fetch('published', true)
end end
# Write the static file to the destination directory (if modified). # Write the static file to the destination directory (if modified).
@ -100,5 +101,41 @@ module Jekyll
"path" => File.join("", relative_path) "path" => File.join("", relative_path)
} }
end end
def placeholders
{
collection: @collection.label,
path: relative_path[
@collection.relative_directory.size..relative_path.size],
output_ext: '',
name: '',
title: '',
}
end
# Applies a similar URL-building technique as Jekyll::Document that takes
# the collection's URL template into account. The default URL template can
# be overriden in the collection's configuration in _config.yml.
def url
@url ||= if @collection.nil?
relative_path
else
::Jekyll::URL.new({
template: @collection.url_template,
placeholders: placeholders,
})
end.to_s.gsub /\/$/, ''
end
# Returns the type of the collection if present, nil otherwise.
def type
@type ||= @collection.nil? ? nil : @collection.label.to_sym
end
# Returns the front matter defaults defined for the file's URL and/or type
# as defined in _config.yml.
def defaults
@defaults ||= @site.frontmatter_defaults.all url, type
end
end end
end end

View File

@ -18,6 +18,16 @@ class TestStaticFile < JekyllUnitTest
StaticFile.new(@site, base, dir, name) StaticFile.new(@site, base, dir, name)
end end
def setup_static_file_with_collection(base, dir, name, label, metadata)
site = fixture_site 'collections' => {label => metadata}
StaticFile.new(site, base, dir, name, site.collections[label])
end
def setup_static_file_with_defaults(base, dir, name, defaults)
site = fixture_site 'defaults' => defaults
StaticFile.new(site, base, dir, name)
end
context "A StaticFile" do context "A StaticFile" do
setup do setup do
clear_dest clear_dest
@ -46,7 +56,44 @@ class TestStaticFile < JekyllUnitTest
should "have a destination relative directory without a collection" do should "have a destination relative directory without a collection" do
static_file = setup_static_file("root", "dir/subdir", "file.html") static_file = setup_static_file("root", "dir/subdir", "file.html")
assert "dir/subdir", static_file.destination_rel_dir assert_equal nil, static_file.type
assert_equal "dir/subdir/file.html", static_file.url
assert_equal "dir/subdir", static_file.destination_rel_dir
end
should "have a destination relative directory with a collection" do
static_file = setup_static_file_with_collection(
"root", "_foo/dir/subdir", "file.html", "foo", {"output" => true})
assert_equal :foo, static_file.type
assert_equal "/foo/dir/subdir/file.html", static_file.url
assert_equal "/foo/dir/subdir", static_file.destination_rel_dir
end
should "use its collection's permalink template for the destination relative directory" do
static_file = setup_static_file_with_collection(
"root", "_foo/dir/subdir", "file.html", "foo",
{"output" => true, "permalink" => "/:path/"})
assert_equal :foo, static_file.type
assert_equal "/dir/subdir/file.html", static_file.url
assert_equal "/dir/subdir", static_file.destination_rel_dir
end
should "be writable by default" do
static_file = setup_static_file("root", "dir/subdir", "file.html")
assert(static_file.write?,
"static_file.write? should return true by default")
end
should "use the _config.yml defaults to determine writability" do
defaults = [{
"scope" => {"path" => "private"},
"values" => {"published" => false}
}]
static_file = setup_static_file_with_defaults(
"root", "private/dir/subdir", "file.html", defaults)
assert(!static_file.write?,
"static_file.write? should return false when _config.yml sets " +
"`published: false`")
end end
should "know its last modification time" do should "know its last modification time" do