diff --git a/lib/haml/template.rb b/lib/haml/template.rb index ff0a48c2..ebaa8466 100644 --- a/lib/haml/template.rb +++ b/lib/haml/template.rb @@ -21,49 +21,11 @@ module Haml end end -# This module refers to the ActionView module that's part of Ruby on Rails. -# Haml can be used as an alternate templating engine for it, -# and includes several modifications to make it more Haml-friendly. -# The documentation can be found -# here[http://rubyonrails.org/api/classes/ActionView/Base.html]. -module ActionView - class Base # :nodoc: - def delegate_template_exists_with_haml(template_path) - template_exists?(template_path, :haml) && [:haml] - end - alias_method :delegate_template_exists_without_haml, :delegate_template_exists? - alias_method :delegate_template_exists?, :delegate_template_exists_with_haml - - def compile_template_with_haml(extension, template, file_name, local_assigns) - return compile_haml(template, file_name, local_assigns) if extension.to_s == "haml" - compile_template_without_haml(extension, template, file_name, local_assigns) - end - alias_method :compile_template_without_haml, :compile_template - alias_method :compile_template, :compile_template_with_haml - - def compile_haml(template, file_name, local_assigns) - render_symbol = assign_method_name(:haml, template, file_name) - locals = local_assigns.keys - - @@template_args[render_symbol] ||= {} - locals_keys = @@template_args[render_symbol].keys | locals - @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } - - options = Haml::Template.options.dup - options[:filename] = file_name || 'compiled-template' - - begin - Haml::Engine.new(template, options).def_method(CompiledTemplates, render_symbol, *locals) - rescue Exception => e - if logger - logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}" - logger.debug "Backtrace: #{e.backtrace.join("\n")}" - end - - raise TemplateError.new(@base_path, file_name || template, @assigns, template, e) - end - - @@compile_time[render_symbol] = Time.now - end - end +# Decide how we want to load Haml into Rails. +# Patching was necessary for versions <= 2.0.1, +# but we can make it a normal handler for higher versions. +if defined?(ActionView::TemplateHandler) + require 'haml/template/plugin' +else + require 'haml/template/patch' end diff --git a/lib/haml/template/patch.rb b/lib/haml/template/patch.rb new file mode 100644 index 00000000..8c855eb6 --- /dev/null +++ b/lib/haml/template/patch.rb @@ -0,0 +1,51 @@ +# This file makes Haml work with Rails +# by monkeypatching the core template-compilation methods. +# This is necessary for versions <= 2.0.1 because the template handler API +# wasn't sufficiently powerful to deal with caching and so forth. + +# This module refers to the ActionView module that's part of Ruby on Rails. +# Haml can be used as an alternate templating engine for it, +# and includes several modifications to make it more Haml-friendly. +# The documentation can be found +# here[http://rubyonrails.org/api/classes/ActionView/Base.html]. +module ActionView + class Base # :nodoc: + def delegate_template_exists_with_haml(template_path) + template_exists?(template_path, :haml) && [:haml] + end + alias_method :delegate_template_exists_without_haml, :delegate_template_exists? + alias_method :delegate_template_exists?, :delegate_template_exists_with_haml + + def compile_template_with_haml(extension, template, file_name, local_assigns) + return compile_haml(template, file_name, local_assigns) if extension.to_s == "haml" + compile_template_without_haml(extension, template, file_name, local_assigns) + end + alias_method :compile_template_without_haml, :compile_template + alias_method :compile_template, :compile_template_with_haml + + def compile_haml(template, file_name, local_assigns) + render_symbol = assign_method_name(:haml, template, file_name) + locals = local_assigns.keys + + @@template_args[render_symbol] ||= {} + locals_keys = @@template_args[render_symbol].keys | locals + @@template_args[render_symbol] = locals_keys.inject({}) { |h, k| h[k] = true; h } + + options = Haml::Template.options.dup + options[:filename] = file_name || 'compiled-template' + + begin + Haml::Engine.new(template, options).def_method(CompiledTemplates, render_symbol, *locals) + rescue Exception => e + if logger + logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}" + logger.debug "Backtrace: #{e.backtrace.join("\n")}" + end + + raise TemplateError.new(@base_path, file_name || template, @assigns, template, e) + end + + @@compile_time[render_symbol] = Time.now + end + end +end diff --git a/lib/haml/template/plugin.rb b/lib/haml/template/plugin.rb new file mode 100644 index 00000000..d9b6ed64 --- /dev/null +++ b/lib/haml/template/plugin.rb @@ -0,0 +1,21 @@ +# This file makes Haml work with Rails +# using the > 2.0.1 template handler API. + +module Haml + class Template + def self.line_offset + 1 + end + + def initialize(view) + @view = view + end + + def compile(template) + options = Haml::Template.options.dup + Haml::Engine.new(template, options).send(:precompiled_with_ambles, []) + end + end +end + +ActionView::Base.register_template_handler(:haml, Haml::Template)