FEATURE: Localization fallbacks (server-side)#9
Conversation
The FallbackLocaleList object tells I18n::Backend::Fallbacks what order the languages should be attempted in. Because of the translate_accelerator patch, the SiteSetting.default_locale is *not* guaranteed to be fully loaded after the server starts, so a call to ensure_loaded! is added after the locale is set for the current user. The declarations of config.i18n.fallbacks = true in the environment files were actually garbage, because the I18n.default_locale was SiteSetting.default_locale, so there was nothing to fall back to. *derp*
There was a problem hiding this comment.
Pull Request Overview
Implements server-side localization fallbacks to improve internationalization by replacing Rails' built-in fallback mechanism with a custom implementation. This change allows for more flexible fallback logic and better handling of missing translations across different locales.
- Introduces custom fallback logic that prioritizes user locale, then site default locale, then English
- Moves pluralization configuration from a separate initializer into the main i18n configuration
- Removes Rails' built-in fallback configuration from environment files
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/freedom_patches/translate_accelerator.rb | Adds ensure_loaded! method to support locale preloading |
| config/initializers/i18n.rb | Creates new i18n configuration with custom FallbackLocaleList class |
| config/initializers/pluralization.rb | Removes separate pluralization initializer (moved to i18n.rb) |
| config/environments/profile.rb | Removes Rails built-in fallback configuration |
| config/environments/production.rb | Removes Rails built-in fallback configuration |
| config/cloud/cloud66/files/production.rb | Removes Rails built-in fallback configuration |
| app/controllers/application_controller.rb | Adds call to ensure fallback locales are loaded |
|
|
||
| def ensure_loaded!(locale) | ||
| @loaded_locales ||= [] | ||
| load_locale locale unless @loaded_locales.include?(locale) |
There was a problem hiding this comment.
The method calls load_locale without checking if @loaded_locales is nil, but only initializes it on line 63. If load_locale fails or throws an exception before completing, @loaded_locales might not be updated, causing potential issues on subsequent calls.
| end | ||
|
|
||
| def ensure_loaded! | ||
| self[I18n.locale].each { |l| I18n.ensure_loaded! l } |
There was a problem hiding this comment.
This calls I18n.ensure_loaded! but the method is defined as ensure_loaded! on the translate accelerator, not on the I18n module itself. This will likely result in a NoMethodError.
| self[I18n.locale].each { |l| I18n.ensure_loaded! l } | |
| self[I18n.locale].each { |l| TranslateAccelerator.ensure_loaded! l } |
| def [](locale) | ||
| # user locale, site locale, english | ||
| # TODO - this can be extended to be per-language for a better user experience | ||
| # (e.g. fallback zh_TW to zh_CN / vice versa) | ||
| [locale, SiteSetting.default_locale.to_sym, :en].uniq.compact |
There was a problem hiding this comment.
This array is created on every access to the fallback list. Consider memoizing the result or caching it to avoid repeated array creation and method calls.
| def [](locale) | |
| # user locale, site locale, english | |
| # TODO - this can be extended to be per-language for a better user experience | |
| # (e.g. fallback zh_TW to zh_CN / vice versa) | |
| [locale, SiteSetting.default_locale.to_sym, :en].uniq.compact | |
| def initialize | |
| super | |
| @cache = {} | |
| end | |
| def [](locale) | |
| # user locale, site locale, english | |
| # TODO - this can be extended to be per-language for a better user experience | |
| # (e.g. fallback zh_TW to zh_CN / vice versa) | |
| @cache[locale] ||= [locale, SiteSetting.default_locale.to_sym, :en].uniq.compact |
|
This pull request has been automatically marked as stale because it has been open for 60 days with no activity. To keep it open, remove the stale tag, push code, or add a comment. Otherwise, it will be closed in 14 days. |
Test 9