Ruby Forum Rails I18n > GetText doesn't work in ActionMailer

Posted by Stephane JAIS (Guest)
on 14.08.2006 04:21
Hi,

I'm using gettext 1.7.0 and rails 1.1.4.

Gettext won't translate:

   * the subject line of my e-mail
   * the view that renders its body.

I have followed the integration guide at:
http://manuals.rubyonrails.org/read/chapter/105

Here's what my application controller looks like:

class ApplicationController < ActionController::Base
  before_filter :init_gettext
  def init_gettext
    bindtextdomain("myapp", request.cgi)
  end

Here's my ActionMailer:

class OrderMailer < ActionMailer::Base
  def confirm(order)
    @subject    = _("Your order with myapp")

The subject is not translated unless I call bindtextdomain right before.

The rhtml template that generate the body is just not translated at all.
I can still create localized versions of it:
cp app/views/order_mailer/confirm.rhtml 
app/views/order_mailer/confirm_fr.rhtml
but that's a little bit disapointing.

Any idea how to get that _() function to work everywhere ?

Thanks,

     Stephane.
Posted by Thomas Baustert (Guest)
on 15.08.2006 14:19
(Received via mailing list)
Hi Stephane,

I try gettext using:

class ApplicationController < ActionController::Base
   init_gettext "myapp"
   ...
end

and it works.


Alternative with bindtextdomain:

I'm not sure, but when using bindtextdomain for tests it
was looking for the mo-file in locale/de/myapp.mo and
not in locale/de/LC_MESSAGES/myapp.mo so you may have to
try with different directories.

Or add a path:

add_default_locale_path(
   File.dirname(__FILE__) + "/locale/%{locale}/LC_MESSAGES/%{name}.mo" )


May it helps.

Thomas




Am 14.08.2006 um 04:21 schrieb Stephane JAIS:

> http://manuals.rubyonrails.org/read/chapter/105
>
> cp app/views/order_mailer/confirm.rhtml
> Posted via http://www.ruby-forum.com/.
> _______________________________________________
> Railsi18n-discussion mailing list
> Railsi18n-discussion@rubyforge.org
> http://rubyforge.org/mailman/listinfo/railsi18n-discussion
>

---
Thomas Baustert - Freiberuflicher Softwarecoach
fon: +49(40)411 622 35 mobil: +49(173)23 911 43
fax: +49(40)411 622 36
thomas.baustert(at)b-simple.de
Posted by Masao Mutoh (Guest)
on 15.08.2006 14:19
(Received via mailing list)
Hi,

It may be a bug of gettext-1.7.0.

Could you try this patch to your gettext/rails.rb ?

--- rails.rb.old        2006-08-15 00:31:42.000000000 +0900
+++ rails.rb    2006-08-15 00:33:08.000000000 +0900
@@ -60,7 +60,7 @@
     # They are remained for backward compatibility.
     #
     def bindtextdomain(domainname, options = {}, locale = nil, charset 
= nil, with_model = true)
-      opt = {:with_helper => true, :with_model => true}
+      opt = {:with_helper => true, :with_model => true, :with_mailer => 
true}
       if options.kind_of? CGI
        # For backward compatibility
        opt.merge!(:cgi => options, :locale => locale, :charset => 
charset, :with_model => with_model)
@@ -73,6 +73,7 @@
       ret = _bindtextdomain(domainname, opt)
       bindtextdomain_to(ActiveRecord::Base, domainname) if 
opt[:with_model]
       bindtextdomain_to(ApplicationHelper, domainname) if 
opt[:with_helper]
+      bindtextdomain_to(ActionMailer::Base, domainname) if 
opt[:with_mailer]
       ret
     end




On Mon, 14 Aug 2006 04:21:10 +0200
Posted by Stephane JAIS (Guest)
on 15.08.2006 22:54
Well, the patch is not doing anything.

I'm using version 1.7.0 which is the last version.
No mention of 'with_mailer' in the source.

$ grep -rs with_mailer /usr/local/lib/ruby/gems/1.8/gems/gettext-1.7.0/
$

Any other idea ?

Thanks a lot,

     Steph.



Masao Mutoh wrote:
> Hi,
> 
> It may be a bug of gettext-1.7.0.
> 
> Could you try this patch to your gettext/rails.rb ?
> 
> --- rails.rb.old        2006-08-15 00:31:42.000000000 +0900
> +++ rails.rb    2006-08-15 00:33:08.000000000 +0900
> @@ -60,7 +60,7 @@
>      # They are remained for backward compatibility.
>      #
>      def bindtextdomain(domainname, options = {}, locale = nil, charset 
> = nil, with_model = true)
> -      opt = {:with_helper => true, :with_model => true}
> +      opt = {:with_helper => true, :with_model => true, :with_mailer => 
> true}
>        if options.kind_of? CGI
>         # For backward compatibility
>         opt.merge!(:cgi => options, :locale => locale, :charset => 
> charset, :with_model => with_model)
> @@ -73,6 +73,7 @@
>        ret = _bindtextdomain(domainname, opt)
>        bindtextdomain_to(ActiveRecord::Base, domainname) if 
> opt[:with_model]
>        bindtextdomain_to(ApplicationHelper, domainname) if 
> opt[:with_helper]
> +      bindtextdomain_to(ActionMailer::Base, domainname) if 
> opt[:with_mailer]
>        ret
>      end
> 
> 
> 
> 
> On Mon, 14 Aug 2006 04:21:10 +0200
Posted by unknown (Guest)
on 16.08.2006 03:19
(Received via mailing list)
Hi,

On Wed Aug 16 05:54:18 JST 2006
Stephane JAIS <rails@stephanejais.com> wrote:

> Well, the patch is not doing anything.
Did you try it?

> I'm using version 1.7.0 which is the last version.
> No mention of 'with_mailer' in the source.

Of course. Because this patch is against 1.7.0.

> 
> > @@ -60,7 +60,7 @@
> >      # They are remained for backward compatibility.
> >      #
> >      def bindtextdomain(domainname, options = {}, locale = nil, 
charset
> > = nil, with_model = true)
> > -      opt = {:with_helper => true, :with_model => true}
> > +      opt = {:with_helper => true, :with_model => true, :with_mailer 
=>
Posted by Mihnea Capraru (mihnea)
on 28.11.2006 18:06
Masao Mutoh wrote:
> Hi,
> 
> It may be a bug of gettext-1.7.0.
> 
> Could you try this patch to your gettext/rails.rb ?
> [...]

Hello, I've experienced the same problem and tried the patch. It works, 
in as much as it translates Subject etc. However the view doesn't get 
translated automatically. Was it supposed to, or does it need to be 
split in one version per language?
Posted by Masao Mutoh (Guest)
on 29.11.2006 01:09
(Received via mailing list)
Hi,

On Tue, 28 Nov 2006 18:06:39 +0100
Mihnea Capraru <mihnea_capraru@fastmail.fm> wrote:

> translated automatically. Was it supposed to, or does it need to be 
> split in one version per language?

I coudn't understand your problem.

You might need to try the tutorial once below.
You can know what Ruby-GetText produces.
http://www.yotabanana.com/hiki/ruby-gettext-howto-rails.html

At least, you should try the newest version of Ruby-GetText(1.8.0).
Then tell me your problem concretely.
Posted by Michael (Guest)
on 30.11.2006 16:19
I'm having issues with ActionMailer too. The problem is that I'm calling 
ActionMailer with a cron task, for example:
   ./script/runner Somerecord.find_stuff_and_mail_it

So I can't set the locale in a controller like I'm used to.

I tried

   init_gettext 'myapp', 'nl'

but that isn't allowed in the model. Couldn't find anything better 
though.
Posted by Mihnea Capraru (mihnea)
on 30.11.2006 16:27
Masao Mutoh wrote:
> Hi,
> 
> On Tue, 28 Nov 2006 18:06:39 +0100
> Mihnea Capraru <mihnea_capraru@fastmail.fm> wrote:
> 
>> translated automatically. Was it supposed to, or does it need to be 
>> split in one version per language?
> 
> I coudn't understand your problem.

The problem is (was) that the '_' function was doing nothing in
ActionMailer views.

This was happening in 1.7 until I called bindtextdomain. Don't know
about 1.8.
Posted by Mihnea Capraru (mihnea)
on 30.11.2006 16:28
Michael wrote:
> I'm having issues with ActionMailer too. The problem is that I'm calling 
> ActionMailer with a cron task, for example:
>    ./script/runner Somerecord.find_stuff_and_mail_it
> 
> So I can't set the locale in a controller like I'm used to.
> 
> I tried
> 
>    init_gettext 'myapp', 'nl'
> 
> but that isn't allowed in the model. Couldn't find anything better 
> though.

Try
     bindtextdomain 'myapp'
in your model, and
     <%= bindtextdomain 'myapp' -%>
in each of your views.
Posted by Michael (Guest)
on 30.11.2006 16:33
> Try
>      bindtextdomain 'myapp'
> in your model, and
>      <%= bindtextdomain 'myapp' -%>
> in each of your views.

Thanks.

But how would I go about setting the language? There is no user session 
when the mail is getting sent, so I need to retrieve the language from 
the record itself and send the mail in the appropriate language.
Posted by Masao Mutoh (Guest)
on 30.11.2006 17:46
(Received via mailing list)
Hi,

On Thu, 30 Nov 2006 16:19:39 +0100
Michael <admin@midela.net> wrote:

> I'm having issues with ActionMailer too. The problem is that I'm calling 
> ActionMailer with a cron task, for example:
>    ./script/runner Somerecord.find_stuff_and_mail_it
> 
> So I can't set the locale in a controller like I'm used to.
> 
> I tried
> 
>    init_gettext 'myapp', 'nl'

init_gettext can't accept lang value as 2nd parameter.
Call GetText.locale= before initialize gettext.

GetText.locale = "nl"
init_gettext 'myapp'

BTW,  I don't know it works with cron.
If it doesn't work with init_gettext, try bindtextdomain as
Mihnea said.

GetText.locale = "nl"
bindtextdomain 'myapp'

Anyway, try 1.8.0 not 1.7.0.
Posted by Masao Mutoh (Guest)
on 30.11.2006 17:46
(Received via mailing list)
Hi,

On Thu, 30 Nov 2006 16:27:27 +0100
Mihnea Capraru <mihnea_capraru@fastmail.fm> wrote:

> 
> The problem is (was) that the '_' function was doing nothing in
> ActionMailer views.
> 
> This was happening in 1.7 until I called bindtextdomain. Don't know
> about 1.8.

So, why don't you try 1.8 ?
Posted by Mihnea Capraru (mihnea)
on 30.11.2006 18:04
Masao Mutoh wrote:
> So, why don't you try 1.8 ?

Hm. That's un/fortunately how a pragmatic user thinks. I got it to work 
with 1.7, so until I schedule a wholesale update of the libraries that I 
use, I'll just focus on other stuff that still doesn't work.
Posted by Michael (Guest)
on 30.11.2006 18:09
Masao Mutoh wrote:
> init_gettext can't accept lang value as 2nd parameter.
> Call GetText.locale= before initialize gettext.
> 
> GetText.locale = "nl"
> init_gettext 'myapp'
> 
> BTW,  I don't know it works with cron.
> If it doesn't work with init_gettext, try bindtextdomain as
> Mihnea said.
> 
> GetText.locale = "nl"
> bindtextdomain 'myapp'
> 
> Anyway, try 1.8.0 not 1.7.0.

I'm using 1.8.0.

Using init_gettext generates an error message. The second suggestion 
does work, but only within the model itself, so far.

Here's what I have in the model:

require 'gettext/rails'
class Mymailer < ActionMailer::Base
  def send_a_mail(email, language)
    GetText.locale = language
    bindtextdomain 'my app'
    @subject    = _('You have a winning combination!')
    @recipients = email
  end

This succesfully translates the subject, but the body of the email (a 
view), doesn't get translated. Can I use translatable strings in the 
actionmailer views or should I created seperate files (like 
mail_nl.rhtml,...)?
Posted by Michael (Guest)
on 30.11.2006 18:13
A quick update: using seperate view files DOES work. (mail_nl.rhtml, 
mail_de.rhtml and so on)

It would still be nice if it worked with .po/.mo files though, because 
that would make it easier to translate the app to more languages.
Posted by Masao Mutoh (Guest)
on 01.12.2006 05:12
(Received via mailing list)
Hi,

On Thu, 30 Nov 2006 18:13:54 +0100
Michael <admin@midela.net> wrote:

> A quick update: using seperate view files DOES work. (mail_nl.rhtml, 
> mail_de.rhtml and so on)
> 
> It would still be nice if it worked with .po/.mo files though, because 
> that would make it easier to translate the app to more languages.

Yes. It should be so.

How about this ?

1. Remove GetText.locale= and bindtextdomain anywhere on your script.
2. Add the lines into app/controller/applications.rb

class ApplicationController < ActionController::Base
  init_gettext "myapp"
  after_init_gettext {                         #HERE
     GetText.set_locale_all("nl")        #HERE
  }                                                     #HERE
end
Posted by Roland (Guest)
on 29.03.2007 19:07
This problem is still existant with Rails 1.2.3 and gettext 1.9.0.

Strings in ActionMailer don't get translated with the _() method, they 
don't appear at all (not even the base language).

This is very annoying because it forces me to hardcode all text blurbs 
in language dependent files (that works as reported before) e.g. 
text_en.rhtml, text_de.rhtml, ...

Is there maybe a way to fix it?

thank you in advance,
best regards
Posted by Myk O'Leary (Guest)
on 29.03.2007 21:06
(Received via mailing list)
There are plenty of issues if you try to do this with ActionMailer in
places like LoginEngine, etc; however, if you create a mailer in your
root app, it does it mighty fine with no hassles.

$RAILS_ROOT> script/generate mailer Mailer

This will create a file RAILS_ROOT/app/model/mailer.rb

Use the _() in this new model after setting your locale, just as in a
controller.

Other benefits include much easier sweeping of the tagged strings into
your stock .po files.

---
Myk Oleary
Web Services Developer
Pure Networks
myko@purenetworks.com
Posted by Roland (Guest)
on 30.03.2007 15:33
Myk O'Leary wrote:

> This will create a file RAILS_ROOT/app/model/mailer.rb
> 
> Use the _() in this new model after setting your locale, just as in a
> controller.

Looks like a misunderstanding: The problem is that the _() does not work
in rhtml templates used by ActionMailer.


e.h

mailer_template.rthml
<%= _("string") %>

=> nothing
Posted by Myk OLeary (Guest)
on 30.03.2007 17:30
(Received via mailing list)
Making a mailer in your root application solves that issue as well.  The
.rhtml I'm using is full of _() that work fine.

-Myk

On Fri, 30 Mar 2007 6:58 am, Roland wrote:
> Myk O'Leary wrote:
>
>>  This will create a file RAILS_ROOT/app/model/mailer.rb
>>
>>  Use the _() in this new model after setting your locale, just as in a
>>  controller.
>
> Looks like a misunderstanding: The problem is that the _() does not 
> work
> in rhtml templates used by ActionMailer.


--From the road on my Sidekick
Posted by Roland (Guest)
on 30.03.2007 17:54
Myk OLeary wrote:
> Making a mailer in your root application solves that issue as well.  The
> .rhtml I'm using is full of _() that work fine.
>

Well I alread have a mailer model:

app/models/signup_mailer.rb

and it does not work.


Do you have template files per language? e.g. template_en.rhtml, 
template_xy.rhtml?
Posted by Myk O'Leary (Guest)
on 30.03.2007 18:50
(Received via mailing list)
I do not.



I'll enclose snippets from my setup with what may help you out with
getting it to work.  There are snippets not included for the actual
setting of the locale which I'll assume you have since you have this
working elsewhere.



One note is that I have my controller, model and view one directory
level deeper than you likely do.  This won't affect success, but does
affect the directory paths, etc that you see below.



RAILS_ROOT/app/controllers/application.rb:

...

require 'gettext/rails'

...





RAILS_ROOT/app/controllers/netreport/report_controller.rb:

...

def emailreport

      ...

      Netreport::Reporter.deliver_emailreport(@user, @locale)

      ...

end

...







RAILS_ROOT/app/models/netreport/reporter.rb:

class Netreport::Reporter < ActionMailer::Base

...

def emailreport(user, locale)

      require 'iconv'

ActionMailer::Base.default_charset = "iso-8859-1"

      C = Iconv.new('ISO-8859-1', 'UTF-8')

      ...

      NR_setlocale(locale)

      @subject = C.iconv(_("My subject"))

      hash_body = {"user" => user, "locale" => locale}

      @body = C.iconv(render_message("emailreport", hash_body))

      ...

end

...







RAILS_ROOT/app/views/netreport/reporter/emailreport.rhtml:

...

      NR_setlocale(@locale)

      _("Report for ")

...



Non gettext related notes are that we use iconv for translated emails at
present because several web mail providers are very inconsistent with
presentation of UTF8 character encoded emails.  This did and will work
w/o needing to use iconv, but I don't have the time today to revert back
to our previous code to make sure the snippets I post are working.  I
know the above are, as they are in production right now.  Make sure you
set the locale in the view, or you could very well not get the proper
translations.



---

Myk OLeary - myko@purenetworks.com

Web Services Developer

Pure Networks - http://www.purenetworks.com
Posted by Roland (Guest)
on 30.03.2007 20:09
Myk O'Leary wrote:
> I'll enclose snippets from my setup with what may help you out with
> getting it to work.  There are snippets not included for the actual
> setting of the locale which I'll assume you have since you have this
> working elsewhere.


Thank you very much :-)

two questions:

- This means to get gettext working with ActionMailer you have to pass 
the current locale from the controller over to the Mailer-model and even 
down to the view? right?

This doesn't look like DRY :-(

- NR_setlocale()  is that your custom method setting GetText.locale?

best regards,
Roland
Posted by Myk O'Leary (Guest)
on 30.03.2007 20:21
(Received via mailing list)
Yes and yes.

---
Myk OLeary - myko@purenetworks.com
Web Services Developer
Pure Networks - http://www.purenetworks.com