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.
-
#t!(key, **options) ⇒ String, Object
Translates the given key, raising an exception if translation is missing.
-
#translate(key, **options) ⇒ String, Object
(also: #t)
Translates the given key.
-
#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.
223 224 225 226 227 228 229 |
# File 'lib/hanami/providers/i18n/backend.rb', line 223 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.
247 248 249 |
# File 'lib/hanami/providers/i18n/backend.rb', line 247 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.
192 193 194 195 |
# File 'lib/hanami/providers/i18n/backend.rb', line 192 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.
265 266 267 |
# File 'lib/hanami/providers/i18n/backend.rb', line 265 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.
285 286 287 |
# File 'lib/hanami/providers/i18n/backend.rb', line 285 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`).
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/hanami/providers/i18n/backend.rb', line 151 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.
237 238 239 |
# File 'lib/hanami/providers/i18n/backend.rb', line 237 def reload! @backend.reload! end |
#t!(key, **options) ⇒ String, Object
Translates the given key, raising an exception if translation is missing.
126 127 128 |
# File 'lib/hanami/providers/i18n/backend.rb', line 126 def t!(key, **) translate(key, **.merge(raise: true)) 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 |
#transliterate(key, locale: nil, replacement: nil, **options) ⇒ String
Transliterates the given string.
211 212 213 214 |
# File 'lib/hanami/providers/i18n/backend.rb', line 211 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.
316 317 318 319 320 321 322 |
# File 'lib/hanami/providers/i18n/backend.rb', line 316 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 |