lolita-i18n 0.1.4 → 0.1.18
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +4 -4
- data/.rspec +1 -1
- data/Gemfile +24 -24
- data/History.rdoc +7 -0
- data/LICENSE.txt +20 -20
- data/README.md +26 -26
- data/Rakefile +46 -46
- data/VERSION +1 -1
- data/app/controllers/lolita/i18n_controller.rb +42 -38
- data/app/helpers/lolita/i18n_helper.rb +24 -24
- data/app/views/lolita/i18n/index.html.haml +35 -33
- data/config/locales/en.yml +5 -0
- data/config/locales/lv.yml +5 -0
- data/config/routes.rb +10 -10
- data/lib/lolita-i18n/backend.rb +76 -76
- data/lib/lolita-i18n/google_translate.rb +6 -6
- data/lib/lolita-i18n/rails.rb +7 -6
- data/lib/lolita-i18n.rb +116 -81
- data/lolita-i18n.gemspec +12 -12
- data/{app/assets → public}/images/lolita/i18n/google_translate_icon.png +0 -0
- data/{app/assets → public}/javascripts/lolita/i18n/application.js +0 -0
- data/public/javascripts/lolita/i18n/i18n.js +169 -0
- data/{app/assets → public}/javascripts/lolita/i18n/spin.min.js +0 -0
- data/{app/assets/stylesheets/lolita/i18n/application.scss → public/stylesheets/lolita/i18n/application.css} +1 -1
- data/spec/controllers/lolita/i18n_controller_spec.rb +38 -38
- data/spec/lolita-i18n/backend_spec.rb +27 -27
- data/spec/rails_app/app/controllers/application_controller.rb +2 -2
- data/spec/rails_app/config/application.rb +18 -18
- data/spec/rails_app/config/enviroment.rb +4 -4
- data/spec/rails_app/config/initializers/lolita_i18n.rb +16 -15
- data/spec/rails_app/config/locales/en.yml +8 -8
- data/spec/rails_app/config/routes.rb +2 -2
- data/spec/spec_helper.rb +34 -32
- metadata +29 -32
- data/Gemfile.lock +0 -161
- data/app/assets/javascripts/lolita/i18n/i18n.js.coffee +0 -135
data/config/locales/en.yml
CHANGED
data/config/locales/lv.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
Rails.application.routes.draw do
|
2
|
-
|
3
|
-
namespace "lolita" do
|
4
|
-
resources :i18n, :only=>[:update],:constraints=>{:id=>/.*/} do
|
5
|
-
collection do
|
6
|
-
put 'translate_untranslated'
|
7
|
-
get 'index'
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
|
3
|
+
namespace "lolita" do
|
4
|
+
resources :i18n, :only=>[:update],:constraints=>{:id=>/.*/} do
|
5
|
+
collection do
|
6
|
+
put 'translate_untranslated'
|
7
|
+
get 'index'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
11
|
end
|
data/lib/lolita-i18n/backend.rb
CHANGED
@@ -1,77 +1,77 @@
|
|
1
|
-
module Lolita
|
2
|
-
module I18n
|
3
|
-
# Allow to operate with I18n keys and values.
|
4
|
-
class Backend
|
5
|
-
|
6
|
-
class << self
|
7
|
-
# Get translation and decode it. Set translate from and to translations.
|
8
|
-
# Return Hash with
|
9
|
-
# * <tt>:key</tt> - translation key
|
10
|
-
# * <tt>:value</tt> - translation
|
11
|
-
# * <tt>:translate_to</tt> - translation locale, like <i>en</i>
|
12
|
-
# * <tt>:translate_from</tt> - translation key for default language
|
13
|
-
def get(key)
|
14
|
-
result={:key=>key}
|
15
|
-
result[:value]=decoded_value(key)
|
16
|
-
result[:original_value]=decoded_value(translate_from(key))
|
17
|
-
result[:translate_to]=translate_to(key)
|
18
|
-
result[:translate_from]=translate_from(key)
|
19
|
-
result
|
20
|
-
end
|
21
|
-
|
22
|
-
# Store translation, decode and store.
|
23
|
-
# Accept:
|
24
|
-
# * <tt>key</tt> - translation key
|
25
|
-
# * <tt>translation</tt> - String with translation
|
26
|
-
def set(key,translation)
|
27
|
-
locale=translate_to(key)
|
28
|
-
translation_key=translation_key(key)
|
29
|
-
value=Yajl::Parser.parse(translation.to_json)
|
30
|
-
if value.blank?
|
31
|
-
del key
|
32
|
-
else
|
33
|
-
if Lolita
|
34
|
-
Lolita::I18n::GoogleTranslate.del_translation locale, translation_key
|
35
|
-
true
|
36
|
-
else
|
37
|
-
false
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def del key
|
43
|
-
Lolita
|
44
|
-
end
|
45
|
-
|
46
|
-
def locale(key)
|
47
|
-
translate_to(key) || ::I18n.default_locale
|
48
|
-
end
|
49
|
-
|
50
|
-
def translation_key(key)
|
51
|
-
(key.to_s.split('.')[1..-1]).join(".")
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def keys
|
57
|
-
@keys||=Lolita
|
58
|
-
end
|
59
|
-
|
60
|
-
def decoded_value(key)
|
61
|
-
value=Lolita
|
62
|
-
value ? (Yajl::Parser.parse(value) rescue "") : ::I18n.t(key.split('.')[1..-1].join('.'), :default => "", :locale => translate_to(key))
|
63
|
-
end
|
64
|
-
|
65
|
-
def translate_to(key)
|
66
|
-
key.to_s.split(".").first
|
67
|
-
end
|
68
|
-
|
69
|
-
def translate_from(key,locale=nil)
|
70
|
-
(key.to_s.split('.')[1..-1]).insert(0,locale || ::I18n.default_locale).join(".")
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
end
|
76
|
-
end
|
1
|
+
module Lolita
|
2
|
+
module I18n
|
3
|
+
# Allow to operate with I18n keys and values.
|
4
|
+
class Backend
|
5
|
+
|
6
|
+
class << self
|
7
|
+
# Get translation and decode it. Set translate from and to translations.
|
8
|
+
# Return Hash with
|
9
|
+
# * <tt>:key</tt> - translation key
|
10
|
+
# * <tt>:value</tt> - translation
|
11
|
+
# * <tt>:translate_to</tt> - translation locale, like <i>en</i>
|
12
|
+
# * <tt>:translate_from</tt> - translation key for default language
|
13
|
+
def get(key)
|
14
|
+
result={:key=>key}
|
15
|
+
result[:value]=decoded_value(key)
|
16
|
+
result[:original_value]=decoded_value(translate_from(key))
|
17
|
+
result[:translate_to]=translate_to(key)
|
18
|
+
result[:translate_from]=translate_from(key)
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
# Store translation, decode and store.
|
23
|
+
# Accept:
|
24
|
+
# * <tt>key</tt> - translation key
|
25
|
+
# * <tt>translation</tt> - String with translation
|
26
|
+
def set(key,translation)
|
27
|
+
locale=translate_to(key)
|
28
|
+
translation_key=translation_key(key)
|
29
|
+
value=Yajl::Parser.parse(translation.to_json)
|
30
|
+
if value.blank?
|
31
|
+
del key
|
32
|
+
else
|
33
|
+
if Lolita.i18n.backend.store_translations(locale,{translation_key=>value},:escape=>false)
|
34
|
+
Lolita::I18n::GoogleTranslate.del_translation locale, translation_key
|
35
|
+
true
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def del key
|
43
|
+
Lolita.i18n.store.del key
|
44
|
+
end
|
45
|
+
|
46
|
+
def locale(key)
|
47
|
+
translate_to(key) || ::I18n.default_locale
|
48
|
+
end
|
49
|
+
|
50
|
+
def translation_key(key)
|
51
|
+
(key.to_s.split('.')[1..-1]).join(".")
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def keys
|
57
|
+
@keys||=Lolita.i18n.flattened_translations.keys.sort
|
58
|
+
end
|
59
|
+
|
60
|
+
def decoded_value(key)
|
61
|
+
value=Lolita.i18n.backend.store[key]
|
62
|
+
value ? (Yajl::Parser.parse(value) rescue "") : ::I18n.t(key.split('.')[1..-1].join('.'), :default => "", :locale => translate_to(key))
|
63
|
+
end
|
64
|
+
|
65
|
+
def translate_to(key)
|
66
|
+
key.to_s.split(".").first
|
67
|
+
end
|
68
|
+
|
69
|
+
def translate_from(key,locale=nil)
|
70
|
+
(key.to_s.split('.')[1..-1]).insert(0,locale || ::I18n.default_locale).join(".")
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
77
|
end
|
@@ -37,7 +37,7 @@ module Lolita
|
|
37
37
|
def untranslated_translations
|
38
38
|
unless @untranslated_translations
|
39
39
|
@untranslated_translations = []
|
40
|
-
Lolita
|
40
|
+
Lolita.i18n.flatten_keys.each do |key|
|
41
41
|
unless unapproved_keys.include?(key)
|
42
42
|
if !::I18n.t(key, :locale => ::I18n.default_locale, :default => '').blank? && ::I18n.t(key, :locale => @locale, :default => '').blank? && Lolita::I18n::GoogleTranslate.get_translation(@locale,key).blank?
|
43
43
|
value = ::I18n.t(key, :locale => ::I18n.default_locale, :default => '').to_s
|
@@ -50,25 +50,25 @@ module Lolita
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def self.get_translation locale, key
|
53
|
-
Lolita
|
53
|
+
Lolita.i18n.store.get :"#{locale}.g.#{key}"
|
54
54
|
end
|
55
55
|
|
56
56
|
def self.del_translation locale, key
|
57
|
-
Lolita
|
57
|
+
Lolita.i18n.store.del :"#{locale}.g.#{key}"
|
58
58
|
end
|
59
59
|
|
60
60
|
private
|
61
61
|
|
62
62
|
def unapproved_keys
|
63
|
-
@@unapproved_keys ||= Lolita
|
63
|
+
@@unapproved_keys ||= Lolita.i18n.store.smembers(:"unapproved_keys_#{@locale}").map(&:to_sym)
|
64
64
|
end
|
65
65
|
|
66
66
|
def add_translation key, value
|
67
|
-
Lolita
|
67
|
+
Lolita.i18n.store.set :"#{@locale}.g.#{key}", value
|
68
68
|
end
|
69
69
|
|
70
70
|
def add_to_unapproved key
|
71
|
-
Lolita
|
71
|
+
Lolita.i18n.store.sadd(:"unapproved_keys_#{@locale}",key)
|
72
72
|
end
|
73
73
|
|
74
74
|
end
|
data/lib/lolita-i18n/rails.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
|
2
|
-
module LolitaI18n
|
3
|
-
class Engine < Rails::Engine
|
4
|
-
|
5
|
-
end
|
6
|
-
end
|
1
|
+
|
2
|
+
module LolitaI18n
|
3
|
+
class Engine < Rails::Engine
|
4
|
+
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
data/lib/lolita-i18n.rb
CHANGED
@@ -1,81 +1,116 @@
|
|
1
|
-
$:<<File.dirname(__FILE__) unless $:.include?(File.dirname(__FILE__))
|
2
|
-
require 'redis'
|
3
|
-
require 'yajl'
|
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
|
-
end
|
80
|
-
end
|
81
|
-
|
1
|
+
$:<<File.dirname(__FILE__) unless $:.include?(File.dirname(__FILE__))
|
2
|
+
require 'redis'
|
3
|
+
require 'yajl'
|
4
|
+
require 'lolita'
|
5
|
+
|
6
|
+
module Lolita
|
7
|
+
# === Uses Redis DB as backend
|
8
|
+
# All translations ar stored with full key like "en.home.index.title" -> Hello world.
|
9
|
+
# Translations whitch are translated with Google translate have prefix "g" -> "g.en.home.index.title".
|
10
|
+
# These translations should be accepted/edited and approved then they will become as normal for general use.
|
11
|
+
#
|
12
|
+
# === Other stored data
|
13
|
+
# => :unapproved_keys_<locale> - a SET containing all unapproved keys from GoogleTranslate
|
14
|
+
#
|
15
|
+
# In your lolita initializer add this line in setup block.
|
16
|
+
# config.i18n.store = {:db => 1}
|
17
|
+
# # or
|
18
|
+
# config.i18n.store = Redis.new()
|
19
|
+
module I18n
|
20
|
+
autoload :Backend, 'lolita-i18n/backend'
|
21
|
+
autoload :GoogleTranslate, 'lolita-i18n/google_translate'
|
22
|
+
|
23
|
+
|
24
|
+
class Configuration
|
25
|
+
|
26
|
+
attr_accessor :yaml_backend
|
27
|
+
|
28
|
+
def store
|
29
|
+
unless @store
|
30
|
+
warn "Lolita::I18n No store specified. See Lolita::I18n"
|
31
|
+
# warn "No Lolita::I18n store specfied."
|
32
|
+
@store = Redis.new
|
33
|
+
# initialize_chain
|
34
|
+
end
|
35
|
+
@store
|
36
|
+
end
|
37
|
+
|
38
|
+
def store=(possible_store)
|
39
|
+
@store = if possible_store.is_a?(Hash)
|
40
|
+
Redis.new(possible_store)
|
41
|
+
else
|
42
|
+
possible_store
|
43
|
+
end
|
44
|
+
@store
|
45
|
+
end
|
46
|
+
|
47
|
+
def backend
|
48
|
+
@backend ||= ::I18n::Backend::KeyValue.new(self.store)
|
49
|
+
end
|
50
|
+
|
51
|
+
# returns Array of flattened keys as "home.index.title"
|
52
|
+
def flatten_keys
|
53
|
+
load_translations
|
54
|
+
self.yaml_backend.flatten_translations(nil, self.yaml_backend.send(:translations)[::I18n.default_locale] || {}, ::I18n::Backend::Flatten::SEPARATOR_ESCAPE_CHAR, false).keys
|
55
|
+
end
|
56
|
+
|
57
|
+
def load_translations
|
58
|
+
if !self.yaml_backend.send(:translations) || self.yaml_backend.send(:translations).empty?
|
59
|
+
self.yaml_backend.load_translations
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize_chain
|
64
|
+
::I18n::Backend::Chain.new(self.backend, self.yaml_backend)
|
65
|
+
end
|
66
|
+
|
67
|
+
def include_modules
|
68
|
+
::I18n::Backend::Simple.send(:include, ::I18n::Backend::Flatten)
|
69
|
+
::I18n::Backend::Simple.send(:include, ::I18n::Backend::Memoize)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module LolitaI18nConfiguration
|
77
|
+
def i18n
|
78
|
+
@i18n ||= Lolita::I18n::Configuration.new
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
Lolita.scope.extend(LolitaI18nConfiguration)
|
83
|
+
|
84
|
+
Lolita.after_setup do
|
85
|
+
Lolita.i18n.yaml_backend = ::I18n.backend
|
86
|
+
Lolita.i18n.include_modules
|
87
|
+
begin
|
88
|
+
r = Redis.new
|
89
|
+
r.ping
|
90
|
+
::I18n.backend = Lolita.i18n.initialize_chain
|
91
|
+
rescue Errno::ECONNREFUSED => e
|
92
|
+
warn "Warning: Lolita was unable to connect to Redis DB: #{e}"
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
require 'lolita-i18n/module'
|
98
|
+
|
99
|
+
if Lolita.rails3?
|
100
|
+
require 'lolita-i18n/rails'
|
101
|
+
end
|
102
|
+
|
103
|
+
Lolita.after_routes_loaded do
|
104
|
+
if tree=Lolita::Navigation::Tree[:"left_side_navigation"]
|
105
|
+
unless tree.branches.detect { |b| b.title=="System" }
|
106
|
+
branch=tree.append(nil, :title=>"System")
|
107
|
+
#mapping=Lolita::Mapping.new(:i18n_index,:singular=>:i18n,:class_name=>Object,:controller=>"lolita/i18n")
|
108
|
+
branch.append(Object, :title=>"I18n", :url=>Proc.new { |view, branch|
|
109
|
+
view.send(:lolita_i18n_index_path)
|
110
|
+
}, :active=>Proc.new { |view, parent_branch, branch|
|
111
|
+
params=view.send(:params)
|
112
|
+
params[:controller].to_s.match(/lolita\/i18n/)
|
113
|
+
})
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|