2010-06-17 6 views
10

J'ai une application multi-locataire et j'expérimente avec l'utilisation de la gemme i18n pour permettre à chacun de nos clients de personnaliser le système à leur goût, en changeant le texte sur différentes pages, en personnalisant les e-mails, etc. Certes, je n'utilise pas i18n comme il était destiné à être utilisé, puisque je ne traduis pas réellement différentes "langues", tout est en anglais, mais chaque client a un anglais différent, si cela a du sens. Pourtant, je suis tombé sur ce que je pense être une décision de conception horriblement mauvaise dans la gemme i18n: si jamais une traduction n'existe pas, plutôt que de ne pas faire une traduction et d'imprimer tout ce qu'elle ferait normalement, elle soulève une erreur. Par exemple,Rails i18n: Puis-je désactiver les erreurs de "translation missing"?

<%= distance_of_time_in_words_to_now @press_release.submitted_at %> 

sort comme

translation missing: en, datetime, distance_in_words, x_days 

Je veux dire, allez! Je ne veux même pas que cela soit traduit.

Je comprends que la raison pour laquelle cela se produit est parce que je n'ai pas les traductions par défaut chargées, mais j'utilise ActiveRecord comme un backend et je voulais le garder propre. La "solution" serait d'importer tous les fichiers de traduction de yaml dans mon magasin de traduction de base de données, mais cela ne semble pas être une bonne idée. Et si je modernisais les rails à l'avenir? Je vais devoir m'inquiéter de garder toutes ces traductions synchronisées.

Encore une fois, je ne peux pas comprendre pourquoi c'est le comportement par défaut. Quand est-ce que ANYBODY voudrait que ce message d'erreur funky apparaisse au lieu de simplement utiliser la valeur par défaut "il y a 3 jours"?

Quoi qu'il en soit, ma question est la suivante: existe-t-il un moyen de désactiver automatiquement la traduction et d'utiliser le message non traduit si la traduction n'existe pas? Merci!

Répondre

6

Cela semble faire l'affaire.

require 'i18n' # without this, the gem will be loaded in the server but not in the console, for whatever reason 

# store translations in the database's translations table 
I18n.backend = I18n::Backend::ActiveRecord.new 

# for translations that don't exist in the database, fallback to the Simple Backend which loads the default English Rails YAML files 
I18nSimpleBackend = I18n::Backend::Simple.new 
I18n.exception_handler = lambda do |exception, locale, key, options| 
    case exception 
    when I18n::MissingTranslationData 
    I18nSimpleBackend.translate(:en, key, options || {}) 
    else 
    raise exception 
    end 
end 
+2

Où placeriez-vous cela exactement? –

+2

Probablement dans un fichier '.rb' sous' config/initializers/'. – Dimitar

+1

'I18n.backend = I18n :: Backend :: ActiveRecord.new' provoque une erreur const non initialisée dans Rails 4.2 – user938363

7

Si vous êtes intéressé à manipuler d'autres exceptions avec le gestionnaire d'exceptions par défaut, ce code modifié de réponse Philip Brocoum devrait faire l'affaire (version Rails 3.2.2):

i18n_simple_backend = I18n::Backend::Simple.new 
old_handler = I18n.exception_handler 
I18n.exception_handler = lambda do |exception, locale, key, options| 
    case exception 
    when I18n::MissingTranslation 
    i18n_simple_backend.translate(:en, key, options || {}) 
    else 
    old_handler.call(exception, locale, key, options) 
    end 
end 

Cette Le code vous permettra de capturer uniquement les exceptions que vous devez gérer différemment.

+0

In Rails 4.2. 'i18n_simple_backend.translate (: en, key, options || {})' provoque une erreur – user938363