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