simplify and correct rendering pipeline

This commit is contained in:
Tom Preston-Werner 2008-12-24 13:17:28 -08:00
parent 2074f92ed6
commit c46ea4096d
5 changed files with 38 additions and 32 deletions

View File

@ -19,7 +19,7 @@ module Jekyll
self.data = YAML.load($1) self.data = YAML.load($1)
end end
end end
# Transform the contents based on the file extension. # Transform the contents based on the file extension.
# #
# Returns nothing # Returns nothing
@ -39,10 +39,8 @@ module Jekyll
# +site_payload+ is the site payload hash # +site_payload+ is the site payload hash
# #
# Returns nothing # Returns nothing
def do_layout(payload, layouts, site_payload) def do_layout(payload, layouts)
# construct payload # render and transform content (this becomes the final content of the object)
payload = payload.merge(site_payload)
# render content
self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters]) self.content = Liquid::Template.parse(self.content).render(payload, [Jekyll::Filters])
self.transform self.transform

View File

@ -37,9 +37,9 @@ module Jekyll
# +site_payload+ is the site payload hash # +site_payload+ is the site payload hash
# #
# Returns nothing # Returns nothing
def add_layout(layouts, site_payload) def render(layouts, site_payload)
payload = {"page" => self.data} payload = {"page" => self.data}.merge(site_payload)
do_layout(payload, layouts, site_payload) do_layout(payload, layouts)
end end
# Write the generated page file to the destination directory. # Write the generated page file to the destination directory.

View File

@ -123,11 +123,16 @@ module Jekyll
# +site_payload+ is the site payload hash # +site_payload+ is the site payload hash
# #
# Returns nothing # Returns nothing
def add_layout(layouts, site_payload) def render(layouts, site_payload)
# construct post payload # construct payload
related = related_posts(site_payload["site"]["posts"]) payload =
payload = {"page" => self.to_liquid.merge(self.data)} {
do_layout(payload, layouts, site_payload.merge({"site" => {"related_posts" => related}})) "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
"page" => self.to_liquid
}
payload = payload.merge(site_payload)
do_layout(payload, layouts)
end end
# Write the generated post file to the destination directory. # Write the generated post file to the destination directory.
@ -147,11 +152,11 @@ module Jekyll
# #
# Returns <Hash> # Returns <Hash>
def to_liquid def to_liquid
self.data.merge({ "title" => self.data["title"] || "", { "title" => self.data["title"] || "",
"url" => self.url, "url" => self.url,
"date" => self.date, "date" => self.date,
"id" => self.id, "id" => self.id,
"content" => self.content }) "content" => self.content }.merge(self.data)
end end
end end

View File

@ -53,15 +53,19 @@ module Jekyll
entries = Dir.entries(base) entries = Dir.entries(base)
entries = entries.reject { |e| File.directory?(File.join(base, e)) } entries = entries.reject { |e| File.directory?(File.join(base, e)) }
# first pass processes, but does not yet render post content
entries.each do |f| entries.each do |f|
if Post.valid?(f) if Post.valid?(f)
post = Post.new(base, f) post = Post.new(base, f)
post.content = Liquid::Template.parse(post.content).render(site_payload, [Jekyll::Filters])
post.transform
self.posts << post self.posts << post
end end
end end
# second pass renders each post now that full site payload is available
self.posts.each do |post|
post.render(self.layouts, site_payload)
end
self.posts.sort! self.posts.sort!
rescue Errno::ENOENT => e rescue Errno::ENOENT => e
# ignore missing layout dir # ignore missing layout dir
@ -72,7 +76,6 @@ module Jekyll
# Returns nothing # Returns nothing
def write_posts def write_posts
self.posts.each do |post| self.posts.each do |post|
post.add_layout(self.layouts, site_payload)
post.write(self.dest) post.write(self.dest)
end end
end end
@ -87,14 +90,14 @@ module Jekyll
def transform_pages(dir = '') def transform_pages(dir = '')
base = File.join(self.source, dir) base = File.join(self.source, dir)
entries = Dir.entries(base) entries = Dir.entries(base)
entries = entries.reject { |e| entries = entries.reject do |e|
(e != '_posts') and ['.', '_'].include?(e[0..0]) (e != '_posts') and ['.', '_'].include?(e[0..0])
} end
# we need to make sure to process _posts *first* otherwise they # we need to make sure to process _posts *first* otherwise they
# might not be available yet to other templates as {{ site.posts }} # might not be available yet to other templates as {{ site.posts }}
if entries.include? '_posts' if entries.include?('_posts')
entries.delete '_posts' entries.delete('_posts')
read_posts(File.join(base, '_posts')) read_posts(File.join(base, '_posts'))
end end
@ -105,13 +108,13 @@ module Jekyll
else else
first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) } first3 = File.open(File.join(self.source, dir, f)) { |fd| fd.read(3) }
# if the file appears to have a YAML header then process it as a page
if first3 == "---" if first3 == "---"
# file appears to have a YAML header so process it as a page
page = Page.new(self.source, dir, f) page = Page.new(self.source, dir, f)
page.add_layout(self.layouts, site_payload) page.render(self.layouts, site_payload)
page.write(self.dest) page.write(self.dest)
# otherwise copy the file without transforming it
else else
# otherwise copy the file without transforming it
FileUtils.mkdir_p(File.join(self.dest, dir)) FileUtils.mkdir_p(File.join(self.dest, dir))
FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f)) FileUtils.cp(File.join(self.source, dir, f), File.join(self.dest, dir, f))
end end

