lib/i18n/js.rb in i18n-js-3.0.0.rc8 vs lib/i18n/js.rb in i18n-js-3.0.0.rc9
- old
+ new
@@ -1,14 +1,15 @@
+require "yaml"
require "i18n"
require "fileutils"
-
require "i18n/js/utils"
module I18n
module JS
require "i18n/js/dependencies"
require "i18n/js/fallback_locales"
+ require "i18n/js/segment"
if JS::Dependencies.rails?
require "i18n/js/middleware"
require "i18n/js/engine"
end
@@ -18,70 +19,74 @@
# The configuration file. This defaults to the `config/i18n-js.yml` file.
#
def self.config_file_path
@config_file_path ||= DEFAULT_CONFIG_PATH
end
+
def self.config_file_path=(new_path)
@config_file_path = new_path
end
# Export translations to JavaScript, considering settings
# from configuration file
def self.export
export_i18n_js
- translation_segments.each do |filename, translations|
- save(translations, filename)
- end
+ translation_segments.each(&:save!)
end
- def self.segments_per_locale(pattern, scope)
- I18n.available_locales.each_with_object({}) do |locale, segments|
+ def self.segments_per_locale(pattern, scope, exceptions, options)
+ I18n.available_locales.each_with_object([]) do |locale, segments|
scope = [scope] unless scope.respond_to?(:each)
- result = scoped_translations(scope.collect{|s| "#{locale}.#{s}"})
- merge_with_fallbacks!(result, locale, scope) if use_fallbacks?
+ result = scoped_translations(scope.collect{|s| "#{locale}.#{s}"}, exceptions)
+ merge_with_fallbacks!(result, locale, scope, exceptions) if use_fallbacks?
next if result.empty?
-
- segment_name = ::I18n.interpolate(pattern,{:locale => locale})
- segments[segment_name] = result
+ segments << Segment.new(::I18n.interpolate(pattern, {:locale => locale}), result, options)
end
end
- def self.segment_for_scope(scope)
+ def self.segment_for_scope(scope, exceptions)
if scope == "*"
- translations
+ exclude(translations, exceptions)
else
- scoped_translations(scope)
+ scoped_translations(scope, exceptions)
end
end
def self.configured_segments
- config[:translations].each_with_object({}) do |options, segments|
- options.reverse_merge!(:only => "*")
- if options[:file] =~ ::I18n::INTERPOLATION_PATTERN
- segments.merge!(segments_per_locale(options[:file], options[:only]))
+ config[:translations].inject([]) do |segments, options|
+ file = options[:file]
+ only = options[:only] || '*'
+ exceptions = [options[:except] || []].flatten
+
+ segment_options = options.slice(:namespace, :pretty_print)
+
+ if file =~ ::I18n::INTERPOLATION_PATTERN
+ segments += segments_per_locale(file, only, exceptions, segment_options)
else
- result = segment_for_scope(options[:only])
- segments[options[:file]] = result unless result.empty?
+ result = segment_for_scope(only, exceptions)
+ segments << Segment.new(file, result, segment_options) unless result.empty?
end
+
+ segments
end
end
def self.filtered_translations
{}.tap do |result|
- translation_segments.each do |filename, translations|
- Utils.deep_merge!(result, translations)
+ translation_segments.each do |segment|
+ Utils.deep_merge!(result, segment.translations)
end
end
end
def self.translation_segments
if config? && config[:translations]
configured_segments
else
- {"#{DEFAULT_EXPORT_DIR_PATH}/translations.js" => translations}
+ [Segment.new("#{DEFAULT_EXPORT_DIR_PATH}/translations.js", translations)]
end
end
# Load configuration file for partial exporting and
# custom output directory
@@ -97,32 +102,34 @@
# Check if configuration file exist
def self.config?
File.file? config_file_path
end
- # Convert translations to JSON string and save file.
- def self.save(translations, file)
- FileUtils.mkdir_p File.dirname(file)
-
- File.open(file, "w+") do |f|
- f << %(I18n.translations || (I18n.translations = {});\n)
- Utils.strip_keys_with_nil_values(translations).each do |locale, translations_for_locale|
- f << %(I18n.translations["#{locale}"] = #{translations_for_locale.to_json};\n);
- end
- end
- end
-
- def self.scoped_translations(scopes) # :nodoc:
+ def self.scoped_translations(scopes, exceptions = []) # :nodoc:
result = {}
[scopes].flatten.each do |scope|
- Utils.deep_merge! result, filter(translations, scope)
+ translations_without_exceptions = exclude(translations, exceptions)
+ filtered_translations = filter(translations_without_exceptions, scope)
+
+ Utils.deep_merge! result, filtered_translations
end
result
end
+ # Exclude keys from translations listed in the `except:` section in the config file
+ def self.exclude(translations, exceptions)
+ return translations if exceptions.empty?
+
+ exceptions.inject(translations) do |memo, exception|
+ Utils.deep_reject(memo) do |key, value|
+ key.to_s == exception.to_s
+ end
+ end
+ end
+
# Filter translations according to the specified scope.
def self.filter(translations, scopes)
scopes = scopes.split(".") if scopes.is_a?(String)
scopes = scopes.clone
scope = scopes.shift
@@ -158,38 +165,41 @@
true
end
end
# deep_merge! given result with result for fallback locale
- def self.merge_with_fallbacks!(result, locale, scope)
+ def self.merge_with_fallbacks!(result, locale, scope, exceptions)
result[locale] ||= {}
fallback_locales = FallbackLocales.new(fallbacks, locale)
fallback_locales.each do |fallback_locale|
- fallback_result = scoped_translations(scope.collect{|s| "#{fallback_locale}.#{s}"}) # NOTE: Duplicated code here
+ fallback_result = scoped_translations(scope.collect{|s| "#{fallback_locale}.#{s}"}, exceptions) # NOTE: Duplicated code here
result[locale] = Utils.deep_merge(fallback_result[fallback_locale], result[locale])
end
end
-
### Export i18n.js
begin
+
# Copy i18n.js
def self.export_i18n_js
- return if export_i18n_js_dir_path.nil?
+ return unless export_i18n_js_dir_path.is_a? String
FileUtils.mkdir_p(export_i18n_js_dir_path)
i18n_js_path = File.expand_path('../../../app/assets/javascripts/i18n.js', __FILE__)
FileUtils.cp(i18n_js_path, export_i18n_js_dir_path)
end
- def self.export_i18n_js_dir_path
- return @export_i18n_js_dir_path if defined?(@export_i18n_js_dir_path)
- @export_i18n_js_dir_path = DEFAULT_EXPORT_DIR_PATH
+ def self.export_i18n_js_dir_path
+ @export_i18n_js_dir_path ||= (config[:export_i18n_js] || :none) if config.has_key?(:export_i18n_js)
+ @export_i18n_js_dir_path ||= DEFAULT_EXPORT_DIR_PATH
+ @export_i18n_js_dir_path
end
+
# Setting this to nil would disable i18n.js exporting
def self.export_i18n_js_dir_path=(new_path)
+ new_path = :none unless new_path.is_a? String
@export_i18n_js_dir_path = new_path
end
end
end
end