Scenario for using instance vars to pass data to layouts and templates, and prevent

changes to instance vars being shared between different templates.
This commit is contained in:
Ben Hollis 2011-12-06 23:24:14 -08:00
parent 9b07bf24dd
commit 97dc2c9742
7 changed files with 41 additions and 6 deletions

View file

@ -0,0 +1,20 @@
Feature: Instance Vars
In order to share data with layouts and partials via instance variables
Scenario: Setting an instance var in a template should be visible in its layout
Given the Server is running at "instance-vars-app"
When I go to "/instance-var-set.html"
Then I should see "Var is 100"
Scenario: Setting an instance var in a template should be visible in a partial
Given the Server is running at "instance-vars-app"
When I go to "/instance-var-set.html"
Then I should see "My var is here!"
Scenario: Setting an instance var in one file should not be visible in another
Given the Server is running at "instance-vars-app"
When I go to "/instance-var-set.html"
When I go to "/no-instance-var.html"
Then I should see "No var..."

View file

View file

@ -0,0 +1,5 @@
<% if @my_var %>
My var is here!
<% else %>
No var...
<% end %>

View file

@ -0,0 +1,2 @@
<% @my_var = 100 %>
<%= partial 'vartial' %>

View file

@ -0,0 +1,3 @@
Var is <%= @my_var %>
<%= yield %>

View file

@ -0,0 +1 @@
<%= partial 'vartial' %>

View file

@ -40,8 +40,12 @@ module Middleman::CoreExtensions::Rendering
@current_engine, engine_was = engine, @current_engine @current_engine, engine_was = engine, @current_engine
# Use a dup of self as a context so that instance variables set within
# the template don't persist for other templates.
context = self.dup
while ::Tilt[path] while ::Tilt[path]
content = render_individual_file(path, locs, opts) content = render_individual_file(path, locs, opts, context)
path = File.basename(path, File.extname(path)) path = File.basename(path, File.extname(path))
cache.set([:raw_template, path], content) cache.set([:raw_template, path], content)
end end
@ -49,7 +53,7 @@ module Middleman::CoreExtensions::Rendering
needs_layout = !%w(.js .css .txt).include?(extension) needs_layout = !%w(.js .css .txt).include?(extension)
if needs_layout && layout_path = fetch_layout(engine, opts) if needs_layout && layout_path = fetch_layout(engine, opts)
content = render_individual_file(layout_path, locs, opts) { content } content = render_individual_file(layout_path, locs, opts, context) { content }
end end
content content
@ -92,14 +96,14 @@ module Middleman::CoreExtensions::Rendering
end end
if found_partial if found_partial
render_individual_file(found_partial, locals, options, &block) render_individual_file(found_partial, locals, options, self, &block)
else else
raise ::Middleman::CoreExtensions::Rendering::TemplateNotFound, "Could not locate partial: #{data}" raise ::Middleman::CoreExtensions::Rendering::TemplateNotFound, "Could not locate partial: #{data}"
end end
end end
# @private # @private
def render_individual_file(path, locs = {}, opts = {}, &block) def render_individual_file(path, locs = {}, opts = {}, context, &block)
path = path.to_s path = path.to_s
@_out_buf, _buf_was = "", @_out_buf @_out_buf, _buf_was = "", @_out_buf
@ -116,7 +120,7 @@ module Middleman::CoreExtensions::Rendering
::Tilt.new(path, 1, options) { body } ::Tilt.new(path, 1, options) { body }
end end
template.render(self, locs, &block) template.render(context, locs, &block)
ensure ensure
@_out_buf = _buf_was @_out_buf = _buf_was
end end