Title: [waffle-scm] [304] trunk/core/src/main/ruby/org/codehaus/waffle: Implemented support for partial pages through ERB (rhtml).
Revision
304
Author
mward
Date
2007-08-09 14:06:11 -0500 (Thu, 09 Aug 2007)

Log Message

Implemented support for partial pages through ERB (rhtml).  This is called from a template like so: <%= partial('file_name', hash_of_locals) %>

Modified Paths

Added Paths

Diff

Modified: trunk/core/src/main/java/org/codehaus/waffle/context/pico/RubyAwarePicoContextContainerFactory.java (303 => 304)

--- trunk/core/src/main/java/org/codehaus/waffle/context/pico/RubyAwarePicoContextContainerFactory.java	2007-08-07 16:20:46 UTC (rev 303)
+++ trunk/core/src/main/java/org/codehaus/waffle/context/pico/RubyAwarePicoContextContainerFactory.java	2007-08-09 19:06:11 UTC (rev 304)
@@ -17,6 +17,7 @@
         super(messageResources);
     }
 
+    @Override
     public ContextContainer buildApplicationContextContainer() {
         ContextContainer contextContainer = super.buildApplicationContextContainer();
 

Modified: trunk/core/src/main/ruby/org/codehaus/waffle/erb_extension.rb (303 => 304)

--- trunk/core/src/main/ruby/org/codehaus/waffle/erb_extension.rb	2007-08-07 16:20:46 UTC (rev 303)
+++ trunk/core/src/main/ruby/org/codehaus/waffle/erb_extension.rb	2007-08-09 19:06:11 UTC (rev 304)
@@ -1,3 +1,57 @@
 require 'erb'
 
-# TODO Implement render for "partial" views
+module Waffle
+  class PartialController
+
+    def initialize(delegate, locals = {})
+
+      def self.metaclass; class << self; self; end; end
+
+      delegate.instance_variables.each do |key|
+        self.instance_variable_set(key, delegate.instance_variable_get(key))
+      end
+
+      # Add locals to virtual class
+      unless locals.empty?
+        locals.keys.each do |key|
+          metaclass.send(:attr_reader, key)
+        end
+
+        locals.each_pair do |key, value|
+          self.instance_variable_set("@#{key}", value)
+        end
+      end
+
+    end
+  end
+end
+
+class ERB
+
+  module Util
+
+    #
+    # renders partial page (rhtml).
+    #
+    # This will be mixed in to ruby based Waffle Controllers
+    #
+    def partial(file_name, locals = {})
+      controller = Waffle::PartialController.new(self, locals)
+
+      # Locate full path to template (*.rhtml)
+      path = Waffle::ScriptLoader.locate_template(file_name)
+
+      return "File Not Found: Unable to render file '#{path}'." unless Kernel.test(?f, path)
+
+      template = ''
+      File.open(path).each { |line| template << line }
+
+      erb = ERB.new(template)
+      return erb.result(controller.send(:binding))
+    end
+
+    module_function :partial
+
+  end
+  
+end

Modified: trunk/core/src/main/ruby/org/codehaus/waffle/waffle.rb (303 => 304)

--- trunk/core/src/main/ruby/org/codehaus/waffle/waffle.rb	2007-08-07 16:20:46 UTC (rev 303)
+++ trunk/core/src/main/ruby/org/codehaus/waffle/waffle.rb	2007-08-09 19:06:11 UTC (rev 304)
@@ -33,6 +33,13 @@
         end
       end
     end
+
+    # Locate RHTML templates
+    def self.locate_template(file_name)
+      file_name = file_name =~ /.rhtml$/ ? file_name : "#{file_name}.rhtml"
+      return @__servlet_context.getRealPath('/') + file_name
+    end
+
   end
 
   ##

Added: trunk/core/src/test/specs/org/codehaus/waffle/servlet/erb_extension_spec.rb (0 => 304)

--- trunk/core/src/test/specs/org/codehaus/waffle/servlet/erb_extension_spec.rb	                        (rev 0)
+++ trunk/core/src/test/specs/org/codehaus/waffle/servlet/erb_extension_spec.rb	2007-08-09 19:06:11 UTC (rev 304)
@@ -0,0 +1,66 @@
+require 'erb'
+require 'org/codehaus/waffle/erb_extension'
+require 'ostruct'
+
+describe "Waffle::PartialController" do
+
+  it "should expose locals as readable attributes" do
+    controller = Waffle::PartialController.new(Object.new, {:foo => 'bar', :hello => 'world'})
+
+    controller.foo.should == 'bar'
+    controller.hello.should == 'world'
+
+    # Ensuring attributes do not propogate to subsequent instances
+    other = Waffle::PartialController.new(Object.new)
+    other.should_not respond_to(:foo)
+    other.should_not respond_to(:bar)
+  end
+
+  it "should define the same instance variables as the provided delegate controller" do
+    delegate = Object.new
+    delegate.instance_variable_set("@foo", 54)
+    delegate.instance_variable_set("@bar", 99)
+
+    controller = Waffle::PartialController.new(delegate)
+    controller.instance_variables.should include("@foo")
+    controller.instance_variables.should include("@bar")
+
+    controller.instance_variable_get("@foo").should == 54
+    controller.instance_variable_get("@bar").should == 99
+  end
+
+end
+
+describe "ERB::Util.partial method" do
+
+  class FakeController
+    include ERB::Util  # Mix-in whats under test
+
+    attr :name
+
+    def initialize
+      @name = 'waffle'
+    end
+  end
+
+  it "should locate file and render through ERB" do
+    controller = FakeController.new
+
+    Kernel.should_receive(:test).with(?f, 'file path').and_return(true)
+    Waffle::ScriptLoader.should_receive(:locate_template).with('file name').and_return("file path")
+    File.should_receive(:open).with('file path').and_return([%{Name: <[EMAIL PROTECTED]> Foo: <%=foo%>}])
+
+    response = controller.send(:partial, 'file name', {:foo => 'bar'})
+    response.should == "Name: waffle Foo: bar"
+  end
+
+  it "should gracefully handle file does not exist" do
+    controller = FakeController.new
+
+    Waffle::ScriptLoader.should_receive(:locate_template).with('bad_file.rhtml').and_return("bad file path")
+    
+    response = controller.send(:partial, "bad_file.rhtml")
+    response.should == %Q{File Not Found: Unable to render file 'bad file path'.}
+  end
+
+end
\ No newline at end of file

Modified: trunk/core/src/test/specs/org/codehaus/waffle/servlet/waffle_spec.rb (303 => 304)

--- trunk/core/src/test/specs/org/codehaus/waffle/servlet/waffle_spec.rb	2007-08-07 16:20:46 UTC (rev 303)
+++ trunk/core/src/test/specs/org/codehaus/waffle/servlet/waffle_spec.rb	2007-08-09 19:06:11 UTC (rev 304)
@@ -31,6 +31,24 @@
 
 end
 
+describe "Waffle::ScriptLoader#locate_template" do
+
+  before(:each) do
+    @servlet_context = mock('ServletContext')
+    @servlet_context.should_receive(:getRealPath).with('/').and_return('/foo/')
+    Waffle::ScriptLoader.instance_variable_set(:@__servlet_context, @servlet_context)
+  end
+
+  it "should find the real path to the template from the ServletContext" do
+    Waffle::ScriptLoader.locate_template('bar.rhtml').should == '/foo/bar.rhtml'
+  end
+
+  it "should post fix '.rhtml' if missing" do
+    Waffle::ScriptLoader.locate_template('baz').should == '/foo/baz.rhtml'
+  end
+
+end
+
 describe "Waffle::WebContext class" do
 
   it "initialize() should obtain all attribute name/values and add them to a Ruby Hash" do


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to