Changeset 192

Show
Ignore:
Timestamp:
02/24/07 14:51:12 (2 years ago)
Author:
e.@brainspl.at
Message:

getting close to merging new template work into trunk. PLease hammer away

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/template_engines/lib/merb/mixins/render_mixin.rb

    r191 r192  
    33  module RenderMixin 
    44     
     5    # universal render method. Template handlers are registered 
     6    # by template extension. So you can use the same render method 
     7    # for any kind of template that implements an adapter module. 
     8    # out of the box Merb support Erubis, Markaby and Builder templates 
     9    # 
     10    # Erubis template ext:  .herb .jerb .erb 
     11    # Markaby template ext: .mab 
     12    # Builder template ext: .rxml .builder .xerb  
     13    # 
     14    # Examples: 
     15    # 
     16    # render 
     17    # looks for views/controllername/actionname.* and renders 
     18    # the template with the proper engine based on its file extension. 
     19    # 
     20    # render :layout => :none 
     21    # renders the current template with no layout. XMl Builder templates 
     22    # are exempt from layout by default. 
     23    #  
     24    # render :action => 'foo' 
     25    # renders views/controllername/foo.* 
     26    # 
     27    # render :nothing => 200 
     28    # renders nothing with a status of 200 
     29    # 
     30    # render :js => "$('some-div').toggle();" 
     31    # if the right hand side of :js => is a string then the proper 
     32    # javascript headers will be set and the string will be returned  
     33    # verbatim as js. 
     34    # 
     35    # render :js => :spinner 
     36    # when the rhs of :js => is a Symbol, it will be used as the  
     37    # action/template name so: views/controllername/spinner.jerb 
     38    # will be rendered as javascript 
     39    # 
     40    # render :js => true 
     41    # this will just look for the current controller/action tenmplate 
     42    # with the .jerb extension and render it as javascript 
     43    # 
     44    # render :xml => @posts.to_xml 
     45    # render :xml => "<foo><bar>Hi!</bar></foo>" 
     46    # this will set the appropriate xml headers and render the rhs 
     47    # of :xml => as a string. SO you can pass any xml string to this 
     48    # to be rendered.  
     49    # 
    550    def render(opts={}, &blk) 
    651      action = opts[:action] || params[:action] 
    752       
    853      case 
     54      when status = opts[:nothing] 
     55        return render_nothing(status) 
    956      when partial = opts[:partial] 
    1057        template = find_partial(partial, opts) 
    1158        opts[:layout] = :none 
    1259      when js = opts[:js] 
    13         template = find_template(:action => action, :ext => 'jerb') 
     60        headers['Content-Type'] = "text/javascript" 
     61        opts[:layout] = :none 
     62        if String === js 
     63          return js 
     64        elsif Symbol === js 
     65          template = find_template(:action => js, :ext => 'jerb') 
     66        else   
     67          template = find_template(:action => action, :ext => 'jerb') 
     68        end 
     69      when xml = opts[:xml] 
     70        headers['Content-Type'] = 'application/xml' 
     71        headers['Encoding']     = 'UTF-8' 
     72        return xml 
    1473      else   
    1574        template = find_template(:action => action) 
     
    2483      content = engine.transform(options) 
    2584      return engine.exempt_from_layout? ? content : wrap_layout(content, opts) 
    26     end 
    27    
    28     def wrap_layout(content, opts={}) 
    29       return content if ((opts[:layout] == :none) || (ancestral_trait[:layout] == :none)) 
    30              
    31       if ancestral_trait[:layout] != :application 
    32         layout_choice = find_template(:layout => ancestral_trait[:layout]) 
    33       else 
    34         if name = find_template(:layout => self.class.name.snake_case) 
    35           layout_choice = name 
    36         else 
    37           layout_choice = find_template(:layout => :application) 
    38         end   
    39       end       
    40        
    41       _view_context.instance_variable_set('@_layout_content', content) 
    42       engine = engine_for(layout_choice) 
    43       options = { 
    44         :file     => layout_choice, 
    45         :view_context  => _view_context, 
    46         :opts => opts 
    47       } 
    48       engine.transform(options) 
    49     end 
    50      
    51    
    52     def find_template(opts={}) 
    53       if action = opts[:action] 
    54         path = 
    55           File.expand_path(MERB_ROOT / "dist/app/views" / self.class.name.snake_case / action) 
    56       elsif layout = opts[:layout] 
    57         path = ancestral_trait[:layout_root] / layout 
    58       else 
    59         raise "called find_template without an :action or :layout"   
    60       end   
    61       extensions = [ancestral_trait[:template_extensions].keys].flatten.uniq 
    62       glob = "#{path}.{#{opts[:ext] || extensions.join(',')}}" 
    63       Dir[glob].first 
    64     end 
    65      
    66     def find_partial(template, opts={}) 
    67       if template =~ /\// 
    68         t = template.split('/') 
    69         template = t.pop 
    70         path = ancestral_trait[:template_root] / t.join('/') / "_#{template}" 
    71       else   
    72         path = ancestral_trait[:template_root]  / self.class.name.snake_case / "_#{template}" 
    73       end 
    74       extensions = [ancestral_trait[:template_extensions].keys].flatten.uniq 
    75       glob = "#{path}.{#{opts[:ext] || extensions.join(',')}}" 
    76       Dir[glob].first 
    7785    end 
    7886 
     
    8997    # .jerb extension. 
    9098    def render_js(template=nil) 
    91       headers['Content-Type'] = "text/javascript" 
    92       render :js => true, :action => template || params[:Action] 
     99      render :js => true, :action => (template || params[:action]) 
    93100    end 
    94      
     101 
    95102    # renders nothing but sets the status, defaults 
    96103    # to 200. does send one \n newline char, tyhis is for 
     
    106113    # explicitely set the template name excluding the file 
    107114    # extension 
    108     def render_no_layout(what=nil, opts={}, &blk
    109       render what, :layout => :none 
     115    def render_no_layout(opts={}
     116      render opts.merge({:layout => :none}) 
    110117    end  
    111118     
     
    120127    # partials that live there like partial('shared/foo') 
    121128    def partial(template) 
    122       if template =~ /\// 
    123         t = template.split('/') 
    124         template = t.pop 
    125         tmpl = new_eruby_obj(template_dir(t.join('/')) / "/_#{template}.#{template_extension_for(:html)}")  
    126       else   
    127         tmpl = new_eruby_obj(template_dir(self.class.name.snake_case) / "/_#{template}.#{template_extension_for(:html)}") 
     129      render :partial => template 
     130    end  
     131     
     132    private 
     133     
     134      def wrap_layout(content, opts={}) 
     135        return content if ((opts[:layout] == :none) || (ancestral_trait[:layout] == :none)) 
     136               
     137        if ancestral_trait[:layout] != :application 
     138          layout_choice = find_template(:layout => ancestral_trait[:layout]) 
     139        else 
     140          if name = find_template(:layout => self.class.name.snake_case) 
     141            layout_choice = name 
     142          else 
     143            layout_choice = find_template(:layout => :application) 
     144          end   
     145        end       
     146         
     147        _view_context.instance_variable_set('@_layout_content', content) 
     148        engine = engine_for(layout_choice) 
     149        options = { 
     150          :file     => layout_choice, 
     151          :view_context  => _view_context, 
     152          :opts => opts 
     153        } 
     154        engine.transform(options) 
    128155      end 
    129       tmpl.evaluate(_view_context) 
    130     end  
    131  
    132      
    133     # this is the xml builder render method. This method 
    134     # builds the Builder::XmlMarkup object for you and adds 
    135     # the xml headers and encoding. Then it evals your template 
    136     # in the context of the xml object. So your .xerb templates 
    137     # will look like this: 
    138     # xml.foo {|xml| 
    139     #   xml.bar "baz" 
    140     # } 
    141     def render_xml(template=current_method_name(1)) 
    142       _xml_body = IO.read( File.expand_path(MERB_ROOT / "dist/app/views" / self.class.name.snake_case / "#{template}.xerb") )  
    143       headers['Content-Type'] = 'application/xml' 
    144       headers['Encoding']     = 'UTF-8' 
    145       _view_context.instance_eval %{ 
    146         xml = Builder::XmlMarkup.new :indent => 2 
    147         xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8" 
    148         #{_xml_body} 
    149         return xml.target! 
    150       }  
    151     end 
    152      
    153     # render using chunked encoding 
    154     # def stream 
    155     #   prefix = '<p>' 
    156     #   suffix = "</p>\r\n" 
    157     #   render_chunked do 
    158     #     IO.popen("cat /tmp/test.log") do |io| 
    159     #       done = false 
    160     #       until done == true do 
    161     #         sleep 0.3 
    162     #         line = io.gets.chomp 
    163     #         if line == 'EOF' 
    164     #           done = true 
    165     #         else 
    166     #           send_chunk(prefix + line + suffix) 
    167     #         end 
    168     #       end 
    169     #     end 
    170     #   end 
    171     # end 
    172     def render_chunked(&blk) 
    173       headers['Transfer-Encoding'] = 'chunked' 
    174       Proc.new { 
    175         response.send_status_no_connection_close(0) 
    176         response.send_header 
    177         blk.call 
    178         response.write("0\r\n\r\n") 
    179       } 
    180     end 
    181      
    182     def send_chunk(data) 
    183       response.write('%x' % data.size + "\r\n") 
    184       response.write(data + "\r\n") 
    185     end 
     156       
     157       
     158      def find_template(opts={}) 
     159        if action = opts[:action] 
     160          path = 
     161            File.expand_path(MERB_ROOT / "dist/app/views" / self.class.name.snake_case / action) 
     162        elsif layout = opts[:layout] 
     163          path = ancestral_trait[:layout_root] / layout 
     164        else 
     165          raise "called find_template without an :action or :layout"   
     166        end   
     167        extensions = [ancestral_trait[:template_extensions].keys].flatten.uniq 
     168        glob = "#{path}.{#{opts[:ext] || extensions.join(',')}}" 
     169        Dir[glob].first 
     170      end 
     171       
     172      def find_partial(template, opts={}) 
     173        if template =~ /\// 
     174          t = template.split('/') 
     175          template = t.pop 
     176          path = ancestral_trait[:template_root] / t.join('/') / "_#{template}" 
     177        else   
     178          path = ancestral_trait[:template_root]  / self.class.name.snake_case / "_#{template}" 
     179        end 
     180        extensions = [ancestral_trait[:template_extensions].keys].flatten.uniq 
     181        glob = "#{path}.{#{opts[:ext] || extensions.join(',')}}" 
     182        Dir[glob].first 
     183      end 
    186184     
    187185  end   
    188 end   
     186end 
  • branches/template_engines/lib/merb/template/markaby.rb

    r191 r192  
    88module Markaby   
    99  class Builder 
    10     # Emulate ERB to satisfy helpers like <tt>form_for</tt>. 
    1110    def _buf; self end 
    12    
    13     # Content_for will store the given block in an instance variable for later use  
    14     # in another template or in the layout. 
    15     # 
    16     # The name of the instance variable is content_for_<name> to stay consistent  
    17     # with @content_for_layout which is used by ActionView's layouts. 
    18     # 
    19     # Example: 
    20     # 
    21     #   content_for("header") do 
    22     #     h1 "Half Shark and Half Lion" 
    23     #   end 
    24     # 
    25     # If used several times, the variable will contain all the parts concatenated. 
    2611    def throw_content(name, &block) 
    2712      @helpers.instance_variable_set "@_#{name}_content",