简体   繁体   中英

Devise and localized own mail template

I'm using devise gem and want to translate confirmation mail. I already got my own template and overridden mailer method:

class LocalizedDeviseMailer < Devise::Mailer
  def confirmation_instructions(record, locale)
    @locale = locale
    super
  end
end

So, in my template I can do something like that:

I18n.locale = @locale

And then:

t("it.really.works")

But I don't know how to pass my variable with locale to mailer method. What is the best way to do that? Any help would be appreciated.

Devise is offering the localisation of mail template "natively".

have a look at the devise source code

https://github.com/plataformatec/devise/blob/master/lib/devise/mailers/helpers.rb In this file is explained how to localise the subject (to be added to your locales files)

  # Setup a subject doing an I18n lookup. At first, it attemps to set a subject
  # based on the current mapping:
  #
  #   en:
  #     devise:
  #       mailer:
  #         confirmation_instructions:
  #           user_subject: '...'
  #

This is then the body template that you need to localise as any other html.erb

https://github.com/plataformatec/devise/blob/master/app/views/devise/mailer/confirmation_instructions.html.erb

Depending if your new user will sign_up using http://yoursite/it/users/sign_up or http://yoursite/en/users/sign_up (as you would normally do in your routes for your localised application) the good localised subject and mail (in the former case in Italian, in the latter in English) will be sent.

I recommend to add a locale column to your User model and use your own mailer. This way you have also more flexibility, if you plan to set your own stylesheets and from fields or add additional mails.

in config/initializer/devise.rb :

Devise.setup do |config|
  ...
  config.mailer = "UserMailer"
  ...
end

in app/mailers/user_mailer.rb

class UserMailer < Devise::Mailer
  default from: "noreply@yourdomain.com"

  def confirmation_instructions(user)
    @user = user
    set_locale(@user)
    mail to: @user.email
  end

  def reset_password_instructions(user)
    @user = user
    set_locale(@user)
    mail to: @user.email
  end

  def unlock_instructions(user)
    @user = user
    set_locale(@user)
    mail to: @user.email
  end

  private
   def set_locale(user)
     I18n.locale = user.locale || I18n.default_locale
   end
end

One more way is to add the initializer:

require 'devise/mailer'

module Devise
  class Mailer
    module Localized
      %w(
        confirmation_instructions
        reset_password_instructions
        unlock_instructions
      ).each do |method|
        define_method(method) do |resource, *args|
          I18n.with_locale(resource.try(:locale)) do
            super(resource, *args)
          end
        end
      end
    end

    prepend Localized
  end
end

For ruby <2.1 you can use concern with alias_method_chain .

I think the simplest way to do that is add it on record. So you can add a locale column in your User or juste add an attr_accessor :locale in your User model

So you just need define this locale in your record and use it with I18n.locale = record.locale

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM