Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for multiple template paths #5

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions lib/mustache_rails.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,21 @@ def partial(name)
#
# Mustache::Rails::Config.template_base_path = Rails.root.join('app', 'templates')
module Config

def self.default!
@template_paths = [::Rails.root.join('app/templates')]
end

def self.template_paths
@template_paths || default!
end

def self.template_base_path
@template_base_path ||= ::Rails.root.join('app', 'templates')
@template_paths.first
end

def self.template_base_path=(value)
@template_base_path = value
@template_paths[0] = value
end

def self.template_extension
Expand Down Expand Up @@ -77,23 +86,23 @@ class TemplateHandler < ActionView::Template::Handler
def compile(template)
mustache_class = mustache_class_from_template(template)
mustache_class.template_file = mustache_template_file(template)

<<-MUSTACHE
mustache = ::#{mustache_class}.new
mustache.view = self
mustache[:yield] = content_for(:layout)
mustache.context.update(local_assigns)
variables = controller.instance_variable_names
variables -= %w[@template]

if controller.respond_to?(:protected_instance_variables)
variables -= controller.protected_instance_variables
end

variables.each do |name|
mustache.instance_variable_set(name, controller.instance_variable_get(name))
end

# Declaring an +attr_reader+ for each instance variable in the
# Mustache::Rails subclass makes them available to your templates.
mustache.class.class_eval do
Expand All @@ -112,7 +121,11 @@ def mustache_class_from_template(template)
end

def mustache_template_file(template)
"#{Config.template_base_path}/#{template.virtual_path}.#{Config.template_extension}"
for template_path in Config.template_paths do
path = ::Rails.root.join(template_path, "#{template.virtual_path}.#{Config.template_extension}")
return path.to_s if File.exists?(path)
end
raise ActionView::MissingTemplate.new(Config.template_paths, template.virtual_path, {}, false)
end

end
Expand All @@ -121,3 +134,4 @@ def mustache_template_file(template)

::ActiveSupport::Dependencies.autoload_paths << Rails.root.join("app", "views")
::ActionView::Template.register_template_handler(:rb, Mustache::Rails::TemplateHandler)
::ActionView::Template.register_template_handler(:mustache, Mustache::Rails::TemplateHandler)
37 changes: 37 additions & 0 deletions spec/mustache_rails_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'spec_helper'

describe Mustache::Rails do

before do
@handler = Mustache::Rails::TemplateHandler.new
@template = mock(ActionView::Template, :virtual_path => "foo/action")
Mustache::Rails::Config.default!
end

it "looks for templates by default in app/templates for templates with a .mustache extension" do
File.stub(:exists?).and_return(true)
@handler.send(:mustache_template_file, @template).should == "#{Rails.root}/app/templates/foo/action.html.mustache"
end

it "raises an error if it can't find the template that you're looking for" do
File.stub(:exists?).and_return(false)
expect {@handler.send(:mustache_template_file, @template)}.to raise_error(ActionView::MissingTemplate)
end

it "can find mustache templates from multiple configured places" do
Mustache::Rails::Config.template_paths << "my/other/template/place"
File.should_receive(:exists?).with(Rails.root.join("app/templates/foo/action.html.mustache")).and_return(false)
File.should_receive(:exists?).with(Rails.root.join("my/other/template/place/foo/action.html.mustache")).and_return(true)
@handler.send(:mustache_template_file, @template).should == "#{Rails.root}/my/other/template/place/foo/action.html.mustache"
end

describe "backwards compatibility" do
it "supports using the template_base_path as the first entry in the template paths array" do
Mustache::Rails::Config.template_base_path.should == Rails.root.join("app/templates")
Mustache::Rails::Config.template_paths << "another/path"
Mustache::Rails::Config.template_base_path.should == Rails.root.join("app","templates")
Mustache::Rails::Config.template_base_path = "foo/bar"
Mustache::Rails::Config.template_paths.should == ["foo/bar", "another/path"]
end
end
end
12 changes: 12 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))

require 'active_support/dependencies'


module Rails
def self.root
Pathname("/fake/rails/root")
end
end
require 'mustache_rails'