module I18n::Backend::Base
def available_locales
Returns an array of locales for which translations are available
def available_locales raise NotImplementedError end
def default(locale, object, subject, options = {})
first translation that can be resolved. Otherwise it tries to resolve
If given subject is an Array, it walks the array and returns the
Evaluates defaults.
def default(locale, object, subject, options = {}) options = options.dup.reject { |key, value| key == :default } case subject when Array subject.each do |item| result = resolve(locale, object, item, options) and return result end and nil else resolve(locale, object, subject, options) end end
def interpolate(locale, string, values = {})
the {{...}} key in a string (once for the string and once for the
Note that you have to double escape the \\ when you want to escape
# => "file test.txt opened by %{user}"
interpolate "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X'
Interpolates values into a given string.
def interpolate(locale, string, values = {}) return string unless string.is_a?(::String) && !values.empty? values.each do |key, value| value = value.call(values) if interpolate_lambda?(value, string, key) value = value.to_s unless value.is_a?(::String) values[key] = value end string % values rescue KeyError => e if string =~ RESERVED_KEYS_PATTERN raise ReservedInterpolationKey.new($1.to_sym, string) else raise MissingInterpolationArgument.new(values, string) end end
def interpolate_lambda?(object, string, key)
returns true when the given value responds to :call and the key is
def interpolate_lambda?(object, string, key) object.respond_to?(:call) && string =~ /%\{#{key}\}|%\<#{key}>.*?\d*\.?\d*[bBdiouxXeEfgGcps]\}/ end
def load_file(filename)
data to the existing translations. Raises I18n::UnknownFileType
#load_yml depending on the file extension and directly merges the
Loads a single translations file by delegating to #load_rb or
def load_file(filename) type = File.extname(filename).tr('.', '').downcase raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true) data = send(:"load_#{type}", filename) raise InvalidLocaleData.new(filename) unless data.is_a?(Hash) data.each { |locale, d| store_translations(locale, d || {}) } end
def load_rb(filename)
Loads a plain Ruby translations file. eval'ing the file must yield
def load_rb(filename) eval(IO.read(filename), binding, filename) end
def load_translations(*filenames)
plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
Accepts a list of paths to translation files. Loads translations from
def load_translations(*filenames) filenames = I18n.load_path.flatten if filenames.empty? filenames.each { |filename| load_file(filename) } end
def load_yml(filename)
Loads a YAML translations file. The data must have locales as
def load_yml(filename) YAML.load_file(filename) end
def localize(locale, object, format = :default, options = {})
format string. Takes a key from the date/time formats translations as
Acts the same as +strftime+, but uses a localized version of the
def localize(locale, object, format = :default, options = {}) raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime) if Symbol === format key = format type = object.respond_to?(:sec) ? 'time' : 'date' options = options.merge(:raise => true, :object => object, :locale => locale) format = I18n.t(:"#{type}.formats.#{key}", options) end # format = resolve(locale, object, format, options) format = format.to_s.gsub(/%[aAbBp]/) do |match| case match when '%a' then I18n.t(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday] when '%A' then I18n.t(:"date.day_names", :locale => locale, :format => format)[object.wday] when '%b' then I18n.t(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon] when '%B' then I18n.t(:"date.month_names", :locale => locale, :format => format)[object.mon] when '%p' then I18n.t(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format) if object.respond_to? :hour end end object.strftime(format) end
def lookup(locale, key, scope = [], options = {})
def lookup(locale, key, scope = [], options = {}) raise NotImplementedError end
def pluralize(locale, entry, count)
and the second translation if it is equal to 1. Other backends can
rules. It will pick the first translation if count is not equal to 1
Picks a translation from an array according to English pluralization
def pluralize(locale, entry, count) return entry unless entry.is_a?(Hash) && count key = :zero if count == 0 && entry.has_key?(:zero) key ||= count == 1 ? :one : :other raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key) entry[key] end
def reload!
def reload! @skip_syntax_deprecation = false end
def resolve(locale, object, subject, options = {})
given options. If it is a Proc then it will be evaluated. All other
If the given subject is a Symbol, it will be translated with the
Resolves a translation.
def resolve(locale, object, subject, options = {}) return subject if options[:resolve] == false case subject when Symbol I18n.translate(subject, options.merge(:locale => locale, :raise => true)) when Proc date_or_time = options.delete(:object) || object resolve(locale, object, subject.call(date_or_time, options)) else subject end rescue MissingTranslationData nil end
def store_translations(locale, data, options = {})
This method receives a locale, a data hash and options for storing translations.
def store_translations(locale, data, options = {}) raise NotImplementedError end
def translate(locale, key, options = {})
def translate(locale, key, options = {}) raise InvalidLocale.new(locale) unless locale entry = key && lookup(locale, key, options[:scope], options) if options.empty? entry = resolve(locale, key, entry, options) else count, default = options.values_at(:count, :default) values = options.except(*RESERVED_KEYS) entry = entry.nil? && default ? default(locale, key, default, options) : resolve(locale, key, entry, options) end raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil? entry = entry.dup if entry.is_a?(String) entry = pluralize(locale, entry, count) if count entry = interpolate(locale, entry, values) if values entry end
def warn_syntax_deprecation!(locale, string) #:nodoc:
def warn_syntax_deprecation!(locale, string) #:nodoc: return if @skip_syntax_deprecation warn "The {{key}} interpolation syntax in I18n messages is deprecated. Please use %{key} instead.\n#{locale} - #{string}\n" @skip_syntax_deprecation = true end