diff --git a/.template/spec/base/app/controllers/concerns/localization_spec.rb b/.template/spec/base/app/controllers/concerns/localization_spec.rb new file mode 100644 index 00000000..8c7b1254 --- /dev/null +++ b/.template/spec/base/app/controllers/concerns/localization_spec.rb @@ -0,0 +1,7 @@ +describe 'localization concern' do + subject { file('app/controllers/concerns/localization.rb') } + + it 'contains the around_action' do + expect(subject).to contain('around_action :switch_locale') + end +end diff --git a/.template/spec/base/config/environments/production_spec.rb b/.template/spec/base/config/environments/production_spec.rb index 7fee9da5..9a1d71a0 100644 --- a/.template/spec/base/config/environments/production_spec.rb +++ b/.template/spec/base/config/environments/production_spec.rb @@ -8,6 +8,14 @@ it 'configures the mailer default url options' do expect(subject).to contain(mailer_default_url_config) end + + it 'adds the i18n configuration' do + expect(subject).to contain(i18n_config) + end + + it 'removes the config.i18n.fallbacks = true' do + expect(subject).not_to contain("config.i18n.fallbacks = true") + end it 'allows Rails serve static file' do expect(subject).to contain('config.public_file_server.enabled = true') @@ -23,4 +31,17 @@ def mailer_default_url_config } EOT end + + def i18n_config + <<~EOT + # eg: AVAILABLE_LOCALES = 'en,th' + config.i18n.available_locales = ENV.fetch('AVAILABLE_LOCALES').split(',') + + # eg: DEFAULT_LOCALE = 'en' + config.i18n.default_locale = ENV.fetch('DEFAULT_LOCALE') + + # eg: FALLBACK_LOCALES = 'en,th' + config.i18n.fallbacks = ENV.fetch('FALLBACK_LOCALES').split(',') + EOT + end end diff --git a/.template/variants/api/app/controllers/concerns/localization.rb b/.template/variants/api/app/controllers/concerns/localization.rb index 96138ba5..4dc726a9 100644 --- a/.template/variants/api/app/controllers/concerns/localization.rb +++ b/.template/variants/api/app/controllers/concerns/localization.rb @@ -2,12 +2,20 @@ module Localization extend ActiveSupport::Concern included do - before_action :set_locale + around_action :switch_locale protected - def set_locale - I18n.locale = request.headers[:'Accept-Language'] || I18n.default_locale + def switch_locale(&action) + locale = extract_locale_from_header || I18n.default_locale + + I18n.with_locale(locale, &action) + end + + def extract_locale_from_header + return request.headers[:'Accept-Language'] if I18n.locale_available?(request.headers[:'Accept-Language']) + + nil end end end diff --git a/.template/variants/web/app/controllers/concerns/localization.rb b/.template/variants/web/app/controllers/concerns/localization.rb index 45abb77d..4787a245 100644 --- a/.template/variants/web/app/controllers/concerns/localization.rb +++ b/.template/variants/web/app/controllers/concerns/localization.rb @@ -2,12 +2,20 @@ module Localization extend ActiveSupport::Concern included do - before_action :set_locale + around_action :switch_locale protected - def set_locale - I18n.locale = params[:locale] || I18n.default_locale + def switch_locale(&action) + locale = extract_locale_from_param || I18n.default_locale + + I18n.with_locale(locale, &action) + end + + def extract_locale_from_param + return params[:locale] if I18n.locale_available?(params[:locale]) + + nil end private diff --git a/config/application.yml.tt b/config/application.yml.tt index 516eabe1..e0153b04 100644 --- a/config/application.yml.tt +++ b/config/application.yml.tt @@ -6,6 +6,9 @@ default: &default MAILER_DEFAULT_HOST: "localhost" MAILER_DEFAULT_PORT: "3000" MAILER_SENDER: "Test " + AVAILABLE_LOCALES: "en" + DEFAULT_LOCALE: "en" + FALLBACK_LOCALES: "en" development: <<: *default diff --git a/config/environments/production.rb b/config/environments/production.rb index 1f281dd1..92555b19 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -12,3 +12,22 @@ } EOT end + +# Remove the incorrect fallback configuration (was generated by Rails) +# https://github.com/ruby-i18n/i18n/releases/tag/v1.1.0 +gsub_file('config/environments/production.rb', 'config.i18n.fallbacks = true', '') + +# Adding the correct fallback configuration along with default locale and available locales +environment do + <<~EOT + # eg: AVAILABLE_LOCALES = 'en,th' + config.i18n.available_locales = ENV.fetch('AVAILABLE_LOCALES').split(',') + + # eg: DEFAULT_LOCALE = 'en' + config.i18n.default_locale = ENV.fetch('DEFAULT_LOCALE') + + # eg: FALLBACK_LOCALES = 'en,th' + config.i18n.fallbacks = ENV.fetch('FALLBACK_LOCALES').split(',') + + EOT +end