Add a `:subject_interpolations` option to `ActionMailer::Base#mail` #9046

Merged
merged 1 commit into from Jan 25, 2013

5 participants

@exviva

It allows to have a properly scoped default I18n subject, but with interpolations, which
will be populated from the :subject_interpolations hash, e.g.:

# config/locales/en.yml
en:
  user_mailer:
    welcome:
      subject: 'Hello, %{username}'

# app/mailers/user_mailer.rb
class UserMailer < ActionMailer::Base
  def welcome(user)
    mail(subject_interpolations: {username: user.name})
  end
end

I was also thinking of not introducing a new option, but use the :subject option, but detect if it's a Hash, and if so, pass it as interpolations to the default i18n subject.

As usual, open for feedback.

@josevalim
Ruby on Rails member

Couldn't this simply be:

mail(subject: t(".subject", username: user.name))
@rafaelfranca
Ruby on Rails member

Yes. Agree with @josevalim. It is simpler and clearer.

@rafaelfranca rafaelfranca reopened this Jan 23, 2013
@rafaelfranca
Ruby on Rails member

Oops! Closed by mistake.

@carlosantoniodasilva
Ruby on Rails member

Also important to notice that you can always override default_i18n_subject in your own mailer :)

@exviva

Actually the thing I cared about the most was to not have to implement mailer_scope on my own. Yeah, the solution with t('.subject' ... is good enough :).

@exviva exviva closed this Jan 24, 2013
@exviva exviva reopened this Jan 24, 2013
@exviva

Actually, t('.subject' ...) doesn't work, it'd only work in the views. So you'd still need to re-implement mailer_scope yourself :/.

@dmathieu

You should be able to use I18n.t.

@exviva

@dmathieu the t method does work, it's the ".subject" lazy lookup that doesn't work. It's not scoped to [mailer_scope, action_name] as I'd like it to be.

@carlosantoniodasilva
Ruby on Rails member

@exviva so it would make sense to extract mailer_scope to another protected method then, so you can reuse.

@exviva

@carlosantoniodasilva well, sort of. What I'd like to achieve, is being able to easily use the default subject I18n structure, but with interpolation. Even if mailer_scope were a method, I'd still need to join it with action_name and ".subject", so it's not as elegant.

I'm aware that this is a tiny improvement, so if your call is that it's not worth the costs, I'm totally fine with that.

What do you think about allowing the :subject option to be a Hash, and if it is, treat it as interpolations for the default I18n subject?

@carlosantoniodasilva
Ruby on Rails member

@exviva This has been discussed in #2314, the result is that it'd bring too much indirection, please see there.

So instead of adding a new option / API, we could just allow default_i18n_subject to receive the extra interpolation hash, so you can call it from your mailers:

def default_i18n_subject(interpolations = {})
  mailer_scope = self.class.mailer_name.tr('/', '.')
  I18n.t(:subject, interpolations.merge(scope: [mailer_scope, action_name], default: action_name.humanize))
end

mail subject: default_i18n_subject(message: "OMGLOL")

Wdyt?

@exviva

@carlosantoniodasilva that's a very reasonable compromise, I'll implement it and ping you back. Thanks!

@exviva

@carlosantoniodasilva done, let me know what you think

@carlosantoniodasilva carlosantoniodasilva commented on an outdated diff Jan 24, 2013
actionmailer/lib/action_mailer/base.rb
@@ -726,9 +726,10 @@ def set_content_type(m, user_content_type, class_default)
# Translates the +subject+ using Rails I18n class under <tt>[mailer_scope, action_name]</tt> scope.
# If it does not find a translation for the +subject+ under the specified scope it will default to a
# humanized version of the <tt>action_name</tt>.
- def default_i18n_subject #:nodoc:
+ # If the subject has interpolations, you can pass them through the +interpolations+ parameter.
+ def default_i18n_subject(interpolations = {}) #:nodoc:
@carlosantoniodasilva
Ruby on Rails member

I think we can remove the nodoc now then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@carlosantoniodasilva
Ruby on Rails member

Other than that, seems good to me.

@exviva exviva Allow passing interpolations to `#default_i18n_subject`, e.g.:
    # config/locales/en.yml
    en:
      user_mailer:
        welcome:
          subject: 'Hello, %{username}'

    # app/mailers/user_mailer.rb
    class UserMailer < ActionMailer::Base
      def welcome(user)
        mail(subject: default_i18n_subject(username: user.name))
      end
    end
57bfbc2
@carlosantoniodasilva carlosantoniodasilva merged commit 01341e3 into rails:master Jan 25, 2013
@carlosantoniodasilva
Ruby on Rails member

@exviva Thanks.

@exviva exviva deleted the exviva:actionmailer_subject_interpolations branch Mar 10, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment