GetText doesn't work in ActionMailer

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.

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
[email protected]
http://rubyforge.org/mailman/listinfo/railsi18n-discussion


Thomas B. - 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

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

Hi,

On Wed Aug 16 05:54:18 JST 2006
Stephane JAIS [email protected] 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 
    

=>

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 M. 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

Hi,

On Tue, 28 Nov 2006 18:06:39 +0100
Mihnea C. [email protected] 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.

Masao M. 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?

Masao M. wrote:

Hi,

On Tue, 28 Nov 2006 18:06:39 +0100
Mihnea C. [email protected] 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.

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.

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.

Hi,

On Thu, 30 Nov 2006 16:19:39 +0100
Michael [email protected] 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.

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.

Hi,

On Thu, 30 Nov 2006 16:27:27 +0100
Mihnea C. [email protected] 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 ?

Masao M. 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.

Masao M. 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,…)?

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.

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

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
[email protected]

Hi,

On Thu, 30 Nov 2006 18:13:54 +0100
Michael [email protected] 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

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