Rails: Missing translations not sent anymore
A5308Y opened this issue · 9 comments
It seems like a similar problem like the one in #126.
Using I18.t() instead of t() works. But with t() the log does not show the
** [Localeapp] translation missing: de-CH.dashboard
I would expect and nothing gets sent to locale.
I don't have a clear indication of when the change happened. (The translators didn't want to bother us programmers again, with the same thing.) But in #126 @markedmondson wrote he saw the problem in RCs of Rails 4.1 which lead me here:
which might mean something to you. This discussion: rails/rails#13429 might also be helpful.
Thanks a lot in advance!
Andy
Yep, I'm seeing the same thing with Rails 4.1.4. As soon as I prefixed I18n.
to my t()
call, then missing translations went up.
I have the exact same issue with Rails 4.1.7
I'd like to use the t()
method but it doesn't work.
It only works with the I18n
prefix.
Does someone found a workaround ?
It seems that Rails has moved all the translate logic in ActionView.
So I have added the following i18n_helper.rb
to my app, and it works as expected (on Rails 4.1.7):
module I18nHelper
def translate(key, options={})
super(key, options.merge(raise: true))
rescue I18n::MissingTranslationData
if Rails.env.development?
if key.first == '.'
tk = "#{controller.class.name.gsub('::', '.').gsub('Controller', '').downcase}.#{action_name}#{key}"
else
tk = key
end
Localeapp.sender.post_translation(I18n.locale, tk, options)
end
super(key, options)
end
alias :t :translate
end
Thanks @lou!
I got it working after reading your idea!
But I had to do some things a little differently. I'll write that down for others having a similar problem:
First: A missing dot.
tk = "#{controller_name}.#{action_name}#{key}"
should be:
tk = "#{controller_name}.#{action_name}.#{key}"
Secondly: The translation key should only be built with controller and action_name, if the first character of a translation is a ".":
translation_key = key.first == '.' ? "#{controller_name}.#{action_name}.#{key}" : key
Thirdly: I had trouble loading the helper at the right place. I ended up including it in initializers/localeapp.rb like this:
module ActionView
module Helpers
module TranslationHelper
def t
This meant that I couldn't use super anymore though, because I'm overwriting the method here. So I defined t explicitly and used translate in this method. This only works because we never use translate (always t) in the views!
So I'd say this should only be a temporary fix. I think the "right way" should be to use a custom exception handler instead. That's the way the do it in this gem right?
I wrote a support request to localeapp on November 11th, but haven't received an answer yet.
Hi @A5308H,
I have updated my code.
It now reflects what you mentioned with the translation keys which do not begin with a "."
And it also handles the case when controller is nested under namespaces.
I think that this solution is not ideal because it's very slow when you have many missing translation keys.
Indeed it will send N requests to localeapp server with N representing the number of translation keys present on the page.
Maybe we can intercept the missing translations and construct an Array with it and send the whole Array of translation keys only one time. I suspect it will not be easy to find the right hooks to achieve this.
So I finally found the solution inside the localeapp gem code.
There is a method to add missing translations and they are already send in an after_filter method by the gem.
So we just have to add missing translations in our helper and also deactivate the Localeapp caching system so it does not keep deleted translations keys.
Here is the full code:
config/initializers/localeapp.rb
:
require 'localeapp/rails'
Localeapp.configure do |config|
...
config.polling_environments = [:development]
config.cache_missing_translations = false
end
app/helpers/i18n_helper.rb
:
module I18nHelper
def translate(key, options={})
super(key, options.merge(raise: true))
rescue I18n::MissingTranslationData
if Rails.env.development?
if key.first == '.'
tk = "#{controller.class.name.gsub('::', '.').gsub('Controller', '').downcase}.#{action_name}#{key}"
else
tk = key
end
Localeapp.missing_translations.add(I18n.locale, tk)
end
super(key, options)
end
alias :t :translate
end
OK, there was a regression bug introduced in Rails 4.1 that prevents custom exception handlers form being called.
I've submitted rails/rails#17676 which addresses the issue but in the mean time, overloading the translate
might be the best option (even if it is quite yucky). Using I18n.t
instead of just t
bypasses ActionView
so that is also a possible temporary solution also.
I'm looking into what we can do from within the gem itself right now.
This should be fixed in gem version 0.9.1