Class: ReactOnRails::Locales::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/react_on_rails/locales/base.rb,
sig/react_on_rails/locales.rbs

Direct Known Subclasses

ToJs, ToJson

Instance Method Summary collapse

Constructor Details

#initialize(force: false) ⇒ Base

Returns a new instance of Base.

Parameters:

  • force: (Boolean) (defaults to: false)


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/react_on_rails/locales/base.rb', line 54

def initialize(force: false)
  return if i18n_dir.nil?

  if locale_files.empty?
    puts "Warning: No locale files found in #{i18n_yml_dir || 'Rails i18n load path'}"
    return
  end

  if !force && !obsolete?
    puts "Locale files are up to date, skipping generation. " \
         "Use 'rake react_on_rails:locale force=true' to force regeneration."
    return
  end

  @translations, @defaults = generate_translations
  convert
  puts "Generated locale files in #{i18n_dir}"
end

Instance Method Details

#convertvoid

This method returns an undefined value.



133
134
135
136
137
138
139
# File 'lib/react_on_rails/locales/base.rb', line 133

def convert
  file_names.each do |name|
    template = send(:"template_#{name}")
    path = file(name)
    generate_file(template, path)
  end
end

#default_localeString

Returns:

  • (String)


129
130
131
# File 'lib/react_on_rails/locales/base.rb', line 129

def default_locale
  @default_locale ||= I18n.default_locale.to_s || "en"
end

#exist_filesArray[String]

Returns:



89
90
91
# File 'lib/react_on_rails/locales/base.rb', line 89

def exist_files
  @exist_files ||= files.select { |file| File.exist?(file) }
end

#file(name) ⇒ String

Parameters:

  • name (String)

Returns:

  • (String)


107
108
109
# File 'lib/react_on_rails/locales/base.rb', line 107

def file(name)
  "#{i18n_dir}/#{name}.#{file_format}"
end

#file_formatString?

Returns:

  • (String, nil)


75
# File 'lib/react_on_rails/locales/base.rb', line 75

def file_format; end

#file_namesArray[String]

Returns:



99
100
101
# File 'lib/react_on_rails/locales/base.rb', line 99

def file_names
  %w[translations default]
end

#filesArray[String]

Returns:



103
104
105
# File 'lib/react_on_rails/locales/base.rb', line 103

def files
  @files ||= file_names.map { |n| file(n) }
end

#files_are_outdatedBoolean

Returns:

  • (Boolean)


93
94
95
96
97
# File 'lib/react_on_rails/locales/base.rb', line 93

def files_are_outdated
  latest_yml = locale_files.map { |file| File.mtime(file) }.max
  earliest = exist_files.map { |file| File.mtime(file) }.min
  latest_yml > earliest
end

#flatten(translations) ⇒ Hash[Symbol, untyped]

Parameters:

  • translations (Hash[untyped, untyped])

Returns:

  • (Hash[Symbol, untyped])


176
177
178
179
180
181
182
183
184
185
186
# File 'lib/react_on_rails/locales/base.rb', line 176

def flatten(translations)
  translations.each_with_object({}) do |(k, v), h|
    if v.is_a? Hash
      flatten(v).map { |hk, hv| h[:"#{k}.#{hk}"] = hv }
    elsif v.is_a?(String)
      h[k] = v.gsub("%{", "{")
    elsif !v.is_a?(Array)
      h[k] = v
    end
  end
end

#flatten_defaults(val) ⇒ Hash[Symbol, Hash[Symbol, untyped]]

Parameters:

  • val (Hash[untyped, untyped])

Returns:

  • (Hash[Symbol, Hash[Symbol, untyped]])


169
170
171
172
173
174
# File 'lib/react_on_rails/locales/base.rb', line 169

def flatten_defaults(val)
  flatten(val).each_with_object({}) do |(k, v), h|
    key = format(k)
    h[key] = { id: k, defaultMessage: v }
  end
end

#format(input) ⇒ Symbol

Parameters:

  • input (Object)

Returns:

  • (Symbol)


165
166
167
# File 'lib/react_on_rails/locales/base.rb', line 165

def format(input)
  input.to_s.tr(".", "_").camelize(:lower).to_sym
end

#generate_file(template, path) ⇒ void

This method returns an undefined value.

Parameters:

  • template (String)
  • path (String)


141
142
143
144
# File 'lib/react_on_rails/locales/base.rb', line 141

def generate_file(template, path)
  result = ERB.new(template).result
  File.write(path, result)
end

#generate_translations[String, String]

Returns:

  • ([String, String])


146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/react_on_rails/locales/base.rb', line 146

def generate_translations
  translations = {}
  defaults = {}
  locale_files.each do |f|
    safe_load_options = ReactOnRails.configuration.i18n_yml_safe_load_options || {}
    translation = YAML.safe_load(File.open(f), **safe_load_options)
    key = translation.keys[0]
    val = flatten(translation[key])
    translations = translations.deep_merge(key => val)
    defaults = defaults.deep_merge(flatten_defaults(val)) if key == default_locale
  rescue Psych::Exception => e
    raise ReactOnRails::Error, <<~MSG
      Error parsing #{f}: #{e.message}
      Consider fixing unsafe YAML or permitting with config.i18n_yml_safe_load_options
    MSG
  end
  [translations.to_json, defaults.to_json]
end

#i18n_dirString?

Returns:

  • (String, nil)


121
122
123
# File 'lib/react_on_rails/locales/base.rb', line 121

def i18n_dir
  @i18n_dir ||= ReactOnRails.configuration.i18n_dir
end

#i18n_yml_dirString?

Returns:

  • (String, nil)


125
126
127
# File 'lib/react_on_rails/locales/base.rb', line 125

def i18n_yml_dir
  @i18n_yml_dir ||= ReactOnRails.configuration.i18n_yml_dir
end

#locale_filesArray[String]

Returns:



111
112
113
114
115
116
117
118
119
# File 'lib/react_on_rails/locales/base.rb', line 111

def locale_files
  @locale_files ||= if i18n_yml_dir.present?
                      Dir["#{i18n_yml_dir}/**/*.yml"]
                    else
                      ReactOnRails::Utils.truthy_presence(
                        Rails.application && Rails.application.config.i18n.load_path
                      ).presence
                    end
end

#obsolete?Boolean

Returns:

  • (Boolean)


77
78
79
80
81
82
83
# File 'lib/react_on_rails/locales/base.rb', line 77

def obsolete?
  return true if exist_files.length != files.length # Some files missing
  return true if exist_files.empty?
  return true if generated_files_obsolete?

  files_are_outdated
end

#template_defaultString

Returns:

  • (String)


194
195
196
197
198
199
200
201
202
# File 'lib/react_on_rails/locales/base.rb', line 194

def template_default
  <<~JS
    const defaultLocale = #{default_locale.to_json};

    const defaultMessages = #{@defaults};

    export { defaultMessages, defaultLocale };
  JS
end

#template_translationsString

Returns:

  • (String)


188
189
190
191
192
# File 'lib/react_on_rails/locales/base.rb', line 188

def template_translations
  <<~JS
    export const translations = #{@translations};
  JS
end