Reputation: 13939
I have a helper function that generates useful HTML markup. My functions are usually called with some parameters, including some text translated with I18n my_helper( t(:translation_symbol) )
.
I use I18n t
translation helper for that, which (if left untouched) outputs some <span class="translation missing">...</span>
for texts without translation
I was wondering how to best "intercept" this translation missing so
In my views I should be able to call both
<%= my_helper(t(:my_text)) %> # My helper needs to handle missing translations
<%= t(:my_text) %> # I want default I18n markup (or a custom one) '<span class="translation missing">fr.my_text</span>
My helper
def my_helper(text=nil)
# Suppose my_text doesn't have a translation, text will have value
# => '<span class="translation-missing">fr.my_text</span>'
if translation_missing?(text)
# Code to handle missing translation
doSomething(remove_translation_missing_markup(text))
notify_translation_missing
else
doSomething(text)
end
end
def translation_missing?(text)
# Uses some regex pattern to detect '<span class="translation-missing">'
end
def remove_translation_missing_markup(text)
# Uses some regex pattern to extract my_text from '<span class="translation-missing">fr.my_text</span>'
end
Is there a better way around this ? I feel bad about using a dirty regex solution.
EDIT : extra requirements
raise: true
or default: xxx
for every translation. If there is a need to change the behavior everywhere I can override the t
method. fr.namespace.translation_symbol
), and the original translation symbol (translation_symbol
), so I can add myself translation_missing
in my custom markup.EDIT2 : I am thinking of something like that
t
helper to rescue I18n::MissingTranslationData => e
<span class="translation..."
Upvotes: 3
Views: 1520
Reputation: 16793
Since missing translations seems to be a pain point in your app, rather than have your app code be constantly on the lookout for whether a translation exists or not, if possible I would advocate ensuring that you always have translations for every potential call to t
, regardless of locale (this is all on the assumption that the :translation_symbol
keys in your calls to my_helper(t(:translation_symbol))
are all static, kept in your config/locales
directory, and aren't generated dynamically).
You can do this using the I18n-tasks gem to:
Upvotes: 2
Reputation: 15944
I think you can leverage the fact that I18n can be configured to raise an exception when translation missing. You can either set ActionView::Base.raise_on_missing_translations = true
to globally raise the exception upon missing translations or you can pass :raise => true
option to the t
translation helper.
Update: since you are already using t
helpers in your views and you don't want to change them, I think the only option for you is overriding the t
helper in your ApplicationHelper
:
# ApplicationHelper
def t(key, options = {})
# try to translate as usual
I18n.t(key, options.merge(raise: true)
rescue I18n::MissingTranslationData => e
# do whatever you want on translation missing, e.g. send notification to someone
# ...
"Oh-oh!"
end
This helper either returns the translated text or "oh-oh" if translation missing. And it should work as-is in your current views.
Upvotes: 3
Reputation: 13057
Why not set the default option to the translate method as follows:
<%= t(:my_text, default: "not here") %>
See http://guides.rubyonrails.org/i18n.html#defaults for details about setting defaults for the I18n.translate
method.
Upvotes: 1