translation_panel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +135 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +39 -0
- data/VERSION +1 -0
- data/app/assets/javascripts/translation_panel.js.coffee +88 -0
- data/app/assets/stylesheets/translation_panel.css.scss +53 -0
- data/lib/generators/translation_panel/install_generator.rb +13 -0
- data/lib/translation_panel/filter.rb +40 -0
- data/lib/translation_panel/redis_backend.rb +65 -0
- data/lib/translation_panel.rb +62 -0
- data/spec/app/.gitignore +2 -0
- data/spec/app/app/controllers/admin/translations_controller.rb +7 -0
- data/spec/app/app/controllers/application_controller.rb +10 -0
- data/spec/app/app/controllers/home_controller.rb +4 -0
- data/spec/app/app/views/home/index.html.erb +10 -0
- data/spec/app/config/application.rb +18 -0
- data/spec/app/config/boot.rb +5 -0
- data/spec/app/config/environment.rb +5 -0
- data/spec/app/config/environments/development.rb +11 -0
- data/spec/app/config/environments/production.rb +11 -0
- data/spec/app/config/environments/test.rb +12 -0
- data/spec/app/config/initializers/i18n.rb +8 -0
- data/spec/app/config/initializers/secret_token.rb +1 -0
- data/spec/app/config/initializers/session_store.rb +1 -0
- data/spec/app/config/redis/test.conf +34 -0
- data/spec/app/config/redis.yml +8 -0
- data/spec/app/config/routes.rb +7 -0
- data/spec/app/config.ru +4 -0
- data/spec/app/db/.gitkeep +0 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/lib/redis_backend_spec.rb +64 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/translation_panel_spec.rb +71 -0
- data/translation_panel.gemspec +94 -0
- metadata +170 -0
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--colour
|
data/.rvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rvm 1.9.2@translation_panel --create
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: http://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
actionmailer (3.1.0.rc4)
|
|
5
|
+
actionpack (= 3.1.0.rc4)
|
|
6
|
+
mail (~> 2.3.0)
|
|
7
|
+
actionpack (3.1.0.rc4)
|
|
8
|
+
activemodel (= 3.1.0.rc4)
|
|
9
|
+
activesupport (= 3.1.0.rc4)
|
|
10
|
+
builder (~> 3.0.0)
|
|
11
|
+
erubis (~> 2.7.0)
|
|
12
|
+
i18n (~> 0.6)
|
|
13
|
+
rack (~> 1.3.0)
|
|
14
|
+
rack-cache (~> 1.0.1)
|
|
15
|
+
rack-mount (~> 0.8.1)
|
|
16
|
+
rack-test (~> 0.6.0)
|
|
17
|
+
sprockets (~> 2.0.0.beta.10)
|
|
18
|
+
tzinfo (~> 0.3.27)
|
|
19
|
+
activemodel (3.1.0.rc4)
|
|
20
|
+
activesupport (= 3.1.0.rc4)
|
|
21
|
+
bcrypt-ruby (~> 2.1.4)
|
|
22
|
+
builder (~> 3.0.0)
|
|
23
|
+
i18n (~> 0.6)
|
|
24
|
+
activerecord (3.1.0.rc4)
|
|
25
|
+
activemodel (= 3.1.0.rc4)
|
|
26
|
+
activesupport (= 3.1.0.rc4)
|
|
27
|
+
arel (~> 2.1.1)
|
|
28
|
+
tzinfo (~> 0.3.27)
|
|
29
|
+
activeresource (3.1.0.rc4)
|
|
30
|
+
activemodel (= 3.1.0.rc4)
|
|
31
|
+
activesupport (= 3.1.0.rc4)
|
|
32
|
+
activesupport (3.1.0.rc4)
|
|
33
|
+
multi_json (~> 1.0)
|
|
34
|
+
arel (2.1.3)
|
|
35
|
+
bcrypt-ruby (2.1.4)
|
|
36
|
+
builder (3.0.0)
|
|
37
|
+
capybara (1.0.0)
|
|
38
|
+
mime-types (>= 1.16)
|
|
39
|
+
nokogiri (>= 1.3.3)
|
|
40
|
+
rack (>= 1.0.0)
|
|
41
|
+
rack-test (>= 0.5.4)
|
|
42
|
+
selenium-webdriver (~> 0.2.0)
|
|
43
|
+
xpath (~> 0.1.4)
|
|
44
|
+
childprocess (0.1.9)
|
|
45
|
+
ffi (~> 1.0.6)
|
|
46
|
+
diff-lcs (1.1.2)
|
|
47
|
+
erubis (2.7.0)
|
|
48
|
+
ffi (1.0.9)
|
|
49
|
+
git (1.2.5)
|
|
50
|
+
hike (1.2.0)
|
|
51
|
+
i18n (0.6.0)
|
|
52
|
+
jeweler (1.6.4)
|
|
53
|
+
bundler (~> 1.0)
|
|
54
|
+
git (>= 1.2.5)
|
|
55
|
+
rake
|
|
56
|
+
json_pure (1.5.3)
|
|
57
|
+
mail (2.3.0)
|
|
58
|
+
i18n (>= 0.4.0)
|
|
59
|
+
mime-types (~> 1.16)
|
|
60
|
+
treetop (~> 1.4.8)
|
|
61
|
+
mime-types (1.16)
|
|
62
|
+
multi_json (1.0.3)
|
|
63
|
+
nokogiri (1.5.0)
|
|
64
|
+
polyglot (0.3.1)
|
|
65
|
+
rack (1.3.1)
|
|
66
|
+
rack-cache (1.0.2)
|
|
67
|
+
rack (>= 0.4)
|
|
68
|
+
rack-mount (0.8.1)
|
|
69
|
+
rack (>= 1.0.0)
|
|
70
|
+
rack-ssl (1.3.2)
|
|
71
|
+
rack
|
|
72
|
+
rack-test (0.6.0)
|
|
73
|
+
rack (>= 1.0)
|
|
74
|
+
rails (3.1.0.rc4)
|
|
75
|
+
actionmailer (= 3.1.0.rc4)
|
|
76
|
+
actionpack (= 3.1.0.rc4)
|
|
77
|
+
activerecord (= 3.1.0.rc4)
|
|
78
|
+
activeresource (= 3.1.0.rc4)
|
|
79
|
+
activesupport (= 3.1.0.rc4)
|
|
80
|
+
bundler (~> 1.0)
|
|
81
|
+
railties (= 3.1.0.rc4)
|
|
82
|
+
railties (3.1.0.rc4)
|
|
83
|
+
actionpack (= 3.1.0.rc4)
|
|
84
|
+
activesupport (= 3.1.0.rc4)
|
|
85
|
+
rack-ssl (~> 1.3.2)
|
|
86
|
+
rake (>= 0.8.7)
|
|
87
|
+
rdoc (~> 3.4)
|
|
88
|
+
thor (~> 0.14.6)
|
|
89
|
+
rake (0.9.2)
|
|
90
|
+
rdoc (3.8)
|
|
91
|
+
redis (2.2.1)
|
|
92
|
+
rspec (2.6.0)
|
|
93
|
+
rspec-core (~> 2.6.0)
|
|
94
|
+
rspec-expectations (~> 2.6.0)
|
|
95
|
+
rspec-mocks (~> 2.6.0)
|
|
96
|
+
rspec-core (2.6.4)
|
|
97
|
+
rspec-expectations (2.6.0)
|
|
98
|
+
diff-lcs (~> 1.1.2)
|
|
99
|
+
rspec-mocks (2.6.0)
|
|
100
|
+
rspec-rails (2.6.1)
|
|
101
|
+
actionpack (~> 3.0)
|
|
102
|
+
activesupport (~> 3.0)
|
|
103
|
+
railties (~> 3.0)
|
|
104
|
+
rspec (~> 2.6.0)
|
|
105
|
+
rubyzip (0.9.4)
|
|
106
|
+
selenium-webdriver (0.2.2)
|
|
107
|
+
childprocess (>= 0.1.9)
|
|
108
|
+
ffi (>= 1.0.7)
|
|
109
|
+
json_pure
|
|
110
|
+
rubyzip
|
|
111
|
+
sprockets (2.0.0.beta.10)
|
|
112
|
+
hike (~> 1.0)
|
|
113
|
+
rack (~> 1.0)
|
|
114
|
+
tilt (!= 1.3.0, ~> 1.1)
|
|
115
|
+
sqlite3 (1.3.3)
|
|
116
|
+
thor (0.14.6)
|
|
117
|
+
tilt (1.3.2)
|
|
118
|
+
treetop (1.4.9)
|
|
119
|
+
polyglot (>= 0.3.1)
|
|
120
|
+
tzinfo (0.3.29)
|
|
121
|
+
xpath (0.1.4)
|
|
122
|
+
nokogiri (~> 1.3)
|
|
123
|
+
yajl-ruby (0.8.2)
|
|
124
|
+
|
|
125
|
+
PLATFORMS
|
|
126
|
+
ruby
|
|
127
|
+
|
|
128
|
+
DEPENDENCIES
|
|
129
|
+
capybara (>= 0.4.0)
|
|
130
|
+
jeweler
|
|
131
|
+
rails (>= 3.1.0.rc4)
|
|
132
|
+
redis
|
|
133
|
+
rspec-rails (>= 2.0.0.beta)
|
|
134
|
+
sqlite3
|
|
135
|
+
yajl-ruby
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2011 YOURNAME
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
require 'rubygems'
|
|
3
|
+
begin
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'rake'
|
|
10
|
+
require 'rdoc/task'
|
|
11
|
+
|
|
12
|
+
require 'rspec/core'
|
|
13
|
+
require 'rspec/core/rake_task'
|
|
14
|
+
|
|
15
|
+
RSpec::Core::RakeTask.new(:spec)
|
|
16
|
+
|
|
17
|
+
task :default => :spec
|
|
18
|
+
|
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
21
|
+
rdoc.title = 'TranslationPanel'
|
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
|
23
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
require 'jeweler'
|
|
28
|
+
Jeweler::Tasks.new do |gem|
|
|
29
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
|
30
|
+
gem.name = "translation_panel"
|
|
31
|
+
gem.homepage = "http://github.com/Mik-die/translation_panel"
|
|
32
|
+
gem.license = "MIT"
|
|
33
|
+
gem.summary = %Q{I18n backend}
|
|
34
|
+
gem.description = %Q{I18n backend, based on redis, with frontend panel for translations}
|
|
35
|
+
gem.email = "MikDiet@gmail.com"
|
|
36
|
+
gem.authors = ["Mik-die"]
|
|
37
|
+
# dependencies defined in Gemfile
|
|
38
|
+
end
|
|
39
|
+
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.0
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
$.translator = translator =
|
|
2
|
+
initialize: ->
|
|
3
|
+
return false unless translationPanel?
|
|
4
|
+
translator.loadData().render()
|
|
5
|
+
loadData: ->
|
|
6
|
+
translator.translatesData = translationPanel.translates || []
|
|
7
|
+
translator.locale = translationPanel.locale
|
|
8
|
+
translator.save_action = translationPanel.action
|
|
9
|
+
translator
|
|
10
|
+
render: ->
|
|
11
|
+
translator.container = $('<div id="translator"></div>').html("Open Translate Panel")
|
|
12
|
+
translator.container.appendTo($('body'))
|
|
13
|
+
translator.renderPanel().renderForm().setHandlers()
|
|
14
|
+
renderPanel: ->
|
|
15
|
+
translator.panel = $('<div id="translator_panel"><ul/></div>').appendTo($('body')).dialog
|
|
16
|
+
autoOpen: false
|
|
17
|
+
dialogClass: 'translator'
|
|
18
|
+
position: ['right',30]
|
|
19
|
+
translator.addTranslates translator.translatesData
|
|
20
|
+
translator
|
|
21
|
+
translates: []
|
|
22
|
+
addTranslates: (translatesData) ->
|
|
23
|
+
translator.addTranslate t for t in translatesData
|
|
24
|
+
addTranslate: (translateData) ->
|
|
25
|
+
if translator.translates[translateData.key]?
|
|
26
|
+
translator.translates[translateData.key].element.remove()
|
|
27
|
+
translator.translates[translateData.key] =
|
|
28
|
+
value: translateData.value
|
|
29
|
+
element: $('<li/>').append($('<a href="#" />').html(translateData.key))
|
|
30
|
+
.append($('<span/>')).appendTo translator.panel.find('ul')
|
|
31
|
+
change_translate: ->
|
|
32
|
+
if this.value? and this.value!=""
|
|
33
|
+
this.element.find('span').text(this.value)
|
|
34
|
+
else
|
|
35
|
+
this.element.find('span').html("<i>no translation</i>")
|
|
36
|
+
translator.translates[translateData.key].change_translate()
|
|
37
|
+
renderForm: ->
|
|
38
|
+
translator.form = $('<form />').attr
|
|
39
|
+
id: 'translator_form'
|
|
40
|
+
"accept-charset": "UTF-8"
|
|
41
|
+
action: translator.save_action
|
|
42
|
+
method: "get"
|
|
43
|
+
$('<span id="translator_key_span" />').appendTo(translator.form)
|
|
44
|
+
$('<input type="hidden" />').appendTo(translator.form).attr
|
|
45
|
+
id: 'translator_key'
|
|
46
|
+
name: 'key'
|
|
47
|
+
$('<input type="text" />').appendTo(translator.form).attr
|
|
48
|
+
id: 'translator_value'
|
|
49
|
+
name: 'value'
|
|
50
|
+
$('<input type="hidden" />').appendTo(translator.form).attr
|
|
51
|
+
name: 'locale'
|
|
52
|
+
value: translator.locale
|
|
53
|
+
$('<input type="submit" />').appendTo(translator.form).attr
|
|
54
|
+
name: 'submit'
|
|
55
|
+
value: 'Update'
|
|
56
|
+
translator.form.appendTo($('body')).dialog
|
|
57
|
+
autoOpen: false
|
|
58
|
+
dialogClass: 'translator'
|
|
59
|
+
position: ['center',30]
|
|
60
|
+
width: 450
|
|
61
|
+
translator
|
|
62
|
+
setHandlers: ->
|
|
63
|
+
translator.container.click ->
|
|
64
|
+
if translator.panel.dialog('isOpen')
|
|
65
|
+
translator.panel.dialog('close')
|
|
66
|
+
else
|
|
67
|
+
translator.panel.dialog('open')
|
|
68
|
+
translator.panel.find('li a').click ->
|
|
69
|
+
translator.form.dialog('open') unless translator.form.dialog('isOpen')
|
|
70
|
+
$('#translator_key_span').html $(this).html()
|
|
71
|
+
$('#translator_key').val $(this).html()
|
|
72
|
+
$('#translator_value').val translator.translates[$(this).html()].value
|
|
73
|
+
false
|
|
74
|
+
translator.form.submit ->
|
|
75
|
+
request = $.ajax
|
|
76
|
+
url: translator.form.attr('action')
|
|
77
|
+
data: translator.form.serializeArray()
|
|
78
|
+
success: (data, textStatus, jqXHR) ->
|
|
79
|
+
jqXHR.translate.change_translate()
|
|
80
|
+
error: (jqXHR, status) ->
|
|
81
|
+
jqXHR.translate.element.find('span').html('<i>Error!! ('+status+')</i>')
|
|
82
|
+
request.translate = translator.translates[$('#translator_key').val()]
|
|
83
|
+
request.translate.value = $('#translator_value').val()
|
|
84
|
+
request.translate.element.find('span').html('<i>saving..</i>')
|
|
85
|
+
translator.form.dialog('close')
|
|
86
|
+
false
|
|
87
|
+
|
|
88
|
+
$ -> $.translator.initialize()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#translator {
|
|
2
|
+
position: fixed;
|
|
3
|
+
top: 0;
|
|
4
|
+
right: 0;
|
|
5
|
+
height: 25px;
|
|
6
|
+
width: 300px;
|
|
7
|
+
background: #f6a828;
|
|
8
|
+
color: #ffffff;
|
|
9
|
+
text-align: center;
|
|
10
|
+
font-weight: bold;
|
|
11
|
+
padding-top: 4px;
|
|
12
|
+
cursor: pointer;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#translator_form {
|
|
16
|
+
padding: 20px;
|
|
17
|
+
input { display:block; width:95%; }
|
|
18
|
+
#translator_key_span { font-weight: bold; }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.translator {
|
|
22
|
+
ul {
|
|
23
|
+
list-style-type: none;
|
|
24
|
+
margin:0;
|
|
25
|
+
padding: 10px 5px;
|
|
26
|
+
max-height:600px;
|
|
27
|
+
overflow: auto;
|
|
28
|
+
li {
|
|
29
|
+
a { display:block; }
|
|
30
|
+
span { display:block; padding: 0 0 5px 10px; }
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }
|
|
35
|
+
.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; }
|
|
36
|
+
.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; }
|
|
37
|
+
.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }
|
|
38
|
+
.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }
|
|
39
|
+
.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }
|
|
40
|
+
.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }
|
|
41
|
+
.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }
|
|
42
|
+
.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; }
|
|
43
|
+
.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; }
|
|
44
|
+
.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }
|
|
45
|
+
.ui-draggable .ui-dialog-titlebar { cursor: move; }
|
|
46
|
+
|
|
47
|
+
.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }
|
|
48
|
+
.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }
|
|
49
|
+
.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee; color: #333333; }
|
|
50
|
+
.ui-widget-content a { color: #333333; }
|
|
51
|
+
.ui-widget-header { border: 1px solid #e78f08; background: #f6a828; color: #ffffff; font-weight: bold; }
|
|
52
|
+
.ui-widget-header a { color: #ffffff; }
|
|
53
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module TranslationPanel
|
|
2
|
+
class InstallGenerator < Rails::Generators::Base
|
|
3
|
+
source_root File.expand_path("../../../../app/assets", __FILE__)
|
|
4
|
+
desc "copies TranslationPanel's javascript and stylesheet into vendor/assets"
|
|
5
|
+
|
|
6
|
+
def copy_asset_files
|
|
7
|
+
copy_file "javascripts/translation_panel.js.coffee",
|
|
8
|
+
"vendor/assets/javascripts/translation_panel.js.coffee"
|
|
9
|
+
copy_file "stylesheets/translation_panel.css.scss",
|
|
10
|
+
"vendor/assets/stylesheets/translation_panel.css.scss"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module TranslationPanel
|
|
2
|
+
class Filter
|
|
3
|
+
include ActionView::Helpers::TagHelper
|
|
4
|
+
|
|
5
|
+
def initialize(save_url, condition = true)
|
|
6
|
+
@save_url = save_url
|
|
7
|
+
@condition = condition
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def before(controller)
|
|
11
|
+
TranslationPanel.show! if controller.send(@condition)
|
|
12
|
+
true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def after(controller)
|
|
16
|
+
if controller.send(@condition)
|
|
17
|
+
case controller.response.content_type
|
|
18
|
+
when "text/html"
|
|
19
|
+
return unless page = controller.response.body
|
|
20
|
+
header_part = tag :link, :href => "/assets/translation_panel.css",
|
|
21
|
+
:media => "screen", :rel => "stylesheet", :type => "text/css"
|
|
22
|
+
header_part+= content_tag :script, "", :src => "/assets/translation_panel.js",
|
|
23
|
+
:type => "text/javascript"
|
|
24
|
+
page.insert page.index("</head>"), header_part
|
|
25
|
+
body_part = content_tag :script,
|
|
26
|
+
"translationPanel = {translates: #{TranslationPanel.values.to_json}, action: '#{@save_url}', locale: '#{I18n.locale}'}",
|
|
27
|
+
{:type => "text/javascript"}, false
|
|
28
|
+
page+= body_part
|
|
29
|
+
controller.response.body = page
|
|
30
|
+
when "text/javascript"
|
|
31
|
+
return unless controller.response.body
|
|
32
|
+
body_part = ";$.translator.addTranslates(#{TranslationPanel.values.to_json});"
|
|
33
|
+
controller.response.body+= body_part
|
|
34
|
+
end
|
|
35
|
+
TranslationPanel.kill!
|
|
36
|
+
end
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module TranslationPanel
|
|
2
|
+
class RedisBackend < I18n::Backend::KeyValue
|
|
3
|
+
def initialize(store)
|
|
4
|
+
@subtrees = false
|
|
5
|
+
@store = store
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
protected
|
|
9
|
+
def lookup(locale, key, scope = [], options = {})
|
|
10
|
+
key = normalize_flat_keys(locale, key, scope, options[:separator])
|
|
11
|
+
count = options[:count]
|
|
12
|
+
if !count && value = @store["#{locale}.#{key}"]
|
|
13
|
+
TranslationPanel.push key if TranslationPanel.show?
|
|
14
|
+
ActiveSupport::JSON.decode(value) if value
|
|
15
|
+
else # look in namespace
|
|
16
|
+
store_count_keys(locale, key) if count
|
|
17
|
+
full_keys = @store.keys "#{locale}.#{key}.*"
|
|
18
|
+
if full_keys.empty?
|
|
19
|
+
TranslationPanel.push key if TranslationPanel.show?
|
|
20
|
+
nil
|
|
21
|
+
else
|
|
22
|
+
keys = full_keys.map{ |full_key| full_key.partition("#{locale}.")[2] }
|
|
23
|
+
TranslationPanel.push keys if TranslationPanel.show?
|
|
24
|
+
flatten_result = full_keys.inject({}) do |result, full_key|
|
|
25
|
+
value = @store[full_key]
|
|
26
|
+
value = ActiveSupport::JSON.decode(value) if value
|
|
27
|
+
result.merge full_key.partition("#{locale}.#{key}.")[2] => value
|
|
28
|
+
end
|
|
29
|
+
expand_keys(flatten_result).deep_symbolize_keys
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def expand_keys(flatten_hash)
|
|
35
|
+
expanded_hash = {}
|
|
36
|
+
flatten_hash.each do |key, value|
|
|
37
|
+
key_parts = key.partition "."
|
|
38
|
+
if key_parts[2].empty?
|
|
39
|
+
expanded_hash.deep_merge! key => value
|
|
40
|
+
else
|
|
41
|
+
expanded_hash.deep_merge! key_parts[0] => expand_keys(key_parts[2] => value)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
expanded_hash
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def store_count_keys(locale, key)
|
|
48
|
+
if TranslationPanel.show?
|
|
49
|
+
I18n.t!('i18n.plural.keys', :locale => locale).each do |k|
|
|
50
|
+
unless translate_present?(locale, "#{key}.#{k}")
|
|
51
|
+
I18n.backend.store_translations locale, {"#{key}.#{k}" => ""}, :escape => false
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
rescue
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def translate_present?(locale, key)
|
|
60
|
+
I18n.t!(key, :locale => locale)
|
|
61
|
+
rescue
|
|
62
|
+
false
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require "translation_panel/filter"
|
|
2
|
+
require "translation_panel/redis_backend"
|
|
3
|
+
|
|
4
|
+
# Using with Redis:
|
|
5
|
+
# 1. Run redis-server
|
|
6
|
+
# 2. Set up redis connection settings and register RedisTranslator::Backend as
|
|
7
|
+
# i18n backend in initializers:
|
|
8
|
+
# require 'redis_translator'
|
|
9
|
+
# I18n.backend = RedisTranslator::Backend.new(Redis.new)
|
|
10
|
+
# # or in chain with another backend
|
|
11
|
+
# 3. Create action which receive translation pair and saves it. Don't forget to
|
|
12
|
+
# create route for GET-requests to this action
|
|
13
|
+
# class Admin::TranslationsController < ApplicationController
|
|
14
|
+
# def new
|
|
15
|
+
# I18n.backend.store_translations params[:locale], {params[:key] => params[:value]},
|
|
16
|
+
# :escape => false
|
|
17
|
+
# render :text => 'ok', :content_type => "text/plain"
|
|
18
|
+
# end
|
|
19
|
+
# end
|
|
20
|
+
# 4. Create around filter for actions, where needed to show TranslationPanel
|
|
21
|
+
# frontend panel. Initializator receives path for action and condition.
|
|
22
|
+
# around_filter TranslationPanel::Filter.new('/admin/translations/new', :show_panel?)
|
|
23
|
+
# 5. TranslationPanel's javascript and stylesheet can be customized by copying
|
|
24
|
+
# necessary files from +app/assets+ to app's +vendor/assets+. It can be done
|
|
25
|
+
# automatically by run:
|
|
26
|
+
# $ rails generate redis_translator:install
|
|
27
|
+
|
|
28
|
+
module TranslationPanel
|
|
29
|
+
class << self
|
|
30
|
+
def show!
|
|
31
|
+
Thread.current[:translations_list] = []
|
|
32
|
+
Thread.current[:collect_translation_data] = true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def kill!
|
|
36
|
+
Thread.current[:translations_list] = nil
|
|
37
|
+
Thread.current[:collect_translation_data] = nil
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def show?
|
|
41
|
+
Thread.current[:collect_translation_data]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def push value
|
|
45
|
+
Thread.current[:translations_list] << value
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def values
|
|
49
|
+
Thread.current[:collect_translation_data] = false
|
|
50
|
+
Thread.current[:translations_list].uniq.map do |key|
|
|
51
|
+
value = get_value(key)
|
|
52
|
+
{:key => key, :value => value} if value.is_a?(String)
|
|
53
|
+
end.compact
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def get_value(key)
|
|
57
|
+
I18n.translate! key
|
|
58
|
+
rescue
|
|
59
|
+
""
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/spec/app/.gitignore
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
class Admin::TranslationsController < ApplicationController
|
|
2
|
+
def new
|
|
3
|
+
params[:value] = nil if params[:value].empty?
|
|
4
|
+
I18n.backend.store_translations params[:locale], {params[:key] => params[:value]}, :escape => false
|
|
5
|
+
render :text => 'ok', :content_type => "text/plain"
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
class ApplicationController < ActionController::Base
|
|
2
|
+
protect_from_forgery
|
|
3
|
+
respond_to :html
|
|
4
|
+
around_filter TranslationPanel::Filter.new('/admin/translations/new', :show_translator?)
|
|
5
|
+
|
|
6
|
+
protected
|
|
7
|
+
def show_translator?
|
|
8
|
+
params[:translator].present?
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require File.expand_path('../boot', __FILE__)
|
|
2
|
+
|
|
3
|
+
require "action_controller/railtie"
|
|
4
|
+
require "action_mailer/railtie"
|
|
5
|
+
require "active_resource/railtie"
|
|
6
|
+
|
|
7
|
+
Bundler.require(:default, Rails.env) if defined?(Bundler)
|
|
8
|
+
|
|
9
|
+
module App
|
|
10
|
+
class Application < Rails::Application
|
|
11
|
+
config.i18n.default_locale = :ru
|
|
12
|
+
config.encoding = "utf-8"
|
|
13
|
+
config.assets.enabled = true
|
|
14
|
+
config.generators do |g|
|
|
15
|
+
g.test_framework :rspec
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
App::Application.configure do
|
|
2
|
+
config.cache_classes = false
|
|
3
|
+
config.whiny_nils = true
|
|
4
|
+
config.consider_all_requests_local = true
|
|
5
|
+
config.action_controller.perform_caching = false
|
|
6
|
+
config.action_mailer.raise_delivery_errors = false
|
|
7
|
+
config.active_support.deprecation = :log
|
|
8
|
+
config.action_dispatch.best_standards_support = :builtin
|
|
9
|
+
config.assets.compress = false
|
|
10
|
+
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
|
|
11
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
App::Application.configure do
|
|
2
|
+
config.cache_classes = true
|
|
3
|
+
config.consider_all_requests_local = false
|
|
4
|
+
config.action_controller.perform_caching = true
|
|
5
|
+
config.serve_static_assets = false
|
|
6
|
+
config.assets.compress = true
|
|
7
|
+
config.assets.js_compressor = :uglifier
|
|
8
|
+
config.action_dispatch.x_sendfile_header = "X-Sendfile"
|
|
9
|
+
config.i18n.fallbacks = true
|
|
10
|
+
config.active_support.deprecation = :notify
|
|
11
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
App::Application.configure do
|
|
2
|
+
config.cache_classes = true
|
|
3
|
+
config.serve_static_assets = true
|
|
4
|
+
config.static_cache_control = "public, max-age=3600"
|
|
5
|
+
config.whiny_nils = true
|
|
6
|
+
config.consider_all_requests_local = true
|
|
7
|
+
config.action_controller.perform_caching = false
|
|
8
|
+
config.action_dispatch.show_exceptions = false
|
|
9
|
+
config.action_controller.allow_forgery_protection = false
|
|
10
|
+
config.action_mailer.delivery_method = :test
|
|
11
|
+
config.active_support.deprecation = :stderr
|
|
12
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
App::Application.config.secret_token = '11111111112222222222333333333344444444444455555555555555'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
App::Application.config.session_store :cookie_store, :key => '_app_session'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
daemonize yes
|
|
2
|
+
pidfile spec/app/db/redis.pid
|
|
3
|
+
port 6381
|
|
4
|
+
timeout 300
|
|
5
|
+
loglevel verbose
|
|
6
|
+
logfile stdout
|
|
7
|
+
databases 16
|
|
8
|
+
|
|
9
|
+
save 900 1
|
|
10
|
+
save 300 10
|
|
11
|
+
save 60 10000
|
|
12
|
+
rdbcompression yes
|
|
13
|
+
dbfilename app_test.rdb
|
|
14
|
+
dir spec/app/db/
|
|
15
|
+
|
|
16
|
+
slave-serve-stale-data yes
|
|
17
|
+
|
|
18
|
+
appendonly no
|
|
19
|
+
appendfsync everysec
|
|
20
|
+
no-appendfsync-on-rewrite no
|
|
21
|
+
|
|
22
|
+
vm-enabled no
|
|
23
|
+
vm-swap-file /tmp/redis.swap
|
|
24
|
+
vm-max-memory 0
|
|
25
|
+
vm-page-size 32
|
|
26
|
+
vm-pages 134217728
|
|
27
|
+
vm-max-threads 4
|
|
28
|
+
|
|
29
|
+
hash-max-zipmap-entries 512
|
|
30
|
+
hash-max-zipmap-value 64
|
|
31
|
+
list-max-ziplist-entries 512
|
|
32
|
+
list-max-ziplist-value 64
|
|
33
|
+
set-max-intset-entries 512
|
|
34
|
+
activerehashing yes
|
data/spec/app/config.ru
ADDED
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe TranslationPanel::RedisBackend do
|
|
5
|
+
before :all do
|
|
6
|
+
I18n.backend.store.flushdb
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "stores data, represented by pair key-value" do
|
|
10
|
+
I18n.backend.store_translations "ru", {"simple.key" => "Simple key"}, :escape => false
|
|
11
|
+
I18n.translate("simple.key").should == "Simple key"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "stores data, represented by hash" do
|
|
15
|
+
I18n.backend.store_translations "ru", :hashed => {:value => "Hashed Value"}
|
|
16
|
+
I18n.translate("hashed.value").should == "Hashed Value"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "stores data, when some pairs" do
|
|
20
|
+
I18n.backend.store_translations "ru", {"first.key" => "First", "second.key" => "Second"}, :escape => false
|
|
21
|
+
I18n.translate("first.key").should == "First"
|
|
22
|
+
I18n.translate("second.key").should == "Second"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "stores data, when some translations in hash" do
|
|
26
|
+
I18n.backend.store_translations "ru", :one => {:two => "Two", :three => "Three"}
|
|
27
|
+
I18n.translate("one.two").should == "Two"
|
|
28
|
+
I18n.translate("one.three").should == "Three"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "searches in scope" do
|
|
32
|
+
I18n.translate(:key, :scope => :simple).should == "Simple key"
|
|
33
|
+
I18n.translate(:value, :scope => :hashed).should == "Hashed Value"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "searches some results in one scope" do
|
|
37
|
+
I18n.translate([:two, :three], :scope =>:one).should == ["Two","Three"]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "searches in namespace" do
|
|
41
|
+
I18n.translate(:one).should include(:two => "Two", :three => "Three")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "searches deep in namespace" do
|
|
45
|
+
I18n.backend.store_translations "ru", :one => {:four => {:five => "Five"}}
|
|
46
|
+
I18n.translate(:one).should include(:four => {:five => "Five"})
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "interpolates strings" do
|
|
50
|
+
I18n.backend.store_translations "ru", :hello => "Hello %{name}!"
|
|
51
|
+
I18n.translate(:hello, :name => 'Mik').should == "Hello Mik!"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "pluralizes translations" do
|
|
55
|
+
I18n.backend.store_translations "ru", :bug => {:one => "1 bug", :other => "%{count} bugs"}
|
|
56
|
+
I18n.translate(:bug, :count => 1).should == "1 bug"
|
|
57
|
+
I18n.translate(:bug, :count => 2).should == "2 bugs"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'deletes existing translation with nil value' do
|
|
61
|
+
I18n.backend.store_translations "ru", "simple.key" => nil
|
|
62
|
+
I18n.backend.store["simple.key"].should be_nil
|
|
63
|
+
end
|
|
64
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe TranslationPanel do
|
|
4
|
+
it "should be valid" do
|
|
5
|
+
TranslationPanel.should be_a(Module)
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe HomeController, :type => :controller do
|
|
10
|
+
render_views
|
|
11
|
+
describe "index" do
|
|
12
|
+
before :all do
|
|
13
|
+
I18n.backend.store.flushdb
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "normal processing" do
|
|
17
|
+
it "doesn't call TranslationPanel in filters" do
|
|
18
|
+
TranslationPanel.should_not_receive(:show!)
|
|
19
|
+
TranslationPanel.should_not_receive(:kill!)
|
|
20
|
+
get :index
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "processing with TranslationPanel" do
|
|
25
|
+
it "shows links to TranslationPanel assets" do
|
|
26
|
+
get :index, :translator => true
|
|
27
|
+
response.body.should have_selector("link", :href => "/assets/redis_translator.css")
|
|
28
|
+
response.body.should have_selector("script", :src => "/assets/redis_translator.js")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe "both processings" do
|
|
33
|
+
before :all do
|
|
34
|
+
I18n.backend.store_translations "ru", :some_i18n_key => "Some Key!"
|
|
35
|
+
I18n.backend.store_translations "ru", :html_part => "<b>Some HTML</b>"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "shows existing tanslates" do
|
|
39
|
+
get :index
|
|
40
|
+
response.body.should include("Some Key!")
|
|
41
|
+
response.body.should have_selector("b") do |bold|
|
|
42
|
+
bold.should include("Some HTML")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it "shows stubs for absent translates" do
|
|
47
|
+
get :index
|
|
48
|
+
response.body.should have_selector("span.translation_missing",
|
|
49
|
+
:title => "translation missing: ru.long.chain.of.keys")
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe Admin::TranslationsController, :type => :controller do
|
|
56
|
+
describe "new" do
|
|
57
|
+
before :all do
|
|
58
|
+
I18n.backend.store.flushdb
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "saves new translation" do
|
|
62
|
+
get :new, :locale => "ru", :key => "some.key", :value => "some_value"
|
|
63
|
+
I18n.t("some.key", :locale => "ru").should == "some_value"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'updates existing translation' do
|
|
67
|
+
get :new, :locale => "ru", :key => "some.key", :value => "other_value"
|
|
68
|
+
I18n.t("some.key", :locale => "ru").should == "other_value"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{translation_panel}
|
|
8
|
+
s.version = "0.1.0"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = [%q{Mik-die}]
|
|
12
|
+
s.date = %q{2011-07-19}
|
|
13
|
+
s.description = %q{I18n backend, based on redis, with frontend panel for translations}
|
|
14
|
+
s.email = %q{MikDiet@gmail.com}
|
|
15
|
+
s.extra_rdoc_files = [
|
|
16
|
+
"README.rdoc"
|
|
17
|
+
]
|
|
18
|
+
s.files = [
|
|
19
|
+
".rspec",
|
|
20
|
+
".rvmrc",
|
|
21
|
+
"Gemfile",
|
|
22
|
+
"Gemfile.lock",
|
|
23
|
+
"MIT-LICENSE",
|
|
24
|
+
"README.rdoc",
|
|
25
|
+
"Rakefile",
|
|
26
|
+
"VERSION",
|
|
27
|
+
"app/assets/javascripts/translation_panel.js.coffee",
|
|
28
|
+
"app/assets/stylesheets/translation_panel.css.scss",
|
|
29
|
+
"lib/generators/translation_panel/install_generator.rb",
|
|
30
|
+
"lib/translation_panel.rb",
|
|
31
|
+
"lib/translation_panel/filter.rb",
|
|
32
|
+
"lib/translation_panel/redis_backend.rb",
|
|
33
|
+
"spec/app/.gitignore",
|
|
34
|
+
"spec/app/app/controllers/admin/translations_controller.rb",
|
|
35
|
+
"spec/app/app/controllers/application_controller.rb",
|
|
36
|
+
"spec/app/app/controllers/home_controller.rb",
|
|
37
|
+
"spec/app/app/views/home/index.html.erb",
|
|
38
|
+
"spec/app/config.ru",
|
|
39
|
+
"spec/app/config/application.rb",
|
|
40
|
+
"spec/app/config/boot.rb",
|
|
41
|
+
"spec/app/config/environment.rb",
|
|
42
|
+
"spec/app/config/environments/development.rb",
|
|
43
|
+
"spec/app/config/environments/production.rb",
|
|
44
|
+
"spec/app/config/environments/test.rb",
|
|
45
|
+
"spec/app/config/initializers/i18n.rb",
|
|
46
|
+
"spec/app/config/initializers/secret_token.rb",
|
|
47
|
+
"spec/app/config/initializers/session_store.rb",
|
|
48
|
+
"spec/app/config/redis.yml",
|
|
49
|
+
"spec/app/config/redis/test.conf",
|
|
50
|
+
"spec/app/config/routes.rb",
|
|
51
|
+
"spec/app/db/.gitkeep",
|
|
52
|
+
"spec/integration/navigation_spec.rb",
|
|
53
|
+
"spec/lib/redis_backend_spec.rb",
|
|
54
|
+
"spec/spec_helper.rb",
|
|
55
|
+
"spec/translation_panel_spec.rb",
|
|
56
|
+
"translation_panel.gemspec"
|
|
57
|
+
]
|
|
58
|
+
s.homepage = %q{http://github.com/Mik-die/translation_panel}
|
|
59
|
+
s.licenses = [%q{MIT}]
|
|
60
|
+
s.require_paths = [%q{lib}]
|
|
61
|
+
s.rubygems_version = %q{1.8.5}
|
|
62
|
+
s.summary = %q{I18n backend}
|
|
63
|
+
|
|
64
|
+
if s.respond_to? :specification_version then
|
|
65
|
+
s.specification_version = 3
|
|
66
|
+
|
|
67
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
68
|
+
s.add_runtime_dependency(%q<rails>, [">= 3.1.0.rc4"])
|
|
69
|
+
s.add_runtime_dependency(%q<redis>, [">= 0"])
|
|
70
|
+
s.add_runtime_dependency(%q<yajl-ruby>, [">= 0"])
|
|
71
|
+
s.add_development_dependency(%q<sqlite3>, [">= 0"])
|
|
72
|
+
s.add_development_dependency(%q<capybara>, [">= 0.4.0"])
|
|
73
|
+
s.add_development_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
|
|
74
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
|
75
|
+
else
|
|
76
|
+
s.add_dependency(%q<rails>, [">= 3.1.0.rc4"])
|
|
77
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
|
78
|
+
s.add_dependency(%q<yajl-ruby>, [">= 0"])
|
|
79
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
|
80
|
+
s.add_dependency(%q<capybara>, [">= 0.4.0"])
|
|
81
|
+
s.add_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
|
|
82
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
83
|
+
end
|
|
84
|
+
else
|
|
85
|
+
s.add_dependency(%q<rails>, [">= 3.1.0.rc4"])
|
|
86
|
+
s.add_dependency(%q<redis>, [">= 0"])
|
|
87
|
+
s.add_dependency(%q<yajl-ruby>, [">= 0"])
|
|
88
|
+
s.add_dependency(%q<sqlite3>, [">= 0"])
|
|
89
|
+
s.add_dependency(%q<capybara>, [">= 0.4.0"])
|
|
90
|
+
s.add_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
|
|
91
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
metadata
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: translation_panel
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease:
|
|
5
|
+
version: 0.1.0
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Mik-die
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
|
|
13
|
+
date: 2011-07-19 00:00:00 Z
|
|
14
|
+
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: rails
|
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
18
|
+
none: false
|
|
19
|
+
requirements:
|
|
20
|
+
- - ">="
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: 3.1.0.rc4
|
|
23
|
+
type: :runtime
|
|
24
|
+
prerelease: false
|
|
25
|
+
version_requirements: *id001
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: redis
|
|
28
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
29
|
+
none: false
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: "0"
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: *id002
|
|
37
|
+
- !ruby/object:Gem::Dependency
|
|
38
|
+
name: yajl-ruby
|
|
39
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
40
|
+
none: false
|
|
41
|
+
requirements:
|
|
42
|
+
- - ">="
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: "0"
|
|
45
|
+
type: :runtime
|
|
46
|
+
prerelease: false
|
|
47
|
+
version_requirements: *id003
|
|
48
|
+
- !ruby/object:Gem::Dependency
|
|
49
|
+
name: sqlite3
|
|
50
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
51
|
+
none: false
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: "0"
|
|
56
|
+
type: :development
|
|
57
|
+
prerelease: false
|
|
58
|
+
version_requirements: *id004
|
|
59
|
+
- !ruby/object:Gem::Dependency
|
|
60
|
+
name: capybara
|
|
61
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
|
62
|
+
none: false
|
|
63
|
+
requirements:
|
|
64
|
+
- - ">="
|
|
65
|
+
- !ruby/object:Gem::Version
|
|
66
|
+
version: 0.4.0
|
|
67
|
+
type: :development
|
|
68
|
+
prerelease: false
|
|
69
|
+
version_requirements: *id005
|
|
70
|
+
- !ruby/object:Gem::Dependency
|
|
71
|
+
name: rspec-rails
|
|
72
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ">="
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: 2.0.0.beta
|
|
78
|
+
type: :development
|
|
79
|
+
prerelease: false
|
|
80
|
+
version_requirements: *id006
|
|
81
|
+
- !ruby/object:Gem::Dependency
|
|
82
|
+
name: jeweler
|
|
83
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
|
84
|
+
none: false
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: "0"
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: *id007
|
|
92
|
+
description: I18n backend, based on redis, with frontend panel for translations
|
|
93
|
+
email: MikDiet@gmail.com
|
|
94
|
+
executables: []
|
|
95
|
+
|
|
96
|
+
extensions: []
|
|
97
|
+
|
|
98
|
+
extra_rdoc_files:
|
|
99
|
+
- README.rdoc
|
|
100
|
+
files:
|
|
101
|
+
- .rspec
|
|
102
|
+
- .rvmrc
|
|
103
|
+
- Gemfile
|
|
104
|
+
- Gemfile.lock
|
|
105
|
+
- MIT-LICENSE
|
|
106
|
+
- README.rdoc
|
|
107
|
+
- Rakefile
|
|
108
|
+
- VERSION
|
|
109
|
+
- app/assets/javascripts/translation_panel.js.coffee
|
|
110
|
+
- app/assets/stylesheets/translation_panel.css.scss
|
|
111
|
+
- lib/generators/translation_panel/install_generator.rb
|
|
112
|
+
- lib/translation_panel.rb
|
|
113
|
+
- lib/translation_panel/filter.rb
|
|
114
|
+
- lib/translation_panel/redis_backend.rb
|
|
115
|
+
- spec/app/.gitignore
|
|
116
|
+
- spec/app/app/controllers/admin/translations_controller.rb
|
|
117
|
+
- spec/app/app/controllers/application_controller.rb
|
|
118
|
+
- spec/app/app/controllers/home_controller.rb
|
|
119
|
+
- spec/app/app/views/home/index.html.erb
|
|
120
|
+
- spec/app/config.ru
|
|
121
|
+
- spec/app/config/application.rb
|
|
122
|
+
- spec/app/config/boot.rb
|
|
123
|
+
- spec/app/config/environment.rb
|
|
124
|
+
- spec/app/config/environments/development.rb
|
|
125
|
+
- spec/app/config/environments/production.rb
|
|
126
|
+
- spec/app/config/environments/test.rb
|
|
127
|
+
- spec/app/config/initializers/i18n.rb
|
|
128
|
+
- spec/app/config/initializers/secret_token.rb
|
|
129
|
+
- spec/app/config/initializers/session_store.rb
|
|
130
|
+
- spec/app/config/redis.yml
|
|
131
|
+
- spec/app/config/redis/test.conf
|
|
132
|
+
- spec/app/config/routes.rb
|
|
133
|
+
- spec/app/db/.gitkeep
|
|
134
|
+
- spec/integration/navigation_spec.rb
|
|
135
|
+
- spec/lib/redis_backend_spec.rb
|
|
136
|
+
- spec/spec_helper.rb
|
|
137
|
+
- spec/translation_panel_spec.rb
|
|
138
|
+
- translation_panel.gemspec
|
|
139
|
+
homepage: http://github.com/Mik-die/translation_panel
|
|
140
|
+
licenses:
|
|
141
|
+
- MIT
|
|
142
|
+
post_install_message:
|
|
143
|
+
rdoc_options: []
|
|
144
|
+
|
|
145
|
+
require_paths:
|
|
146
|
+
- lib
|
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
|
+
none: false
|
|
149
|
+
requirements:
|
|
150
|
+
- - ">="
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
hash: -173789987
|
|
153
|
+
segments:
|
|
154
|
+
- 0
|
|
155
|
+
version: "0"
|
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
|
+
none: false
|
|
158
|
+
requirements:
|
|
159
|
+
- - ">="
|
|
160
|
+
- !ruby/object:Gem::Version
|
|
161
|
+
version: "0"
|
|
162
|
+
requirements: []
|
|
163
|
+
|
|
164
|
+
rubyforge_project:
|
|
165
|
+
rubygems_version: 1.8.5
|
|
166
|
+
signing_key:
|
|
167
|
+
specification_version: 3
|
|
168
|
+
summary: I18n backend
|
|
169
|
+
test_files: []
|
|
170
|
+
|