Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Gem for automatic creation i18n keys in your YAML files as you develop

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 lib
Octocat-spinner-32 README.textile
Octocat-spinner-32 i18n_translation_spawner.gemspec
README.textile

Introduction

I18n translation spawner (ITS) addresses the issue of having to add translation keys to multiple translation files
manually as you develop an app.

Whenever I18n::MissingTranslationData exception is caught, ITS tries to add a new key into your translation file,
generates new translation for it and does it within all locales you have defined in your app.

Installation

Nothing fancy, just add gem 'i18n_translation_spawner' and run bundle install

Then add following line in an initializer, (e.g. /config/initializers/i18n.rb)


    I18n.exception_handler = I18n::TranslationSpawner.new

Configuration

There is a number customizations possible to achieve with ITS

Automatic translations

If you want some keys being translated in a specific way, you can add those to default_translations


    translations_spawner = I18n::TranslationSpawner.new

    translations_spawner.default_translations = {"new.button_submit" => "Create",
    "edit.button_submit" => "Save changes",
    "save" => {"en-GB" => "Save", "nb-NO" => "Lagre" }}

    I18n.exception_handler = translations_spawner

Then for instance the following key customer.new.button_submit will be automatically assigned with translation of “Create”

Automatic prefix removal

By default ITS humanizes the last part of key (“link_new_candidate” becomes “Link new candidate”).
If you want to automatically strip some of prefixes before humanization occurs, specify those in removable_prefixes


    translations_spawner = I18n::TranslationSpawner.new

    translations_spawner.removable_prefixes = %w(link table_header label header)

    I18n.exception_handler = translations_spawner

Then for instance the following key customer.new.link_new_candidate will be automatically assigned with translation of “New candidate”

Skipping some locale during automatic key spawning

As easy as


 translations_spawner = I18n::TranslationSpawner.new

 translations_spawner.skip_locales =["nb-NO"]

 I18n.exception_handler = translations_spawner

Hacking automatic key translations

For instance, you can try handling translations to different languages automatically.
Note, that this code is not super-duper-awesome. It just shows the basic how-to


translations_spawner = I18n::TranslationSpawner.new

require "net/http"
require "json"
require "iconv"
translations_spawner.key_translations_handler = lambda do |key, locale, spawner|
    default = spawner.default_translation_for_key(key, locale)

    begin
        source_language = 'en'
        target_language = locale.split('-').first.downcase

        target_language = case target_language
            when 'nb' then
            'no'
            else
            target_language
        end

        json_string = Net::HTTP.get('translate.google.pl', "/translate_a/t?client=t&text=#{default}&hl=#{target_language}&sl=#{source_language}&tl=#{target_language}&multires=1&otf=1&ssel=0&tsel=0&sc=1").gsub(/,{2,}/, ',')
        ic = Iconv.new('UTF-8//IGNORE', 'UTF-8')
        valid_string = ic.iconv(json_string)

        return JSON.parse(valid_string).flatten.first
    rescue
        default
    end
end
I18n.exception_handler = translations_spawner

Hacking file selection

If you have more complex structure of yaml files placement, you can always add some custom logic for it.
In this example, the first part of key can be a directory name, and in case of no directory with that name, it can be a file name.
If the directory is found, the second part of key is the file name within it (imagine having files like common.en-GB.yml and customer/common.en-GB.yml)


    translations_spawner = I18n::TranslationSpawner.new
    translations_spawner.file_path_decoder = lambda do |key, locale, _|
        tokens = key.to_s.split('.')
        file_path_tokens = if File.file?(File.join(Rails.root, 'config', 'locales', tokens.first, "#{tokens.second}.#{locale.to_s}.yml"))
            tokens[0..1]
        elsif File.file?(File.join(Rails.root, 'config', 'locales', "#{tokens.first}.#{locale.to_s}.yml"))
            tokens.first
        else
            nil
        end
        raise I18n::TranslationSpawner::CannotDecodeTranslationFilePath unless file_path_tokens
        File.join(Rails.root, "config/locales", *file_path_tokens)+".#{locale.to_s}.yml"
    end
    I18n.exception_handler = translations_spawner

Hacking exception catching

If you have some custom translation inheritance mechanism that is based on catching I18n::MissingTranslationData, you can always
incorporate it as well. In this case, the prefix is being stripped and translating re-attempted before re-raising an exception.


    translations_spawner = I18n::TranslationSpawner.new
    translations_spawner.exception_handler = lambda do |exception, locale, key, spawner, options|
        if exception.is_a?(I18n::MissingTranslationData) and %w(customer admin).include?(key.to_s.split('.').first)
            I18n.translate((key.to_s.split('.')[1..-1].join('.')), options.merge({:raise => true})) rescue spawner.handle_exception(exception, locale, key, options)
        else
            spawner.handle_exception(exception, locale, key, options)
        end
    end
    I18n.exception_handler = translations_spawner
Something went wrong with that request. Please try again.