I'm trying to port my Rails email templates over to mustache using the stache gem.
I have a standard mailer action which simply sends an email to a user. I've renamed my template path in order to prevent a naming clash when I create the stash view class for the template associated with this mailer action. This process is outlined in the Rails guides.
# app/mailers/registration_mailer.rb
class RegistrationMailer < ActionMailer::Base
def bailed(user)
@user = user
mail to: user.email, template_path: 'er_registration_mailer'
end
end
This is the Stache view associated with the action above. Notice that the module name matches the template path above.
# app/views/er_registration_mailer/bailed.rb
module ErRegistrationMailer
class Bailed < ::Stache::Mustache::View
def continue_registration_link
link_to "Continue registration by connecting your Twitter account",
connect_registrations_url
end
def signature
@view.render "shared/mailer/sig"
end
end
end
Finally I have a mustache template for my mailer.
# app/templates/er_registration_mailer/bailed.html.mustache
<p>Hi there!</p>
<p>I noticed you recently started the signup process for my app but didn't complete it.</p>
<p>{{{continue_registration_link}}}</p>
{{{signature}}}
When I try to send an email, I get an error when it tries to render the signature
partial. This partial lives in app/templates/shared/mailer
where I have both mustache and erb versions of it called _sig.html.mustache
and _sig.html.erb
respectively.
Here's the error:
Failure/Error: RegistrationMailer.bailed(user).deliver
ActionView::Template::Error:
Missing partial shared/mailer/sig with {:locale=>[:en], :formats=>[:html, :text, :js, :css, :ics, :csv, :png, :jpeg, :gif, :bmp, :tiff, :mpeg, :xml, :rss, :atom, :yaml, :multipart_form, :url_encoded_form, :json, :pdf, :zip], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee, :slim, :arb, :rb, :mustache]}. Searched in:
* "/Users/davidtuite/dev/shareshaper/app/app/views"
* "/Users/davidtuite/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/bundler/gems/active_admin-6f04ed5cec24/app/views"
* "/Users/davidtuite/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/devise-3.2.2/app/views"
* "/Users/davidtuite/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/foundation-rails-5.0.3.1/app/views"
* "/Users/davidtuite/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/kaminari-0.15.1/app/views"
# ./app/views/er_registration_mailer/bailed.rb:17:in `signature'
Rails appears to be searching in app/views
for the template (or view class, I'm not sure which).
How can I get the partial to render correctly?
I'm using Rails 4.0.3, Ruby 2.1.1 and stache 1.0.3.
Things I've tried
Using the wrapper class functionality of the stache gem instead of specifying the template_path
to mailers and prefixing the name spacing of the view class.
I've tried both:
# app/views/registration_mailer/bailed.rb
module Wrapper
module RegistrationMailer
class Bailed < ::Stache::Mustache::View
end
end
end
and (note the directory structure):
# app/views/wrapper/registration_mailer/bailed.rb
module Wrapper
module RegistrationMailer
class Bailed < ::Stache::Mustache::View
end
end
end
But I just get an Uninitialized const: Wrapper
error.
I've also tried using mustache to specify the partial in the mailer template:
# app/templates/er_registration_mailer/bailed.html.mustache
<!-- HTML as in above code sample -->
{{{>shared/mailer/sig}}}
That just gives me a different 'not found' error.
Here is an example of using Stache with a mailer:
# config / initializers / stache.rb
Stache.configure do |c|
c.template_base_path = Rails.root.join('app', 'views')
c.wrapper_module_name = "Wrapper"
c.use :mustache
end
# app / mailers / registration_mailer.rb
class RegistrationMailer < ActionMailer::Base
default template_path: 'mailers/registration_mailer'
def bailed(user)
@user = user
mail to: user.email
end
end
# app / models / wrapper / mailers / regisration_mailer / bailed.rb
module Wrapper
module Mailers
module RegistrationMailer
class Bailed < ::Stache::Mustache::View
def continue_registration_link
link_to "Continue registration by connecting your Twitter account",
connect_registrations_url
end
def signature
@view.render "shared/mailer/sig"
end
end
end
end
end
I think what you are missing is the need to configure both the wrapper module and the template path.