Class: I18n::Backend::Database

Inherits:
Object
  • Object
show all
Defined in:
lib/i18n_backend_database/database.rb

Constant Summary collapse

INTERPOLATION_RESERVED_KEYS =
%w(scope default)
MATCH =
/(\\\\)?\{\{([^\}]+)\}\}/

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Database

Returns a new instance of Database.



12
13
14
15
16
17
# File 'lib/i18n_backend_database/database.rb', line 12

def initialize(options = {})
  store = options.delete(:cache_store)
  text_tag = options.delete(:localize_text_tag)
  @cache_store = store ? ActiveSupport::Cache.lookup_store(store) : Rails.cache
  @localize_text_tag = text_tag ? text_tag : '^^'
end

Instance Attribute Details

#cache_storeObject

Returns the value of attribute cache_store.



9
10
11
# File 'lib/i18n_backend_database/database.rb', line 9

def cache_store
  @cache_store
end

#localeObject

Returns the value of attribute locale.



8
9
10
# File 'lib/i18n_backend_database/database.rb', line 8

def locale
  @locale
end

#localize_text_tagObject

Returns the value of attribute localize_text_tag.



10
11
12
# File 'lib/i18n_backend_database/database.rb', line 10

def localize_text_tag
  @localize_text_tag
end

Instance Method Details

#available_localesObject



128
129
130
# File 'lib/i18n_backend_database/database.rb', line 128

def available_locales
  Locale.available_locales
end

#localize(locale, object, format = :default) ⇒ Object

Acts the same as strftime, but returns a localized version of the formatted date string. Takes a key from the date/time formats translations as a format argument (e.g., :short in :'date.formats').

Raises:

  • (ArgumentError)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/i18n_backend_database/database.rb', line 101

def localize(locale, object, format = :default)
  raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
  
  type = object.respond_to?(:sec) ? 'time' : 'date'
  format = translate(locale, "#{type}.formats.#{format.to_s}") unless format.to_s.index('%') # lookup keyed formats unless a custom format is passed

  format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday]) 
  format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
  format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
  format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
  format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
  
  object.strftime(format)
end

#localize_text(locale, text) ⇒ Object

Returns the text string with the text within the localize text tags translated.



117
118
119
120
121
122
123
124
125
126
# File 'lib/i18n_backend_database/database.rb', line 117

def localize_text(locale, text)
  text_tag    = Regexp.escape(localize_text_tag).to_s
  expression  = Regexp.new(text_tag + "(.*?)" + text_tag)
  tagged_text = text[expression, 1]
  while tagged_text do
    text = text.sub(expression, translate(locale, tagged_text))
    tagged_text = text[expression, 1]
  end
  return text
end

#reload!Object



132
133
134
135
# File 'lib/i18n_backend_database/database.rb', line 132

def reload!
  # get's called on initialization
  # let's not do anything yet
end

#translate(locale, key, options = {}) ⇒ Object

Handles the lookup and addition of translations to the database

On an initial translation, the locale is checked to determine if this is the default locale. If it is, we’ll create a complete translation record for this locale with both the key and value.

If the current locale is checked, and it differs from the default locale, we’ll create a translation record with a nil value. This allows for the lookup of untranslated records in a given locale.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/i18n_backend_database/database.rb', line 36

def translate(locale, key, options = {})
  @locale = locale_in_context(locale)

  options[:scope] = [options[:scope]] unless options[:scope].is_a?(Array) || options[:scope].blank?
  key = "#{options[:scope].join('.')}.#{key}".to_sym if options[:scope] && key.is_a?(Symbol)
  count = options[:count]
  # pull out values for interpolation
  values = options.reject { |name, value| [:scope, :default].include?(name) }

  entry = lookup(@locale, key)
  cache_lookup = true unless entry.nil?

  # if no entry exists for the current locale and the current locale is not the default locale then lookup translations for the default locale for this key
  unless entry || @locale.default_locale?
    entry = use_and_copy_default_locale_translations_if_they_exist(@locale, key)
  end

  # if we have no entry and some defaults ... start looking them up
  unless entry || key.is_a?(String) || options[:default].blank?
    default = options[:default].is_a?(Array) ? options[:default].shift : options.delete(:default)
    return translate(@locale.code, default, options.dup)
  end

  # this needs to be folded into the above at some point.
  # this handles the case where the default of the string key is a space
  if !entry && key.is_a?(String) && options[:default] == " "
    default = options[:default].is_a?(Array) ? options[:default].shift : options.delete(:default)
    return translate(@locale.code, default, options.dup)
  end

  # The requested key might not be a parent node in a hierarchy of keys instead of a regular 'leaf' node
  #   that would simply result in a string return.  If so, check the database for possible children 
  #   and return them in a nested hash if we find them.
  #   We can safely ignore pluralization indeces here since they should never apply to a hash return
  if !entry && (key.is_a?(String) || key.is_a?(Symbol))
    #We need to escape % and \.  Rails will handle the rest.
    escaped_key = key.to_s.gsub('\\', '\\\\\\\\').gsub(/%/, '\%')
    children = @locale.translations.find :all, :conditions => ["raw_key like ?", "#{escaped_key}.%"]
    if children.size > 0
      entry = hashify_record_array(key.to_s, children)
      @cache_store.write(Translation.ck(@locale, key), entry) unless cache_lookup == true
      return entry
    end
  end

  # we check the database before creating a translation as we can have translations with nil values
  # if we still have no blasted translation just go and create one for the current locale!
  unless entry 
    pluralization_index = (options[:count].nil? || options[:count] == 1) ? 1 : 0
    translation =  @locale.translations.find_by_key_and_pluralization_index(Translation.hk(key), pluralization_index) ||
                   @locale.create_translation(key, key, pluralization_index)
    entry = translation.value_or_default
  end

  # write to cache unless we've already had a successful cache hit
  @cache_store.write(Translation.ck(@locale, key), entry) unless cache_lookup == true

  entry = pluralize(@locale, entry, count)
  entry = interpolate(@locale.code, entry, values)
  entry.is_a?(Array) ? entry.dup : entry # array's can get frozen with cache writes
end