Class: Hanami::Providers::I18n::Backend
- Inherits:
-
Object
- Object
- Hanami::Providers::I18n::Backend
- Defined in:
- lib/hanami/providers/i18n/backend.rb
Overview
A wrapper that provides a full I18n-like interface for an individual I18n backend. This
allows each Hanami slice to have its own isolated I18n instance.
Unlike the global I18n module which uses class variables for configuration, this wrapper maintains per-instance state for true isolation between slices.
Instance Attribute Summary collapse
- #backend ⇒ Object readonly
-
#default_locale ⇒ Symbol
readonly
Returns the default locale.
Instance Method Summary collapse
-
#available_locales ⇒ Object
Returns available locales.
-
#eager_load! ⇒ void
Eager loads translations if the backend supports it.
-
#exists?(key, locale: nil, **options) ⇒ Boolean
Returns true if a translation exists for the given key.
-
#initialize(backend, locale: nil, default_locale: :en, available_locales: [], fallbacks: nil) ⇒ Backend
constructor
private
Creates a new Backend instance.
-
#locale ⇒ Symbol
Returns the current locale from fiber/thread-local storage, or default_locale.
-
#locale=(value) ⇒ Symbol?
Sets the current locale in fiber/thread-local storage.
-
#localize(object, locale: nil, format: :default, **options) ⇒ String
(also: #l)
Localizes the given date or time.
-
#reload! ⇒ void
Reloads translations from translation files.
-
#translate(key, **options) ⇒ String, Object
(also: #t)
Translates the given key.
-
#translate!(key, **options) ⇒ String, Object
(also: #t!)
Translates the given key, raising an exception if translation is missing.
-
#transliterate(key, locale: nil, replacement: nil, **options) ⇒ String
Transliterates the given string.
-
#with_locale(tmp_locale) ⇒ Object
Executes a block with a temporary locale.
Constructor Details
#initialize(backend, locale: nil, default_locale: :en, available_locales: [], fallbacks: nil) ⇒ Backend
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Creates a new Backend instance.
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/hanami/providers/i18n/backend.rb', line 35 def initialize(backend, locale: nil, default_locale: :en, available_locales: [], fallbacks: nil) @backend = backend @default_locale = default_locale.to_sym @available_locales = Array(available_locales).map(&:to_sym) @fallbacks = fallbacks # Set initial locale (if provided) in thread-local storage. @storage_key = :"hanami_i18n_#{object_id}" self.locale = locale if locale end |
Instance Attribute Details
#backend ⇒ Object (readonly)
15 16 17 |
# File 'lib/hanami/providers/i18n/backend.rb', line 15 def backend @backend end |
#default_locale ⇒ Symbol (readonly)
Returns the default locale.
23 24 25 |
# File 'lib/hanami/providers/i18n/backend.rb', line 23 def default_locale @default_locale end |
Instance Method Details
#available_locales ⇒ Object
Returns available locales.
If configured via config.i18n.available_locales, returns the configured locales.
Otherwise, returns all locales detected from loaded translation files.
227 228 229 230 231 232 233 |
# File 'lib/hanami/providers/i18n/backend.rb', line 227 def available_locales if @available_locales.any? @available_locales else @backend.available_locales end end |
#eager_load! ⇒ void
This method returns an undefined value.
Eager loads translations if the backend supports it.
251 252 253 |
# File 'lib/hanami/providers/i18n/backend.rb', line 251 def eager_load! @backend.eager_load! if @backend.respond_to?(:eager_load!) end |
#exists?(key, locale: nil, **options) ⇒ Boolean
Returns true if a translation exists for the given key.
196 197 198 199 |
# File 'lib/hanami/providers/i18n/backend.rb', line 196 def exists?(key, locale: nil, **) locale ||= self.locale @backend.exists?(locale, key, ) end |
#locale ⇒ Symbol
Returns the current locale from fiber/thread-local storage, or default_locale.
This is thread-safe and works correctly with concurrent requests. Each backend instance maintains its own locale in thread storage.
269 270 271 |
# File 'lib/hanami/providers/i18n/backend.rb', line 269 def locale Thread.current[@storage_key] || default_locale end |
#locale=(value) ⇒ Symbol?
Sets the current locale in fiber/thread-local storage.
This is thread-safe and works correctly with concurrent requests. Each backend instance maintains its own locale in thread storage.
289 290 291 |
# File 'lib/hanami/providers/i18n/backend.rb', line 289 def locale=(value) Thread.current[@storage_key] = value&.to_sym end |
#localize(object, locale: nil, format: :default, **options) ⇒ String Also known as: l
Localizes the given date or time.
Resolves symbol formats through this instance's translations (e.g. :short becomes
date.formats.short or time.formats.short). Also resolves locale-dependent strftime
codes (e.g. %a, %A, %b, %B, %p, %P).
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/hanami/providers/i18n/backend.rb', line 155 def localize(object, locale: nil, format: :default, **) locale ||= self.locale return [:default] if object.nil? && .key?(:default) unless object.respond_to?(:strftime) raise ArgumentError, <<~MSG Object must be a Date, DateTime or Time object. #{object.inspect} given. MSG end if format.is_a?(Symbol) type = object.respond_to?(:sec) ? "time" : "date" format = translate( :"#{type}.formats.#{format}", **, locale:, object:, raise: true ) end format = (locale, object, format) object.strftime(format) end |
#reload! ⇒ void
This method returns an undefined value.
Reloads translations from translation files.
241 242 243 |
# File 'lib/hanami/providers/i18n/backend.rb', line 241 def reload! @backend.reload! end |
#translate(key, **options) ⇒ String, Object Also known as: t
Translates the given key.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/hanami/providers/i18n/backend.rb', line 73 def translate(key, **) locale = [:locale] || self.locale result = catch(:exception) do @backend.translate(locale, key, ) end # If translation is missing and fallbacks are configured, try fallback locales if result.is_a?(::I18n::MissingTranslation) && @fallbacks && ![:fallback] fallback_locales = @fallbacks[locale] - [locale] fallback_locales.each do |fallback_locale| fallback_result = catch(:exception) do @backend.translate(fallback_locale, key, .merge(fallback: true)) end unless fallback_result.is_a?(::I18n::MissingTranslation) return fallback_result end end end if result.is_a?(::I18n::MissingTranslation) if [:raise] raise ::I18n::MissingTranslationData.new(locale, key, ) else handle_missing_translation(result, ) end else result end end |
#translate!(key, **options) ⇒ String, Object Also known as: t!
Translates the given key, raising an exception if translation is missing.
126 127 128 |
# File 'lib/hanami/providers/i18n/backend.rb', line 126 def translate!(key, **) translate(key, **.merge(raise: true)) end |
#transliterate(key, locale: nil, replacement: nil, **options) ⇒ String
Transliterates the given string.
215 216 217 218 |
# File 'lib/hanami/providers/i18n/backend.rb', line 215 def transliterate(key, locale: nil, replacement: nil, **) locale ||= self.locale @backend.transliterate(locale, key, replacement) end |
#with_locale(tmp_locale) ⇒ Object
Executes a block with a temporary locale.
This is useful for executing code with a specific locale without affecting other concurrent requests. The previous locale is restored even if the block raises.
320 321 322 323 324 325 326 |
# File 'lib/hanami/providers/i18n/backend.rb', line 320 def with_locale(tmp_locale) previous_locale = Thread.current[@storage_key] Thread.current[@storage_key] = tmp_locale&.to_sym yield ensure Thread.current[@storage_key] = previous_locale end |