OMG COLLECTIONS ARE RENDERING CALL THE POLICE
This commit is contained in:
parent
7fef0302a7
commit
75f49a751e
|
@ -17,7 +17,7 @@ Feature: Collections
|
||||||
And I have a configuration file with:
|
And I have a configuration file with:
|
||||||
| key | value |
|
| key | value |
|
||||||
| collections | ['methods'] |
|
| collections | ['methods'] |
|
||||||
| render | \n methods: /methods/:subdir/:title:extname |
|
| render | ['methods'] |
|
||||||
When I run jekyll
|
When I run jekyll
|
||||||
Then the _site directory should exist
|
Then the _site directory should exist
|
||||||
And I should see "Collections: methods" in "_site/index.html"
|
And I should see "Collections: methods" in "_site/index.html"
|
||||||
|
|
|
@ -53,6 +53,7 @@ require 'jekyll/cleaner'
|
||||||
require 'jekyll/entry_filter'
|
require 'jekyll/entry_filter'
|
||||||
require 'jekyll/layout_reader'
|
require 'jekyll/layout_reader'
|
||||||
require 'jekyll/publisher'
|
require 'jekyll/publisher'
|
||||||
|
require 'jekyll/renderer'
|
||||||
|
|
||||||
# extensions
|
# extensions
|
||||||
require 'jekyll/plugin'
|
require 'jekyll/plugin'
|
||||||
|
|
|
@ -4,6 +4,8 @@ module Jekyll
|
||||||
class Site
|
class Site
|
||||||
# Handles the cleanup of a site's destination before it is built.
|
# Handles the cleanup of a site's destination before it is built.
|
||||||
class Cleaner
|
class Cleaner
|
||||||
|
attr_reader :site
|
||||||
|
|
||||||
def initialize(site)
|
def initialize(site)
|
||||||
@site = site
|
@site = site
|
||||||
end
|
end
|
||||||
|
@ -27,7 +29,7 @@ module Jekyll
|
||||||
# Returns a Set with the file paths
|
# Returns a Set with the file paths
|
||||||
def existing_files
|
def existing_files
|
||||||
files = Set.new
|
files = Set.new
|
||||||
Dir.glob(File.join(@site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
|
Dir.glob(File.join(site.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
|
||||||
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
|
files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex
|
||||||
end
|
end
|
||||||
files
|
files
|
||||||
|
@ -38,7 +40,7 @@ module Jekyll
|
||||||
# Returns a Set with the file paths
|
# Returns a Set with the file paths
|
||||||
def new_files
|
def new_files
|
||||||
files = Set.new
|
files = Set.new
|
||||||
@site.each_site_file { |item| files << item.destination(@site.dest) }
|
site.each_site_file { |item| files << item.destination(site.dest) }
|
||||||
files
|
files
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -64,7 +66,7 @@ module Jekyll
|
||||||
#
|
#
|
||||||
# Returns the regular expression
|
# Returns the regular expression
|
||||||
def keep_file_regex
|
def keep_file_regex
|
||||||
or_list = @site.keep_files.join("|")
|
or_list = site.keep_files.join("|")
|
||||||
pattern = "\/(#{or_list.gsub(".", "\.")})"
|
pattern = "\/(#{or_list.gsub(".", "\.")})"
|
||||||
Regexp.new pattern
|
Regexp.new pattern
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,8 +22,12 @@ module Jekyll
|
||||||
docs.sort!
|
docs.sort!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def relative_directory
|
||||||
|
"_#{label}"
|
||||||
|
end
|
||||||
|
|
||||||
def directory
|
def directory
|
||||||
Jekyll.sanitized_path(site.source, "_#{label}")
|
Jekyll.sanitized_path(site.source, relative_directory)
|
||||||
end
|
end
|
||||||
|
|
||||||
def allowed_document?(path)
|
def allowed_document?(path)
|
||||||
|
|
|
@ -3,7 +3,7 @@ module Jekyll
|
||||||
include Comparable
|
include Comparable
|
||||||
|
|
||||||
attr_reader :path, :site
|
attr_reader :path, :site
|
||||||
attr_accessor :content, :collection
|
attr_accessor :content, :collection, :output
|
||||||
|
|
||||||
# Create a new Document.
|
# Create a new Document.
|
||||||
#
|
#
|
||||||
|
@ -37,10 +37,66 @@ module Jekyll
|
||||||
File.extname(path)
|
File.extname(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def cleaned_relative_path
|
||||||
|
relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "")
|
||||||
|
end
|
||||||
|
|
||||||
def yaml_file?
|
def yaml_file?
|
||||||
%w[.yaml .yml].include?(extname)
|
%w[.yaml .yml].include?(extname)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sass_file?
|
||||||
|
%w[.sass .scss].include?(extname)
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_with_liquid?
|
||||||
|
!(sass_file? || yaml_file?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def url_template
|
||||||
|
"/:collection/:path:output_ext"
|
||||||
|
end
|
||||||
|
|
||||||
|
def url_placeholders
|
||||||
|
{
|
||||||
|
collection: collection.label,
|
||||||
|
path: cleaned_relative_path,
|
||||||
|
output_ext: Jekyll::Renderer.new(site, self).output_ext
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def permalink
|
||||||
|
return nil if data.nil? || data['permalink'].nil?
|
||||||
|
data['permalink']
|
||||||
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
@url ||= URL.new({
|
||||||
|
:template => url_template,
|
||||||
|
:placeholders => url_placeholders,
|
||||||
|
:permalink => permalink
|
||||||
|
}).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def destination(base_directory)
|
||||||
|
path = Jekyll.sanitized_path(base_directory, url)
|
||||||
|
path = File.join(path, "index.html") if url =~ /\/$/
|
||||||
|
path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Write the generated Document file to the destination directory.
|
||||||
|
#
|
||||||
|
# dest - The String path to the destination dir.
|
||||||
|
#
|
||||||
|
# Returns nothing.
|
||||||
|
def write(dest)
|
||||||
|
path = destination(dest)
|
||||||
|
FileUtils.mkdir_p(File.dirname(path))
|
||||||
|
File.open(path, 'wb') do |f|
|
||||||
|
f.write(output)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Returns merged option hash for File.read of self.site (if exists)
|
# Returns merged option hash for File.read of self.site (if exists)
|
||||||
# and a given param
|
# and a given param
|
||||||
#
|
#
|
||||||
|
@ -84,8 +140,10 @@ module Jekyll
|
||||||
# Returns a Hash representing this Document's data.
|
# Returns a Hash representing this Document's data.
|
||||||
def to_liquid
|
def to_liquid
|
||||||
data.merge({
|
data.merge({
|
||||||
"content" => content,
|
"content" => content,
|
||||||
"path" => path
|
"path" => path,
|
||||||
|
"relative_path" => relative_path,
|
||||||
|
"url" => url
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
module Jekyll
|
||||||
|
class Renderer
|
||||||
|
|
||||||
|
attr_reader :document, :site
|
||||||
|
|
||||||
|
def initialize(site, document)
|
||||||
|
@site = site
|
||||||
|
@document = document
|
||||||
|
end
|
||||||
|
|
||||||
|
# Determine which converters to use based on this document's
|
||||||
|
# extension.
|
||||||
|
#
|
||||||
|
# Returns an array of Converter instances.
|
||||||
|
def converters
|
||||||
|
@converters ||= site.converters.select { |c| c.matches(document.extname) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Determine the extname the outputted file should have
|
||||||
|
#
|
||||||
|
# Returns the output extname including the leading period.
|
||||||
|
def output_ext
|
||||||
|
converters.first.output_ext(document.extname)
|
||||||
|
end
|
||||||
|
|
||||||
|
######################
|
||||||
|
## DAT RENDER THO
|
||||||
|
######################
|
||||||
|
|
||||||
|
def run
|
||||||
|
payload = Utils.deep_merge_hashes({
|
||||||
|
"page" => document.to_liquid
|
||||||
|
}, site.site_payload)
|
||||||
|
info = {
|
||||||
|
filters: [Jekyll::Filters],
|
||||||
|
registers: { :site => site, :page => payload['page'] }
|
||||||
|
}
|
||||||
|
|
||||||
|
# render and transform content (this becomes the final content of the object)
|
||||||
|
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
||||||
|
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
||||||
|
|
||||||
|
output = document.content
|
||||||
|
|
||||||
|
if document.render_with_liquid?
|
||||||
|
output = render_liquid(output, payload, info)
|
||||||
|
end
|
||||||
|
|
||||||
|
place_in_layouts(
|
||||||
|
convert(output),
|
||||||
|
payload,
|
||||||
|
info
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Convert the given content using the converters which match this renderer's document.
|
||||||
|
#
|
||||||
|
# content - the raw, unconverted content
|
||||||
|
#
|
||||||
|
# Returns the converted content.
|
||||||
|
def convert(content)
|
||||||
|
output = content.dup
|
||||||
|
converters.each do |converter|
|
||||||
|
begin
|
||||||
|
output = converter.convert(output)
|
||||||
|
rescue => e
|
||||||
|
Jekyll.logger.error "Conversion error:", "#{converter.class} encountered an error converting '#{document.relative_path}'."
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
end
|
||||||
|
output
|
||||||
|
end
|
||||||
|
|
||||||
|
# Render the given content with the payload and info
|
||||||
|
#
|
||||||
|
# content -
|
||||||
|
# payload -
|
||||||
|
# info -
|
||||||
|
# path - (optional) the path to the file, for use in ex
|
||||||
|
#
|
||||||
|
# Returns the content, rendered by Liquid.
|
||||||
|
def render_liquid(content, payload, info, path = nil)
|
||||||
|
Liquid::Template.parse(content).render!(payload, info)
|
||||||
|
rescue Tags::IncludeTagError => e
|
||||||
|
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{e.path}, included in #{path || document.relative_path}"
|
||||||
|
raise e
|
||||||
|
rescue Exception => e
|
||||||
|
Jekyll.logger.error "Liquid Exception:", "#{e.message} in #{path || document.relative_path}"
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
|
||||||
|
# Render layouts and place given content inside.
|
||||||
|
#
|
||||||
|
# content - the content to be placed in the layout
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Returns the content placed in the Liquid-rendered layouts
|
||||||
|
def place_in_layouts(content, payload, info)
|
||||||
|
output = content.dup
|
||||||
|
layout = site.layouts[document.data["layout"]]
|
||||||
|
used = Set.new([layout])
|
||||||
|
|
||||||
|
while layout
|
||||||
|
payload = Utils.deep_merge_hashes(
|
||||||
|
payload,
|
||||||
|
{
|
||||||
|
"content" => output,
|
||||||
|
"page" => document.to_liquid,
|
||||||
|
"layout" => layout.data
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
output = render_liquid(
|
||||||
|
layout.content,
|
||||||
|
payload,
|
||||||
|
info,
|
||||||
|
File.join(site.config['layouts'], layout.name)
|
||||||
|
)
|
||||||
|
|
||||||
|
if layout = layouts[layout.data["layout"]]
|
||||||
|
if used.include?(layout)
|
||||||
|
layout = nil # avoid recursive chain
|
||||||
|
else
|
||||||
|
used << layout
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
output
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -14,14 +14,13 @@ module Jekyll
|
||||||
def initialize(config)
|
def initialize(config)
|
||||||
self.config = config.clone
|
self.config = config.clone
|
||||||
|
|
||||||
%w[
|
%w[safe lsi highlighter baseurl exclude include future unpublished
|
||||||
safe lsi highlighter baseurl exclude include future unpublished
|
show_drafts limit_posts keep_files gems].each do |opt|
|
||||||
show_drafts limit_posts keep_files gems collections].each do |opt|
|
|
||||||
self.send("#{opt}=", config[opt])
|
self.send("#{opt}=", config[opt])
|
||||||
end
|
end
|
||||||
|
|
||||||
self.source = File.expand_path(config['source'])
|
self.source = File.expand_path(config['source'])
|
||||||
self.dest = File.expand_path(config['destination'])
|
self.dest = File.expand_path(config['destination'])
|
||||||
self.permalink_style = config['permalink'].to_sym
|
self.permalink_style = config['permalink'].to_sym
|
||||||
|
|
||||||
self.plugin_manager = Jekyll::PluginManager.new(self)
|
self.plugin_manager = Jekyll::PluginManager.new(self)
|
||||||
|
@ -85,6 +84,14 @@ module Jekyll
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def collections
|
||||||
|
@collections ||= if config['collections']
|
||||||
|
Hash[config['collections'].map { |coll| [coll, Jekyll::Collection.new(self, coll)] } ]
|
||||||
|
else
|
||||||
|
Hash.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Read Site data from disk and load it into internal data structures.
|
# Read Site data from disk and load it into internal data structures.
|
||||||
#
|
#
|
||||||
# Returns nothing.
|
# Returns nothing.
|
||||||
|
@ -187,7 +194,6 @@ module Jekyll
|
||||||
# Returns nothing.
|
# Returns nothing.
|
||||||
def read_collections
|
def read_collections
|
||||||
if collections
|
if collections
|
||||||
self.collections = Hash[collections.map { |coll| [coll, Jekyll::Collection.new(self, coll)] } ]
|
|
||||||
collections.each { |_, collection| collection.read }
|
collections.each { |_, collection| collection.read }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -207,6 +213,14 @@ module Jekyll
|
||||||
def render
|
def render
|
||||||
relative_permalinks_deprecation_method
|
relative_permalinks_deprecation_method
|
||||||
|
|
||||||
|
if collections
|
||||||
|
collections.each do |label, collection|
|
||||||
|
collection.docs.each do |document|
|
||||||
|
document.output = Jekyll::Renderer.new(self, document).run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
payload = site_payload
|
payload = site_payload
|
||||||
[posts, pages].flatten.each do |page_or_post|
|
[posts, pages].flatten.each do |page_or_post|
|
||||||
page_or_post.render(layouts, payload)
|
page_or_post.render(layouts, payload)
|
||||||
|
@ -369,8 +383,20 @@ module Jekyll
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def documents
|
||||||
|
docs = Set.new
|
||||||
|
if collections
|
||||||
|
collections.each do |label, coll|
|
||||||
|
if config['render'].include?(label)
|
||||||
|
docs = docs.merge(coll.docs)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
docs
|
||||||
|
end
|
||||||
|
|
||||||
def each_site_file
|
def each_site_file
|
||||||
%w(posts pages static_files).each do |type|
|
%w(posts pages static_files documents).each do |type|
|
||||||
send(type).each do |item|
|
send(type).each do |item|
|
||||||
yield item
|
yield item
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,9 +24,9 @@ module Jekyll
|
||||||
# template. Instead, the given permalink will be
|
# template. Instead, the given permalink will be
|
||||||
# used as URL.
|
# used as URL.
|
||||||
def initialize(options)
|
def initialize(options)
|
||||||
@template = options[:template]
|
@template = options[:template]
|
||||||
@placeholders = options[:placeholders] || {}
|
@placeholders = options[:placeholders] || {}
|
||||||
@permalink = options[:permalink]
|
@permalink = options[:permalink]
|
||||||
|
|
||||||
if (@template || @permalink).nil?
|
if (@template || @permalink).nil?
|
||||||
raise ArgumentError, "One of :template or :permalink must be supplied."
|
raise ArgumentError, "One of :template or :permalink must be supplied."
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'pry'
|
||||||
|
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), *%w{ .. lib })
|
||||||
|
require 'jekyll'
|
||||||
|
|
||||||
|
TEST_DIR = File.expand_path(File.join(File.dirname(__FILE__), *%w{ .. test }))
|
||||||
|
|
||||||
|
def fixture_site(overrides = {})
|
||||||
|
Jekyll::Site.new(site_configuration(overrides))
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_configs(overrides, base_hash = Jekyll::Configuration::DEFAULTS)
|
||||||
|
Jekyll::Utils.deep_merge_hashes(base_hash, overrides)
|
||||||
|
end
|
||||||
|
|
||||||
|
def site_configuration(overrides = {})
|
||||||
|
build_configs({
|
||||||
|
"source" => source_dir,
|
||||||
|
"destination" => dest_dir
|
||||||
|
}, build_configs(overrides))
|
||||||
|
end
|
||||||
|
|
||||||
|
def dest_dir(*subdirs)
|
||||||
|
test_dir('dest', *subdirs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def source_dir(*subdirs)
|
||||||
|
test_dir('source', *subdirs)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_dir(*subdirs)
|
||||||
|
File.join(TEST_DIR, *subdirs)
|
||||||
|
end
|
||||||
|
|
||||||
|
module Jekyll
|
||||||
|
binding.pry
|
||||||
|
end
|
Loading…
Reference in New Issue