forked from fnando/i18n-js
-
Notifications
You must be signed in to change notification settings - Fork 5
/
i18n-js.rb
181 lines (153 loc) · 5.34 KB
/
i18n-js.rb
1
2
3
4
5
6
7
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
33
34
35
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
require "FileUtils" unless defined?(FileUtils)
module SimplesIdeias
module I18n
extend self
require "i18n-js/railtie" if Rails.version >= "3.0"
require "i18n-js/engine" if Rails.version >= "3.1"
require "i18n-js/preprocessor" if Rails.version >= "3.1"
require "i18n-js/middleware"
# deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
MERGER = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &MERGER) : v2 }
# Under rails 3.1.1 and higher, perform a check to ensure that the
# full environment will be available during asset compilation.
# This is required to ensure I18n is loaded.
def assert_usable_configuration!
@usable_configuration ||= Rails.version >= "3.1.1" &&
Rails.configuration.assets.initialize_on_precompile ||
raise("Cannot precompile i18n-js translations unless environment is initialized. Please set config.assets.initialize_on_precompile to true.")
end
def has_asset_pipeline?
Rails.configuration.respond_to?(:assets) && Rails.configuration.assets.enabled
return false unless Rails.configuration.respond_to?('assets')
assets = Rails.configuration.assets
assets.enabled.nil? || assets.enabled
end
def config_file
Rails.root.join("config/i18n-js.yml")
end
def export_dir
if has_asset_pipeline?
"app/assets/javascripts/i18n"
else
"public/javascripts"
end
end
def javascript_file
Rails.root.join(export_dir, "i18n.js")
end
# Export translations to JavaScript, considering settings
# from configuration file
def export!
translation_segments.each do |filename, translations|
save(translations, filename)
end
end
def segments_per_locale(pattern,scope)
::I18n.available_locales.each_with_object({}) do |locale,segments|
result = scoped_translations("#{locale}.#{scope}")
unless result.empty?
segment_name = ::I18n.interpolate(pattern,{:locale => locale})
segments[segment_name] = result
end
end
end
def segment_for_scope(scope)
if scope == "*"
translations
else
scoped_translations(scope)
end
end
def 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]))
else
result = segment_for_scope(options[:only])
segments[options[:file]] = result unless result.empty?
end
end
end
def translation_segments
if config? && config[:translations]
configured_segments
else
{"#{export_dir}/translations.js" => translations}
end
end
# Load configuration file for partial exporting and
# custom output directory
def config
if config?
(YAML.load_file(config_file) || {}).with_indifferent_access
else
{}
end
end
# Check if configuration file exist
def config?
File.file? config_file
end
# Copy configuration and JavaScript library files to
# <tt>config/i18n-js.yml</tt> and <tt>public/javascripts/i18n.js</tt>.
def setup!
FileUtils.cp(File.dirname(__FILE__) + "/../vendor/assets/javascripts/i18n.js", javascript_file) unless has_asset_pipeline?
FileUtils.cp(File.dirname(__FILE__) + "/../config/i18n-js.yml", config_file) unless config?
end
# Retrieve an updated JavaScript library from Github.
def update!
require "open-uri"
contents = open("https://raw.github.com/fnando/i18n-js/master/vendor/assets/javascripts/i18n.js").read
File.open(javascript_file, "w+") {|f| f << contents}
end
# Convert translations to JSON string and save file.
def save(translations, file)
file = Rails.root.join(file)
FileUtils.mkdir_p File.dirname(file)
File.open(file, "w+") do |f|
f << %(var I18n = I18n || {};\n)
f << %(I18n.translations = );
f << translations.to_json
f << %(;)
end
end
def scoped_translations(scopes) # :nodoc:
result = {}
[scopes].flatten.each do |scope|
deep_merge! result, filter(translations, scope)
end
result
end
# Filter translations according to the specified scope.
def filter(translations, scopes)
scopes = scopes.split(".") if scopes.is_a?(String)
scopes = scopes.clone
scope = scopes.shift
if scope == "*"
results = {}
translations.each do |scope, translations|
tmp = scopes.empty? ? translations : filter(translations, scopes)
results[scope.to_sym] = tmp unless tmp.nil?
end
return results
elsif translations.has_key?(scope.to_sym)
return {scope.to_sym => scopes.empty? ? translations[scope.to_sym] : filter(translations[scope.to_sym], scopes)}
end
nil
end
# Initialize and return translations
def translations
::I18n.backend.instance_eval do
init_translations unless initialized?
translations
end
end
def deep_merge(target, hash) # :nodoc:
target.merge(hash, &MERGER)
end
def deep_merge!(target, hash) # :nodoc:
target.merge!(hash, &MERGER)
end
end
end