This initializer extends the standard Ruby I18n library to support "variations" of translations. This allows you to define multiple versions of a translation string under the same key and select the appropriate one based on context, without cluttering your locale files with verbose, duplicated keys.
Standard I18n is excellent for internationalization, but it doesn't natively offer a clean way to handle contextual differences within the same language and key. For example, you might need:
- Different tones (e.g., formal vs. informal greetings).
- Domain-specific terminology (e.g., "hottest" for an adult site vs. "most popular" for a children's site).
- User-segment-specific language.
- Existing translations will still be used if no variation is set.
Traditionally, this might be handled by creating more specific keys (greetings_formal
, greetings_informal
) or by embedding logic directly in your views/controllers, leading to less maintainable code and locale files.
This solution introduces the concept of "variations" to I18n:
- Define Variations: You can define a set of available variations (e.g.,
:formal
,:informal
,:thriller
,:child
). - Structure Translations: In your YAML locale files, you can structure translations for a key as a hash, where each key-value pair represents a variation.
en: sorting: created_at: "Recently added first" # No variations are given, so this will be used as for all variations most_sold: "Most sold first" hotness_score: all: "Trending first" # Default/fallback variation child: "Most popular first" thriller: "Hottest first"
- Set Current Variation: You can set a global "current variation" (e.g., in a Rails controller
before_action
) or specify a variation directly in theI18n.t
call. - Automatic Resolution:
- When
I18n.t('some.key')
is called, if the resolved value is a hash and a current variation is active, the system attempts to return the string for that specific variation. - If the specific variation isn't found within the hash, it falls back to a configurable
I18n.default_variation
(e.g.,:
). - If neither is found, an error is raised.
- If no variation is active, or the key doesn't resolve to a hash of variations, the standard I18n behavior applies.
- When
- Cleaner Locale Files: Keeps your translation files organized by grouping related contextual translations under a single key.
- Maintainable Contextual Translations: Centralizes the logic for choosing translation variations, rather than scattering it throughout your codebase.
- Flexibility:
- Set a global variation (thread-safe) for the current request or context.
- Override the global variation on a per-translation basis using
I18n.t('key', variation: :some_variation)
.
- Configurable Defaults: Define a default variation to fall back to if a specific variation is requested but not found.
- Validation: Optionally define a list of
I18n.available_variations
to ensure only valid variations are set, preventing typos and unexpected behavior. - Explicit Errors: Raises specific errors (
I18n::InvalidVariationError
,I18n::MissingDefaultVariationError
) if configurations are incorrect or translations are missing, aiding in debugging.
This approach is beneficial when you need to present different "flavors" of text for the same logical concept based on runtime context, such as:
- User roles or preferences.
- Different sections or "themes" of your application.
- A/B testing different phrasings.
- Adapting language for specific target audiences (e.g., age groups, professional vs. casual).
- DRYing up your locale files.
By extending I18n with this variation logic, you can manage complex contextual translation requirements in a more structured and Rails-idiomatic way.