All Ruby on Rails Node JS Android iOS React Native Frontend Flutter QA

TIL #1: Multi-domain Translations with Rails and Gettext

Welcome to brand new series of content where we will share short tips and pieces of knowledge.

This time Ruby on Rails!

Recently I was working on separating gettext translations in our project into separate domains. It's very useful in cases when some strings should be translated differently in different contexts. I will explain shortly how to use multiple domains for Gettext translations in your Rails app. Enjoy!

Ingredients:
- Rails app

- grosser/fast_gettext - it's one of the commonly used alternatives for I18n.

By default, gettext is using single default domain. To have more than one domain we will need to overwrite gettext:setup task using our app configuration. Here are some examples which can show you how you can achieve that:


# config/application.rb
# Add configuration constant with list of translation domains you need

module MyApp
  class Application < Rails::Application
    ...
    TEXT_DOMAINS = %w(app frontend new_design).freeze
    ...
  end
end

# lib/tasks/gettext.rake

# Remove the provided gettext setup task
Rake::Task["gettext:setup"].clear

# Use your custom translation repositories list
namespace :gettext do
  task :setup => [:environment] do
    FastGettext.translation_repositories.each_key do |domain|
      GetText::Tools::Task.define do |task|
        task.package_name = domain
        task.package_version = "1.0.0"
        task.domain = domain
        task.po_base_directory = locale_path
        task.mo_base_directory = locale_path
        task.files = files_to_translate
        task.enable_description = false
        task.msgmerge_options = gettext_msgmerge_options
        task.msgcat_options = gettext_msgcat_options
        task.xgettext_options = gettext_xgettext_options
      end
    end
  end
end

# config/initializers/locale.rb
# Add gettext domain's based on constant from your app configuration

MyApp::Application::TEXT_DOMAINS.each do |domain|
  FastGettext.add_text_domain domain,
                              path: File.join(Rails.root, "locale"),
                              type: :po,
                              ignore_fuzzy: true,
                              report_warning: true
end
FastGettext.default_text_domain = "app"

Now rails gettext:setup and rails gettext:find should create files called app.pot, frontend.pot and new_design.pot. Every call of domain-based translation method (e.g. d_("new_design", "Some string from new design goes here")) will be translated based on the values in the domain pot file. Voila, problem solved!


TIL, or Today I Learned, is where our developers share the best tech stuff they found every day. You can find smart solutions for some issues, useful advices and anything which will make your developer life easier.

Photo by Patrick Tomasso on Unsplash

Code stories CTA
READ ALSO FROM Ruby/Ruby on Rails
Read also
Need a successful project?
Estimate project or contact us