View File

@ -59,10 +59,10 @@ class TestPost < Test::Unit::TestCase
assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", p.content assert_equal "<h1>{{ page.title }}</h1>\n<p>Best <strong>post</strong> ever</p>", p.content
end end
def test_add_layout def test_render
p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-10-18-foo-bar.textile") p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-10-18-foo-bar.textile")
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")} layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
p.add_layout(layouts, {"site" => {"posts" => []}}) p.render(layouts, {"site" => {"posts" => []}})
assert_equal "<<< <h1>Foo Bar</h1>\n<p>Best <strong>post</strong> ever</p> >>>", p.output assert_equal "<<< <h1>Foo Bar</h1>\n<p>Best <strong>post</strong> ever</p> >>>", p.output
end end
@ -72,14 +72,14 @@ class TestPost < Test::Unit::TestCase
p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-10-18-foo-bar.textile") p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-10-18-foo-bar.textile")
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")} layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
p.add_layout(layouts, {"site" => {"posts" => []}}) p.render(layouts, {"site" => {"posts" => []}})
p.write(dest_dir) p.write(dest_dir)
end end
def test_data def test_data
p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-11-21-complex.textile") p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-11-21-complex.textile")
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")} layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
p.add_layout(layouts, {"site" => {"posts" => []}}) p.render(layouts, {"site" => {"posts" => []}})
assert_equal "<<< <p>url: /test/source/2008/11/21/complex.html<br />\ndate: #{Time.parse("2008-11-21")}<br />\nid: /test/source/2008/11/21/complex</p> >>>", p.output assert_equal "<<< <p>url: /test/source/2008/11/21/complex.html<br />\ndate: #{Time.parse("2008-11-21")}<br />\nid: /test/source/2008/11/21/complex</p> >>>", p.output
end end
@ -88,7 +88,7 @@ class TestPost < Test::Unit::TestCase
Jekyll.source = File.join(File.dirname(__FILE__), *%w[source]) Jekyll.source = File.join(File.dirname(__FILE__), *%w[source])
p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-12-13-include.markdown") p = Post.new(File.join(File.dirname(__FILE__), *%w[source _posts]), "2008-12-13-include.markdown")
layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")} layouts = {"default" => Layout.new(File.join(File.dirname(__FILE__), *%w[source _layouts]), "simple.html")}
p.add_layout(layouts, {"site" => {"posts" => []}}) p.render(layouts, {"site" => {"posts" => []}})
assert_equal "<<< <hr />\n<p>Tom Preston-Werner github.com/mojombo</p>\n\n<p>This <em>is</em> cool</p> >>>", p.output assert_equal "<<< <hr />\n<p>Tom Preston-Werner github.com/mojombo</p>\n\n<p>This <em>is</em> cool</p> >>>", p.output
end end