Project

mini_i18n

0.03
Low commit activity in last 3 years
A long-lived project that still receives updates
Minimalistic I18n library for Ruby. It supports localization, pluralization, interpolations, fallbacks, nested keys and more.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

 Project Readme

MiniI18n

Gem Build Status Maintainability

Minimalistic i18n library for Ruby

MiniI18n is a simple, flexible, and fast Ruby Internationalization library. It supports localization, interpolation, pluralization, fallbacks, nested keys and more, with a minimal footprint and straightforward API (inspired by the well-known I18n gem).

Translations should be stored in YAML or JSON files and they will be loaded in an in-memory Hash.

en:
  hello: 'Hello'
es:
  hello: 'Hola'
>> T(:hello)
=> "Hello"
>> T(:hello, locale: :es)
=> "Hola"

Installation

Add this line to your application's Gemfile:

gem 'mini_i18n'

And then execute:

bundle install

Or install it yourself as:

gem install mini_i18n

Configuration

Configure your environment using the configure method:

MiniI18n.configure do |config|
  # Path to your translation files.
  config.load_translations(__dir__ + '/translations/*')

  # Default locale.
  config.default_locale = :pt

  # Available locales in your application.
  config.available_locales = [:en, :es, :fr, :pt]

  # If given key is empty, defaults to the default_locale.
  config.fallbacks = true

  # Custom separator for nested keys.
  config.separator = '/'

  # Custom pluralization rules, by locale.
  config.pluralization_rules = {
    es: -> (n) { n == 0 ? 'zero' : 'other' },
    fr: -> (n) { ... }
  }
end

Usage

Quick examples

>> T(:hello)
=> "Hello"
>> T(:hello, locale: :fr)
=> "Bonjour"
>> MiniI18n.locale = :es
>> T(:hello)
=> "Hola"
>> T(:non_existent_key)
=> nil
>> T([:hello, :bye])
=> ["Hello", "Bye"]
>> T('validations.empty')
=> "Can't be empty!"
>> L(Date.new(2025, 8, 16), format: :short)
=> "16 Aug, 18"
>> L(1000.25)
=> "1,000.25"

Helpers

  • Use T() for translations.
  • Use L() for localization (dates, times, numbers). Read more details in this section.

You can also use the long form methods:

  • MiniI18n.t() or MiniI18n.translate()
  • MiniI18n.l() or MiniI18n.localize()

Options for translation helper

locale

>> T(:hello, locale: :es)
=> "Hola"
>> T(:hello, locale: [:en, :fr, :es])
=> ["Hello", "Bonjour", "Hola"]

scope

>> T('views.welcome')
=> "Welcome"
>> T('welcome', scope: 'views')
=> "Welcome"

default

>> T(:non_existent_key, default: 'this is a default value')
=> "this is a default value"

count

>> T('notifications', count: 0)
=> "no unread notifications"

Read more details in the Pluralization section.

Nested Keys

Use custom separators (default is .) to access nested keys.

en:
  validations:
    empty: "Can't be empty!"
T('validations.empty')
MiniI18n.separator = '/'
T('validations/empty')

Interpolation

en:
  hello_with_name: "Hello %{name}!"
>> T(:hello_with_name, name: 'John Doe')
=> "Hello John Doe!"

Pluralization

Define plurals (default keys: zero, one, other):

en:
  notifications:
    zero: 'good job! no new notifications'
    one: '1 unread notification'
    other: '%{count} unread notifications'
>> T('notifications', count: 0)
=> "good job! no new notifications"
>> T('notifications', count: 1)
=> "1 unread notification"
>> T('notifications', count: 5)
=> "5 unread notifications"

Custom pluralization rules

You are also able to customize how plurals are handled in each locale, by defining custom pluralization rules. Example:

MiniI18n.pluralization_rules = {
  es: -> (n) {
    if n == 0
      'zero'
    elsif (1..3).include?(n)
      'few'
    elsif (4..10).include?(n)
      'many'
    else
      'other'
    end
  }
}

Then, define those keys in your translation files:

es:
  notifications:
    zero: 'no tienes nuevas notificaciones'
    few: 'tienes algunas notificaciones pendientes ...'
    many: 'tienes %{count} notificaciones!'
    other: 'alerta!! %{count} notificaciones!'
>> T('notifications', count: 0)
=> "no tienes nuevas notificaciones"
>> T('notifications', count: 2)
=> "tienes algunas notificaciones pendientes ..."
>> T('notifications', count: 5)
=> "tienes 5 notificaciones!"
>> T('notifications', count: 20)
=> "alerta!! 20 notificaciones!"

Localization

Use L() to localize dates, times, and numbers. Don't forget you can also use MiniI18n.l() or MiniI18n.localize().

The gem provides built-in localization for some languages:

  • :en - English
  • :es - Spanish
  • :fr - French
  • :de - German
  • :pt - Portuguese
  • :it - Italian
  • :nl - Dutch
  • :zh - Chinese
  • :ja - Japanese

These defaults include proper date/time formats, day and month names, and number formatting that follows each language's conventions. You can check out a full example of all supported keys in this folder.

Dates and time

It uses strftime under the hood. You can customize the defaults using the following format:

en:
  date:
    formats:
      default: "%A %d, %b %Y"
      short: "%d %B, %y"
>> L(Date.new(2018, 8, 15))
=> "Wednesday 15, Aug 2018"
>> L(Date.new(2018, 8, 15), format: :short)
=> "15 August, 18"

Numbers

To localize your numbers, you can provide the following keys:

en:
  number:
    format:
      delimiter: ','
      separator: '.'
    as:
      currency: '%{number} $'
>> L(1000.25)
=> "1,000.25"
>> L(1000, as: :currency)
=> "1,000 $"
>> L(1000, as: :currency, locale: :es)
=> "1.000 €"

TIP 💡 By using the :as option you can build custom full sentences with formatted numbers, like:

en:
  number:
    as:
      final_price: 'Final price: %{number} $'
      percentage: '%{number}%'
>> L(1000, as: :final_price)
=> "Final price: 1,000 $"
>> L(70.5, as: :percentage)
=> "70.5%"

Development

Feedback, bug reports, ideas, and enhancements are welcome!

To contribute, fork the repo, make your changes, and open a pull request. Please add specs for any behavior changes and run the test suite:

bundle exec rspec

License

Copyright (c) Marc Anguera. MiniI18n is released under the MIT License.