module Merb module RenderMixin # shortcut to a template path based on name. def template_dir(loc) File.expand_path(Merb::Server.config[:merb_root] + "/dist/app/views/#{loc}") end # returns the current method name. Used for # auto discovery of which template to render # based on the action name. def current_method_name(depth=0) caller[depth] =~ /`(.*)'$/; $1 end def template_extension_for(ext) Merb::Server.config[:template_ext][ext] end # does a render with no layout. Also sets the # content type header to text/javascript def render_js(template=current_method_name(1), b=binding) headers['Content-Type'] = "text/javascript" template = Erubis::Eruby.new(IO.read( template_dir(self.class.name.snake_case) + "/#{template}.#{template_extension_for(:js)}" )) template.result(b) end # set the @layout. Use this right before a render to # set the name of the layout to use minus the .rhtml def layout(l) @layout = l end # renders nothing but sets the status def render_nothing(status=200) @status = status return "\n" end # renders the action without wrapping it in a layout. def render_no_layout(template=current_method_name(1), b=binding) template = Erubis::Eruby.new( IO.read( template_dir(self.class.name.snake_case) + "/#{template}.#{template_extension_for(:html)}" ) ) template.result(b) end def partial(template) template = Erubis::Eruby.new( IO.read( template_dir(self.class.name.snake_case) + "/_#{template}.#{template_extension_for(:html)}" ) ) template.result(binding) end def render_xml(template=current_method_name(1)) xml = Builder::XmlMarkup.new :indent => 2 xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8" eval IO.read( template_dir(self.class.name.snake_case) + "/#{template}.#{template_extension_for(:xml)}" ) @headers['Content-Type'] = 'application/xml' @headers['Encoding'] = 'UTF-8' xml.target! end # renders a template based on the current action name # you can pass the name of a template if you want to # render a template with a different name then then # current action name. Wraps the rendered template in # the layout. Uses layout/application.rhtml unless # there is a layout named after the current controller # or @layout has been set to another value. def render(template=current_method_name(1), b=binding) tmpl_ext = template_extension_for(:html) MERB_LOGGER.info("Rendering template: #{template_dir(template)}..#{tmpl_ext}") name = self.class.name.snake_case template = Erubis::Eruby.new( IO.read( template_dir(name) + "/#{template}.#{tmpl_ext}" ) ) layout_content = template.result(b) return layout_content if (@layout.to_s == 'none') if ['application', name].include?(@layout.to_s) if File.exist?(template_dir("layout/#{name}.#{tmpl_ext}")) layout = name else layout = 'application' end else layout = @layout.to_s end MERB_LOGGER.info("With Layout: #{template_dir('layout')}/#{layout}.#{tmpl_ext}") @layout_content = layout_content layout_tmpl = Erubis::Eruby.new( IO.read( "#{template_dir('layout')}/#{layout}.#{tmpl_ext}" ) ) layout_tmpl.result(b) end end end