require 'markaby/rails/rails_builder' module Markaby module Rails class TemplateHandler < ::ActionView::TemplateHandler include ActionView::TemplateHandlers::Compilable def compile(template, local_assigns={}) <<-CODE __template_handler = Markaby::Rails::TemplateHandler.new __template_handler.view = self __template_handler.render(lambda { #{template.source} }, local_assigns) CODE end def render(template, local_assigns = (template.respond_to?(:locals) ? template.locals : {})) builder = RailsBuilder.new(instance_variables.merge(local_assigns), @view) @view.output_buffer = builder template.is_a?(Proc) ? builder.instance_eval(&template) : builder.instance_eval(template.source) builder.to_s end attr_accessor :view private def instance_variables instance_variable_hash(@view) end def instance_variable_hash(object) returning Hash.new do |hash| object.instance_variables.each do |var_name| hash[var_name.gsub("@", "")] = object.instance_variable_get(var_name) end end end end module Helpers # allow fragments to act as strings. url_for has a # case statment in it: # # case options # when String # ... # # which essential is doing the following: # # String === options # # That assertion fails with Markaby::Fragments, which are essential # builder/string fragments. # def url_for(options={}) case options when Markaby::Fragment super(options.to_s) else super end end def capture(*args, &block) if output_buffer.kind_of?(Markaby::Builder) output_buffer.capture(&block) else super end end end end end ActionView::Base.class_eval do include Markaby::Rails::Helpers end ActionView::Template.register_template_handler(:mab, Markaby::Rails::TemplateHandler)