Skip to content

Commit

Permalink
Adapt StaticFile for collections, config defaults
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
Mike Bland committed Jun 29, 2015
1 parent 0125af8 commit 250b6eb
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 4 deletions.
43 changes: 40 additions & 3 deletions lib/jekyll/static_file.rb
Expand Up @@ -37,7 +37,7 @@ def destination(dest)

def destination_rel_dir
if @collection
@dir.gsub(/\A_/, '')
File.dirname(url)
else
@dir
end
Expand All @@ -61,9 +61,10 @@ def modified?

# 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?
true
defaults.fetch('published', true)
end

# Write the static file to the destination directory (if modified).
Expand Down Expand Up @@ -100,5 +101,41 @@ def to_liquid
"path" => File.join("", relative_path)
}
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
49 changes: 48 additions & 1 deletion test/test_static_file.rb
Expand Up @@ -18,6 +18,16 @@ def setup_static_file(base, dir, name)
StaticFile.new(@site, base, dir, name)
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
setup do
clear_dest
Expand Down Expand Up @@ -46,7 +56,44 @@ def setup_static_file(base, dir, name)

should "have a destination relative directory without a collection" do
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

should "know its last modification time" do
Expand Down

0 comments on commit 250b6eb

Please sign in to comment.