Class: Stache::Mustache::Handler
- Inherits:
-
Object
- Object
- Stache::Mustache::Handler
- Includes:
- Util.av_template_class(:Handlers)::Compilable
- Defined in:
- lib/stache/mustache/handler.rb
Overview
From HAML, thanks a bunch, guys! In Rails 3.1+, template handlers don’t inherit from anything. In <= 3.0, they do. To avoid messy logic figuring this out, we just inherit from whatever the ERB handler does.
Class Method Summary collapse
-
.call(template) ⇒ Object
In Rails 3.1+, #call takes the place of #compile.
Instance Method Summary collapse
-
#compile(template) ⇒ Object
Thanks to Mustache::Rails3 for getting us most of the way home here.
-
#mustache_class_from_template(template) ⇒ Object
suss out a constant name for the given template.
Class Method Details
.call(template) ⇒ Object
In Rails 3.1+, #call takes the place of #compile
83 84 85 |
# File 'lib/stache/mustache/handler.rb', line 83 def self.call(template) new.compile(template) end |
Instance Method Details
#compile(template) ⇒ Object
Thanks to Mustache::Rails3 for getting us most of the way home here
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/stache/mustache/handler.rb', line 14 def compile(template) # # get a custom Mustache, or the default Stache::Mustache::View mustache_class = mustache_class_from_template(template) # If the class is in the same directory as the template, the source of the template can be the # source of the class, and so we need to read the template source from the file system. # Matching against `module` may seem a bit hackish, but at worst it provides false positives # only for templates containing the word `module`, and reads the template again from the file # system. template_is_class = template.source.match(/module/) ? true : false virtual_path = template.virtual_path.to_s # Caching key template_id = "#{template.identifier.to_s}#{template.updated_at.to_i}" # Return a string that will be eval'd in the context of the ActionView, ugly, but it works. <<-MUSTACHE mustache = ::#{mustache_class}.new mustache.view = self mustache.virtual_path = '#{virtual_path}' mustache[:yield] = content_for(:layout) mustache.context.push(local_assigns) variables = controller.instance_variables variables.delete(:@template) variables -= controller.class.protected_instance_variables.to_a variables.each do |name| mustache.instance_variable_set(name, controller.instance_variable_get(name)) end # Add view instance variables also so RSpec view spec assigns will work (instance_variable_names - variables).each do |name| mustache.instance_variable_set(name, instance_variable_get(name)) end # Declaring an +attr_reader+ for each instance variable in the # Stache::Mustache::View subclass makes them available to your templates. mustache.singleton_class.class_eval do attr_reader *variables.map { |name| name.to_s.sub(/^@/, '').to_sym } end # Try to get template from cache, otherwise use template source template_cached = ::Stache.template_cache.read(:'#{template_id}', :namespace => :templates, :raw => true) mustache.template = template_cached || Stache::Mustache::CachedTemplate.new( if #{template_is_class} template_name = "#{virtual_path}" file = Dir.glob(File.join(::Stache.template_base_path, template_name + "\.*" + mustache.template_extension)).first File.read(file) else '#{template.source.gsub(/'/, "\\\\'")}' end ) # Render - this will also compile the template compiled = mustache.render.html_safe # Store the now compiled template unless template_cached ::Stache.template_cache.write(:'#{template_id}', mustache.template, :namespace => :templates, :raw => true) end compiled MUSTACHE end |
#mustache_class_from_template(template) ⇒ Object
suss out a constant name for the given template
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/stache/mustache/handler.rb', line 88 def mustache_class_from_template(template) # If we don't have a source template to render, return an abstract view class. # This is normally used with rspec-rails. You probably never want to normally # render a bare Stache::View if template.source.empty? return Stache::Mustache::View end const_name = ActiveSupport::Inflector.camelize(ActiveSupport::Inflector.underscore(template.virtual_path.to_s)) const_name = "#{Stache.wrapper_module_name}::#{const_name}" if Stache.wrapper_module_name begin const_name.constantize rescue NameError, LoadError => e # Only rescue NameError/LoadError concerning our mustache_class e_const_name = e..match(/ ([^ ]*)$/)[1] if const_name.match(/#{e_const_name}(::|$)/) Stache::Mustache::View else raise e end end end |