Module: I18nJS
- Defined in:
- lib/i18n-js.rb,
lib/i18n-js/cli.rb,
lib/i18n-js/cli/ui.rb,
lib/i18n-js/listen.rb,
lib/i18n-js/plugin.rb,
lib/i18n-js/schema.rb,
lib/i18n-js/version.rb,
lib/i18n-js/sort_hash.rb,
lib/i18n-js/clean_hash.rb,
lib/i18n-js/cli/command.rb,
lib/i18n-js/cli/init_command.rb,
lib/i18n-js/cli/check_command.rb,
lib/i18n-js/cli/export_command.rb,
lib/i18n-js/cli/plugins_command.rb,
lib/i18n-js/cli/version_command.rb,
lib/i18n-js/export_files_plugin.rb,
lib/i18n-js/cli/lint_scripts_command.rb,
lib/i18n-js/cli/lint_translations_command.rb,
lib/i18n-js/embed_fallback_translations_plugin.rb
Defined Under Namespace
Classes: CLI, EmbedFallbackTranslationsPlugin, ExportFilesPlugin, Plugin, Schema
Constant Summary collapse
- MissingConfigError =
Class.new(StandardError)
- VERSION =
"4.2.3"
Class Attribute Summary collapse
-
.started ⇒ Object
Returns the value of attribute started.
Class Method Summary collapse
- .available_plugins ⇒ Object
- .call(config_file: nil, config: nil) ⇒ Object
- .capture ⇒ Object
- .clean_hash(hash) ⇒ Object
- .compute_changes(paths, changed, added, removed) ⇒ Object
- .debug(message) ⇒ Object
- .export_group(group) ⇒ Object
- .included_on_watched_paths(paths, changes) ⇒ Object
- .initialize_plugins!(config:) ⇒ Object
- .listen(config_file: Rails.root.join("config/i18n.yml"), locales_dir: Rails.root.join("config/locales"), run_on_start: true, options: {}) ⇒ Object
- .listener(config_file, locales_dirs, options) ⇒ Object
- .load_config_file(config_file) ⇒ Object
- .load_plugins! ⇒ Object
- .logger ⇒ Object
- .plugin_files ⇒ Object
- .plugins ⇒ Object
- .register_plugin(plugin) ⇒ Object
- .relative_path(path) ⇒ Object
- .relative_path_list(paths) ⇒ Object
- .sort_hash(hash) ⇒ Object
- .translations ⇒ Object
- .write_file(file_path, translations) ⇒ Object
Class Attribute Details
.started ⇒ Object
Returns the value of attribute started.
5 6 7 |
# File 'lib/i18n-js/listen.rb', line 5 def started @started end |
Class Method Details
.available_plugins ⇒ Object
6 7 8 |
# File 'lib/i18n-js/plugin.rb', line 6 def self.available_plugins @available_plugins ||= Set.new end |
.call(config_file: nil, config: nil) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/i18n-js.rb', line 22 def self.call(config_file: nil, config: nil) if !config_file && !config raise MissingConfigError, "you must set either `config_file` or `config`" end config = Glob::SymbolizeKeys.call(config || load_config_file(config_file)) load_plugins! initialize_plugins!(config: config) Schema.validate!(config) exported_files = [] config[:translations].each {|group| exported_files += export_group(group) } plugins.each do |plugin| plugin.after_export(files: exported_files.dup) if plugin.enabled? end exported_files end |
.capture ⇒ Object
71 72 73 74 75 76 77 78 79 |
# File 'lib/i18n-js/listen.rb', line 71 def self.capture original = $stdout $stdout = StringIO.new yield rescue StandardError # noop ensure $stdout = original end |
.clean_hash(hash) ⇒ Object
4 5 6 7 8 9 10 11 12 |
# File 'lib/i18n-js/clean_hash.rb', line 4 def self.clean_hash(hash) hash.keys.each_with_object({}) do |key, buffer| value = hash[key] next if value.is_a?(Proc) buffer[key] = value.is_a?(Hash) ? clean_hash(value) : value end end |
.compute_changes(paths, changed, added, removed) ⇒ Object
81 82 83 84 85 86 87 88 89 |
# File 'lib/i18n-js/listen.rb', line 81 def self.compute_changes(paths, changed, added, removed) paths = paths.map {|path| relative_path(path) } { changed: included_on_watched_paths(paths, changed), added: included_on_watched_paths(paths, added), removed: included_on_watched_paths(paths, removed) }.select {|_k, v| v.any? } end |
.debug(message) ⇒ Object
42 43 44 |
# File 'lib/i18n-js/listen.rb', line 42 def self.debug() logger.tagged("i18n-js") { logger.debug() } end |
.export_group(group) ⇒ Object
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 |
# File 'lib/i18n-js.rb', line 45 def self.export_group(group) filtered_translations = Glob.filter(translations, group[:patterns]) filtered_translations = plugins.reduce(filtered_translations) do |buffer, plugin| if plugin.enabled? plugin.transform(translations: buffer) else buffer end end filtered_translations = sort_hash(clean_hash(filtered_translations)) output_file_path = File.(group[:file]) exported_files = [] if output_file_path.include?(":locale") filtered_translations.each_key do |locale| locale_file_path = output_file_path.gsub(/:locale/, locale.to_s) exported_files << write_file(locale_file_path, locale => filtered_translations[locale]) end else exported_files << write_file(output_file_path, filtered_translations) end exported_files end |
.included_on_watched_paths(paths, changes) ⇒ Object
91 92 93 94 95 |
# File 'lib/i18n-js/listen.rb', line 91 def self.included_on_watched_paths(paths, changes) changes.map {|change| relative_path(change) }.select do |change| paths.any? {|path| change.start_with?(path) } end end |
.initialize_plugins!(config:) ⇒ Object
28 29 30 31 32 |
# File 'lib/i18n-js/plugin.rb', line 28 def self.initialize_plugins!(config:) @plugins = available_plugins.map do |plugin| plugin.new(config: config).tap(&:setup) end end |
.listen(config_file: Rails.root.join("config/i18n.yml"), locales_dir: Rails.root.join("config/locales"), run_on_start: true, options: {}) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/i18n-js/listen.rb', line 8 def self.listen( config_file: Rails.root.join("config/i18n.yml"), locales_dir: Rails.root.join("config/locales"), run_on_start: true, options: {} ) return unless Rails.env.development? return if started gem "listen" require "listen" require "i18n-js" self.started = true locales_dirs = Array(locales_dir).map {|path| File.(path) } relative_paths = [config_file, *locales_dirs].map {|path| relative_path(path) } debug("Watching #{relative_paths.inspect}") listener(config_file, locales_dirs.map(&:to_s), ).start I18nJS.call(config_file: config_file) if run_on_start end |
.listener(config_file, locales_dirs, options) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/i18n-js/listen.rb', line 50 def self.listener(config_file, locales_dirs, ) paths = [File.dirname(config_file), *locales_dirs] Listen.to(*paths, ) do |changed, added, removed| changes = compute_changes( [config_file, *locales_dirs], changed, added, removed ) next unless changes.any? debug(changes.map {|key, value| "#{key}=#{value.inspect}" }.join(", ")) capture do system "i18n", "export", "--config", config_file.to_s end end end |
.load_config_file(config_file) ⇒ Object
103 104 105 106 |
# File 'lib/i18n-js.rb', line 103 def self.load_config_file(config_file) erb = ERB.new(File.read(config_file)) YAML.safe_load(erb.result(binding)) end |
.load_plugins! ⇒ Object
22 23 24 25 26 |
# File 'lib/i18n-js/plugin.rb', line 22 def self.load_plugins! plugin_files.each do |path| require path end end |
.logger ⇒ Object
46 47 48 |
# File 'lib/i18n-js/listen.rb', line 46 def self.logger @logger ||= ActiveSupport::TaggedLogging.new(Rails.logger) end |
.plugin_files ⇒ Object
18 19 20 |
# File 'lib/i18n-js/plugin.rb', line 18 def self.plugin_files Gem.find_files("i18n-js/*_plugin.rb") end |
.plugins ⇒ Object
10 11 12 |
# File 'lib/i18n-js/plugin.rb', line 10 def self.plugins @plugins ||= [] end |
.register_plugin(plugin) ⇒ Object
14 15 16 |
# File 'lib/i18n-js/plugin.rb', line 14 def self.register_plugin(plugin) available_plugins << plugin end |
.relative_path(path) ⇒ Object
34 35 36 |
# File 'lib/i18n-js/listen.rb', line 34 def self.relative_path(path) Pathname.new(path).relative_path_from(Rails.root).to_s end |
.relative_path_list(paths) ⇒ Object
38 39 40 |
# File 'lib/i18n-js/listen.rb', line 38 def self.relative_path_list(paths) paths.map {|path| relative_path(path) } end |
.sort_hash(hash) ⇒ Object
4 5 6 7 8 9 10 11 |
# File 'lib/i18n-js/sort_hash.rb', line 4 def self.sort_hash(hash) return hash unless hash.is_a?(Hash) hash.keys.sort_by(&:to_s).each_with_object({}) do |key, seed| value = hash[key] seed[key] = value.is_a?(Hash) ? sort_hash(value) : value end end |
.translations ⇒ Object
94 95 96 97 98 99 100 101 |
# File 'lib/i18n-js.rb', line 94 def self.translations ::I18n.backend.instance_eval do has_been_initialized_before = respond_to?(:initialized?, true) && initialized? init_translations unless has_been_initialized_before translations end end |
.write_file(file_path, translations) ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/i18n-js.rb', line 73 def self.write_file(file_path, translations) FileUtils.mkdir_p(File.dirname(file_path)) contents = ::JSON.pretty_generate(translations) digest = Digest::MD5.hexdigest(contents) file_path = file_path.gsub(/:digest/, digest) # Don't rewrite the file if it already exists and has the same content. # It helps the asset pipeline or webpack understand that file wasn't # changed. if File.exist?(file_path) && File.read(file_path) == contents return file_path end File.open(file_path, "w") do |file| file << contents end file_path end |