Mark
Mark

Reputation: 7635

Extract all untranslated keys in a Rails application

I have an application that needs to be internationalized. Currently almost all strings are assigned to a translation key using t('.whatever').

I want to ensure that all keys are translated to a certain language before we release them. In the development/test environment I can enable config.action_view.raise_on_missing_translations = true.

But some parts like devise and some others generated with a gem are not covered in the tests and there is no grantee that really all pages are tested before the release.

I would prefer a solution, that extracts all keys and adds them to the locales/xxx.yml, preferable with some logic to sort and add the missing keys.

I had a look at the following gems/projects, that did not meet my requirements:

Additional Information

Our keys are English, our default language is :de but we need to translate everything to [:de, :en, :fr, :it]

Upvotes: 2

Views: 816

Answers (3)

tomkr4l
tomkr4l

Reputation: 322

I recommend to use gem i18n-tasks. https://github.com/glebm/i18n-tasks

You can list unused translations, remove them or translate them automatically with google translate. This gem even supports normalization and It's possible to select only specific languages, which you want to work with.

I suggest to add gem 'i18n-tasks' to :development group.

Upvotes: 1

Dorian
Dorian

Reputation: 9185

you can also find the missing keys by using yaml-compare (a tool i made).

you can find it at https://github.com/dorianmariefr/yaml-compare

and then use it as:

yaml-compare config/locales/de.yml config.locales/en.yml de en

Upvotes: 1

sled
sled

Reputation: 14625

Here's how I'd go about it:

First, decide which locale is the reference/complete one, let's say it's :de

Then launch a rails console (or create a rake task), and initialize the I18n backend as follows:

I18n.backend.send(:init_translations)

I18n.backend.send(:translations)

gives you access to all translations for all locales, i.e something like

{
  en: {
    hello: 'Hello World'
  },
  de: {
    hello: 'Hallo Welt'
  }
}

Now pick your reference locale, i.e I18n.backend.send(:translations)[:de] and then iterate through all translation keys in the :de hash and check whether they exist in the other locales using I18n.backend.exists?(locale, translation_key)

Example:

I18n.backend.exists?(:en, [:errors, :messages, :improbable_phone]) I18n.backend.exists?(:en, 'errors.messages.improbable_phone')

If the key does not exists, I'd add it to the hash with a stub like "## TRANSLATION MISSING##", and finally write the hash as YAML file to disk.

Upvotes: 0

Related Questions