couch_i18n 0.3.0 → 0.3.1
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.
- checksums.yaml +7 -0
- data/README.rdoc +0 -1
- data/app/assets/javascripts/couch_i18n/application.js.coffee +8 -0
- data/app/assets/stylesheets/couch_i18n/application.sass +4 -0
- data/app/assets/stylesheets/couch_i18n/components/_buttons.sass +11 -0
- data/app/assets/stylesheets/couch_i18n/components/_forms.sass +45 -0
- data/app/assets/stylesheets/couch_i18n/components/_offset_navigation.sass +19 -0
- data/app/assets/stylesheets/couch_i18n/foundation_and_overrides.scss +1447 -0
- data/app/assets/stylesheets/couch_i18n/{structure.css.scss → structure.scss} +0 -24
- data/app/controllers/couch_i18n/application_controller.rb +5 -1
- data/app/controllers/couch_i18n/translations_controller.rb +24 -19
- data/app/models/couch_i18n/translation.rb +81 -35
- data/app/views/couch_i18n/application/_error_messages.html.slim +6 -0
- data/app/views/couch_i18n/translations/_form.html.slim +15 -0
- data/app/views/couch_i18n/translations/edit.html.slim +2 -0
- data/app/views/couch_i18n/translations/index.html.slim +91 -0
- data/app/views/couch_i18n/translations/new.html.slim +2 -0
- data/app/views/kaminari/couch_i18n/_first_page.html.erb +3 -0
- data/app/views/kaminari/couch_i18n/_first_page.html.slim +2 -0
- data/app/views/kaminari/couch_i18n/_gap.html.erb +3 -0
- data/app/views/kaminari/couch_i18n/_gap.html.slim +2 -0
- data/app/views/kaminari/couch_i18n/_last_page.html.erb +3 -0
- data/app/views/kaminari/couch_i18n/_last_page.html.slim +2 -0
- data/app/views/kaminari/couch_i18n/_next_page.html.erb +3 -0
- data/app/views/kaminari/couch_i18n/_next_page.html.slim +2 -0
- data/app/views/kaminari/couch_i18n/_page.html.erb +3 -0
- data/app/views/kaminari/couch_i18n/_page.html.slim +2 -0
- data/app/views/kaminari/couch_i18n/_paginator.html.erb +17 -0
- data/app/views/kaminari/couch_i18n/_paginator.html.slim +12 -0
- data/app/views/kaminari/couch_i18n/_prev_page.html.erb +3 -0
- data/app/views/kaminari/couch_i18n/_prev_page.html.slim +2 -0
- data/app/views/layouts/couch_i18n/application.html.slim +28 -0
- data/config/initializers/assets.rb +1 -0
- data/config/locales/couch_i18n.en.yml +8 -2
- data/config/routes.rb +2 -1
- data/lib/couch_i18n/active_model_errors.rb +2 -2
- data/lib/couch_i18n/backend.rb +1 -5
- data/lib/couch_i18n/engine.rb +2 -0
- data/lib/couch_i18n/store.rb +24 -12
- data/lib/couch_i18n/version.rb +3 -0
- data/lib/couch_i18n.rb +30 -9
- metadata +51 -43
- data/app/assets/javascripts/couch_i18n/application.js +0 -10
- data/app/assets/stylesheets/couch_i18n/application.css +0 -7
- data/app/assets/stylesheets/couch_i18n/bootstrap_and_override.css.sass +0 -6
- data/app/views/couch_i18n/application/_error_messages.html.haml +0 -6
- data/app/views/couch_i18n/translations/_form.html.haml +0 -17
- data/app/views/couch_i18n/translations/edit.html.haml +0 -4
- data/app/views/couch_i18n/translations/index.html.haml +0 -84
- data/app/views/couch_i18n/translations/new.html.haml +0 -4
- data/app/views/couch_i18n/translations/new.html.haml~ +0 -4
- data/app/views/layouts/couch_i18n/application.html.haml +0 -27
- /data/app/assets/stylesheets/couch_i18n/{alerts.css.scss → alerts.scss} +0 -0
- /data/app/views/couch_i18n/application/{_alerts.html.haml → _alerts.html.slim} +0 -0
@@ -46,30 +46,6 @@ form{
|
|
46
46
|
.untranslated-label{
|
47
47
|
display: inline;
|
48
48
|
}
|
49
|
-
.offset-navigation-block{
|
50
|
-
border-style: double;
|
51
|
-
border-color: #444;
|
52
|
-
border-left-width: 0;
|
53
|
-
border-right-width: 0;
|
54
|
-
padding: 5px 0;
|
55
|
-
margin-top: 5px;
|
56
|
-
.offset-navigation-deeper, .offset-navigation-higher{
|
57
|
-
a{
|
58
|
-
float: left;
|
59
|
-
margin-right: 5px;
|
60
|
-
margin-top: 5px;
|
61
|
-
padding: 4px;
|
62
|
-
border: 1px solid #aaa;
|
63
|
-
&:hover {
|
64
|
-
background-color: #ddd;
|
65
|
-
border-color: black;
|
66
|
-
}
|
67
|
-
}
|
68
|
-
}
|
69
|
-
.offset-navigation-form{
|
70
|
-
margin-top: 5px;
|
71
|
-
}
|
72
|
-
}
|
73
49
|
.clearing{
|
74
50
|
clear: both;
|
75
51
|
}
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module CouchI18n
|
2
2
|
class ApplicationController < ::ApplicationController
|
3
|
-
|
3
|
+
before_action :authorize_user
|
4
4
|
layout :couch_i18n_layout
|
5
5
|
|
6
6
|
private
|
7
7
|
|
8
|
+
def cmtool_user
|
9
|
+
main_app.cmtool_user
|
10
|
+
end
|
11
|
+
|
8
12
|
def couch_i18n_layout
|
9
13
|
defined?(Cmtool) ? 'cmtool/application' : 'couch_i18n/application'
|
10
14
|
# Does not integrate well with cmtool layout at the moment (2012-12-17)
|
@@ -40,16 +40,16 @@ module CouchI18n
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def new
|
43
|
-
@translation = CouchI18n::Translation.new :
|
43
|
+
@translation = CouchI18n::Translation.new translation_key: params[:offset]
|
44
44
|
end
|
45
45
|
|
46
46
|
def create
|
47
|
-
@translation = CouchI18n::Translation.new
|
47
|
+
@translation = CouchI18n::Translation.new translation_params
|
48
48
|
if @translation.value.present? && params[:is_json].present?
|
49
49
|
@translation.value = JSON.parse(@translation.value)
|
50
50
|
end
|
51
51
|
if @translation.save
|
52
|
-
redirect_to({:action => :index, :offset => @translation.
|
52
|
+
redirect_to({:action => :index, :offset => @translation.translation_key.to_s.sub(/\.[\w\s-]+$/, '')}, :notice => I18n.t('couch_i18n.action.create.successful', :model => CouchI18n::Translation.model_name.human))
|
53
53
|
else
|
54
54
|
render :action => :new
|
55
55
|
end
|
@@ -64,11 +64,12 @@ module CouchI18n
|
|
64
64
|
def update
|
65
65
|
@translation = CouchI18n::Translation.find(params[:id])
|
66
66
|
@translation.translated = true
|
67
|
-
|
68
|
-
|
67
|
+
tparams = translation_params
|
68
|
+
if tparams["value"].present? && params[:is_json].present?
|
69
|
+
tparams["value"] = JSON.parse(tparams["value"])
|
69
70
|
end
|
70
|
-
if @translation.update_attributes(
|
71
|
-
redirect_to({:action => :index, :offset => @translation.
|
71
|
+
if @translation.update_attributes(tparams)
|
72
|
+
redirect_to({:action => :index, :offset => @translation.translation_key.to_s.sub(/\.[\w\s-]+$/, '')}, :notice => I18n.t('couch_i18n.action.update.successful', :model => CouchI18n::Translation.model_name.human))
|
72
73
|
else
|
73
74
|
render :action => :edit
|
74
75
|
end
|
@@ -79,7 +80,7 @@ module CouchI18n
|
|
79
80
|
if @translation.destroy
|
80
81
|
flash[:notice] = I18n.t('couch_i18n.action.destroy.successful', :model => CouchI18n::Translation.model_name.human)
|
81
82
|
end
|
82
|
-
redirect_to({:action => :index, :offset => @translation.
|
83
|
+
redirect_to({:action => :index, :offset => @translation.translation_key.to_s.sub(/\.\w+$/, '')})
|
83
84
|
end
|
84
85
|
|
85
86
|
# POST /couch_i18n/translations/export
|
@@ -102,12 +103,12 @@ module CouchI18n
|
|
102
103
|
if params[:exportformat] == 'csv'
|
103
104
|
response.headers['Content-Type'] = 'text/csv'
|
104
105
|
response.headers['Content-Disposition'] = %{attachment; filename="#{base_filename}.csv"}
|
105
|
-
render :text => @translations.map{|s| [s.
|
106
|
+
render :text => @translations.map{|s| [s.translation_key, s.translation_value.to_json].join(',')}.join("\n")
|
106
107
|
elsif params[:exportformat] == 'json'
|
107
108
|
response.headers['Content-Type'] = 'application/json'
|
108
109
|
response.headers['Content-Disposition'] = %{attachment; filename="#{base_filename}.json"}
|
109
110
|
# render :text => CouchI18n.indent_keys(@translations).to_json # for indented json
|
110
|
-
render :json => @translations.map{|s| {s.
|
111
|
+
render :json => @translations.map{|s| {s.translation_key => s.translation_value}}.to_json
|
111
112
|
else #yaml
|
112
113
|
response.headers['Content-Type'] = 'application/x-yaml'
|
113
114
|
response.headers['Content-Disposition'] = %{attachment; filename="#{base_filename}.yml"}
|
@@ -118,28 +119,28 @@ module CouchI18n
|
|
118
119
|
# POST /couch_i18n/translations/import
|
119
120
|
# Import yml files
|
120
121
|
def import
|
121
|
-
redirect_to({:action => :index, :offset => params[:offset]}, :alert => I18n.t('couch_i18n.
|
122
|
+
redirect_to({:action => :index, :offset => params[:offset]}, :alert => I18n.t('couch_i18n.import.no_file_given')) and return unless params[:importfile].present?
|
122
123
|
filename = params[:importfile].original_filename
|
123
124
|
extension = filename.sub(/.*\./, '')
|
124
125
|
if extension == 'yml'
|
125
126
|
hash = YAML.load_file(params[:importfile].tempfile.path) rescue nil
|
126
|
-
redirect_to({:action => :index, :offset => params[:offset]}, :alert => I18n.t('couch_i18n.
|
127
|
+
redirect_to({:action => :index, :offset => params[:offset]}, :alert => I18n.t('couch_i18n.import.cannot_parse')) and return unless hash
|
127
128
|
CouchI18n.traverse_flatten_keys(hash).each do |key, value|
|
128
|
-
existing = CouchI18n::Translation.
|
129
|
+
existing = CouchI18n::Translation.find_by_translation_key(key)
|
129
130
|
if existing
|
130
|
-
if existing.
|
131
|
-
existing.
|
131
|
+
if existing.translation_value != value || !existing.translated?
|
132
|
+
existing.translation_value = value
|
132
133
|
existing.translated = true
|
133
134
|
existing.save
|
134
135
|
end
|
135
136
|
else
|
136
|
-
CouchI18n::Translation.create :
|
137
|
+
CouchI18n::Translation.create translation_key: key, translation_value: value
|
137
138
|
end
|
138
139
|
end
|
139
140
|
else
|
140
|
-
redirect_to({:action => :index, :offset => params[:offset]}, :alert => I18n.t('couch_i18n.
|
141
|
+
redirect_to({:action => :index, :offset => params[:offset]}, :alert => I18n.t('couch_i18n.import.extension_not_valid', :extension => extension)) and return
|
141
142
|
end
|
142
|
-
redirect_to({:action => :index, :offset => params[:offset]}, :notice => I18n.t('couch_i18n.
|
143
|
+
redirect_to({:action => :index, :offset => params[:offset]}, :notice => I18n.t('couch_i18n.import.notice', :filename => filename))
|
143
144
|
end
|
144
145
|
|
145
146
|
# Very dangarous action, please handle this with care, large removals are supported!
|
@@ -151,7 +152,7 @@ module CouchI18n
|
|
151
152
|
@translations = CouchI18n::Translation.all
|
152
153
|
end
|
153
154
|
@translations.map(&:destroy)
|
154
|
-
redirect_to({:action => :index}, :notice => I18n.t('couch_i18n.
|
155
|
+
redirect_to({:action => :index}, :notice => I18n.t('couch_i18n.general.offset_deleted_notice', :count => @translations.size, :offset => params[:offset]))
|
155
156
|
end
|
156
157
|
|
157
158
|
private
|
@@ -160,5 +161,9 @@ module CouchI18n
|
|
160
161
|
params[:untranslated].presence
|
161
162
|
end
|
162
163
|
helper_method :untranslated?
|
164
|
+
|
165
|
+
def translation_params
|
166
|
+
params.require(:translation).permit(:translation_key, :translation_value, :translated)
|
167
|
+
end
|
163
168
|
end
|
164
169
|
end
|
@@ -3,53 +3,86 @@ module CouchI18n
|
|
3
3
|
include SimplyStored::Couch
|
4
4
|
per_page_method :limit_value
|
5
5
|
|
6
|
-
property :
|
7
|
-
property :value
|
6
|
+
property :translation_value
|
8
7
|
property :translated, type: :boolean, default: true
|
9
8
|
|
10
|
-
|
9
|
+
def translation_key
|
10
|
+
id.present? ? id[3..-1] : nil
|
11
|
+
end
|
11
12
|
|
12
|
-
|
13
|
+
def key
|
14
|
+
translation_key
|
15
|
+
end
|
13
16
|
|
14
|
-
view :all_documents, :
|
15
|
-
|
17
|
+
view :all_documents, map_function: %|function(doc){
|
18
|
+
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation') {
|
19
|
+
emit(doc._id.substr(3), 1);
|
20
|
+
}
|
21
|
+
}|, type: :custom, reduce_function: '_sum'
|
22
|
+
#view :by_key, :key => :key
|
16
23
|
|
17
24
|
view :with_key_array, map_function: %|function(doc){
|
18
25
|
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation') {
|
19
|
-
emit(doc.
|
26
|
+
emit(doc._id.substr(3).split('.').slice(0, -1), 1);
|
20
27
|
}
|
21
28
|
}|, type: :raw, reduce_function: '_sum'
|
22
29
|
|
23
|
-
view :untranslated_view,
|
24
|
-
|
25
|
-
|
26
|
-
|
30
|
+
view :untranslated_view, map_function: %|function(doc){
|
31
|
+
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation' && !doc.translated) {
|
32
|
+
emit(doc._id.substr(3), 1);
|
33
|
+
}
|
34
|
+
}|, type: :custom, reduce_function: '_sum'
|
35
|
+
view :by_translation_value, key: :translation_value
|
36
|
+
view :untranslated_by_translation_value, key: :translation_value, conditions: "!doc['translated']"
|
37
|
+
view :by_translation_key_part, type: :custom, map_function: %|function(doc){
|
27
38
|
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation') {
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
39
|
+
doc._id.substr(3).split('.').forEach(function(key_part){
|
40
|
+
emit(key_part, 1)
|
41
|
+
})
|
32
42
|
}
|
33
43
|
}|, reduce_function: '_count'
|
34
44
|
|
35
|
-
view :
|
45
|
+
view :untranslated_by_translation_key_part, type: :custom, map_function: %|function(doc){
|
36
46
|
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation' && !doc.translated) {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
}
|
47
|
+
doc._id.substr(3).split('.').forEach(function(key_part){
|
48
|
+
emit(key_part, 1)
|
49
|
+
})
|
41
50
|
}
|
42
51
|
}|, reduce_function: '_count'
|
43
52
|
|
44
|
-
def self.
|
45
|
-
data = database.view(with_key_array(options.merge(:
|
53
|
+
def self.get_translation_keys_by_level(level = 0, options = {})
|
54
|
+
data = database.view(with_key_array(options.merge(group_level: level.succ)))["rows"]
|
46
55
|
# data = data.select{|h| h["key"].size > level } # Only select ones that have a deeper nesting
|
47
56
|
data.map{|h| h['key'][level].try(:to_sym)}.compact
|
48
57
|
end
|
49
58
|
|
59
|
+
def translation_key=(val)
|
60
|
+
self.id = "t::#{val}"
|
61
|
+
end
|
62
|
+
|
50
63
|
# Shorthand for selecting all stored with a given offset
|
51
64
|
def self.with_offset(offset, options = {})
|
52
|
-
|
65
|
+
key = "#{offset}.".."#{offset}.ZZZZZZZZZ"
|
66
|
+
total_entries = database.view(all_documents(key: key, reduce: true))
|
67
|
+
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
68
|
+
database.view(all_documents(options.merge(key: key, reduce: false, include_docs: true)))
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.all(options = {})
|
73
|
+
total_entries = database.view(all_documents(reduce: true))
|
74
|
+
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
75
|
+
database.view(all_documents(options.merge(reduce: false, include_docs: true)))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.find_by_translation_key(key)
|
80
|
+
begin
|
81
|
+
find("t::#{key}")
|
82
|
+
rescue SimplyStored::RecordNotFound
|
83
|
+
CouchI18n.handle_missing_key(key)
|
84
|
+
nil
|
85
|
+
end
|
53
86
|
end
|
54
87
|
|
55
88
|
# Find all records having the term part in their key
|
@@ -60,9 +93,9 @@ module CouchI18n
|
|
60
93
|
# find_all_by_part('action')
|
61
94
|
# will return the first two since they have action as key part
|
62
95
|
def self.find_all_by_key_part(part, options = {})
|
63
|
-
total_entries = database.view(
|
96
|
+
total_entries = database.view(by_translation_key_part(key: part, reduce: true))
|
64
97
|
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
65
|
-
database.view(
|
98
|
+
database.view(by_translation_key_part(options.merge(key: part, reduce: false, include_docs: true)))
|
66
99
|
end
|
67
100
|
end
|
68
101
|
|
@@ -74,9 +107,9 @@ module CouchI18n
|
|
74
107
|
# find_all_by_part('action')
|
75
108
|
# will return the first two since they have action as key part
|
76
109
|
def self.find_all_untranslated_by_key_part(part, options = {})
|
77
|
-
total_entries = database.view(
|
110
|
+
total_entries = database.view(untranslated_by_translation_key_part(key: part, reduce: true))
|
78
111
|
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
79
|
-
database.view(
|
112
|
+
database.view(untranslated_by_translation_key_part(options.merge(key: part, reduce: false, include_docs: true)))
|
80
113
|
end
|
81
114
|
end
|
82
115
|
|
@@ -88,9 +121,23 @@ module CouchI18n
|
|
88
121
|
# find_all_untranslated_by_value('Value')
|
89
122
|
# will return en.action.two
|
90
123
|
def self.find_all_untranslated_by_value(part, options = {})
|
91
|
-
total_entries = database.view(
|
124
|
+
total_entries = database.view(untranslated_by_translation_value(key: part, reduce: true))
|
92
125
|
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
93
|
-
database.view(
|
126
|
+
database.view(untranslated_by_translation_value(options.merge(key: part, reduce: false, include_docs: true)))
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Find all untranslated records having the term part as value
|
131
|
+
# nl.action.one: 'Value', translated: true
|
132
|
+
# en.action.two: 'Value', translated: false
|
133
|
+
# en.activemodel.plural.models.user: 'Other Value', translated: false
|
134
|
+
# and using
|
135
|
+
# find_all_untranslated_by_value('Value')
|
136
|
+
# will return en.action.two
|
137
|
+
def self.find_all_by_value(part, options = {})
|
138
|
+
total_entries = database.view(by_translation_value(key: part, reduce: true))
|
139
|
+
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
140
|
+
database.view(by_translation_value(options.merge(key: part, reduce: false, include_docs: true)))
|
94
141
|
end
|
95
142
|
end
|
96
143
|
|
@@ -98,7 +145,7 @@ module CouchI18n
|
|
98
145
|
def self.untranslated(options = {})
|
99
146
|
total_entries = database.view(untranslated_view(options.slice(:key, :keys, :startkey, :endkey).merge(reduce: true)))
|
100
147
|
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
101
|
-
database.view(untranslated_view(options))
|
148
|
+
database.view(untranslated_view(options.merge(reduce: false, include_docs: true)))
|
102
149
|
end
|
103
150
|
end
|
104
151
|
|
@@ -106,11 +153,10 @@ module CouchI18n
|
|
106
153
|
CouchI18n::Translation.untranslated(options.merge(key: "#{offset}.".."#{offset}.ZZZZZZZZZ"))
|
107
154
|
end
|
108
155
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
#I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store.respond_to?(:clear)
|
156
|
+
def self.get_keys_by_level(level = 0, options = {})
|
157
|
+
data = database.view(with_key_array(options.merge(group_level: level.succ)))["rows"]
|
158
|
+
# data = data.select{|h| h["key"].size > level } # Only select ones that have a deeper nesting
|
159
|
+
data.map{|h| h['key'][level].try(:to_sym)}.compact
|
114
160
|
end
|
115
161
|
|
116
162
|
def self.deeper_keys_for_offset( offset )
|
@@ -0,0 +1,15 @@
|
|
1
|
+
= form_for @translation, html: {class: 'form-horizontal'} do |f|
|
2
|
+
= hidden_field_tag 'offset', params[:offset]
|
3
|
+
= render 'error_messages', :target => @translation
|
4
|
+
.form-row
|
5
|
+
.form-label= f.label :translation_key, class: 'control-label'
|
6
|
+
.form-field.full= f.text_field :translation_key, :size => 70, class: 'input-xxlarge'
|
7
|
+
.form-row
|
8
|
+
.form-label= f.label :translation_value, class: 'control-label'
|
9
|
+
.form-field.full= f.text_field :translation_value, :size => 70, class: 'input-xxlarge'
|
10
|
+
.form-row
|
11
|
+
.form-label= label_tag :is_json, t('couch_i18n.general.is_json'), class: 'control-label'
|
12
|
+
.form-field= check_box_tag :is_json, 1, f.object.translation_value.to_s =~ /^\{|^\[/
|
13
|
+
.form-row: .form-actions
|
14
|
+
= link_to link_to_index_content(:translations), couch_i18n.translations_path(:offset => params[:offset] || @translation.key.to_s.sub(/\.[\w\s-]+$/, '')), class: 'secondary button'
|
15
|
+
= f.submit local_assigns[:submit] || update_button_text, class: 'button'
|
@@ -0,0 +1,91 @@
|
|
1
|
+
- if params[:offset].present?
|
2
|
+
- title params[:offset]
|
3
|
+
- else
|
4
|
+
- title t("couch_i18n.action.index.title")
|
5
|
+
.row.top-buttons: .small-12.columns
|
6
|
+
a.import-button data-reveal-id="import-modal" href="#" = t('couch_i18n.import.label')
|
7
|
+
a.export-button data-reveal-id="export-modal" href="#" = t('couch_i18n.export.label')
|
8
|
+
= link_to t('couch_i18n.action.destroy.offset_link'), couch_i18n.destroy_offset_translations_path(offset: params[:offset]), method: :delete, data: {confirm: (defined?(:are_you_sure) ? are_you_sure : t('couch_i18n.general.are_you_sure'))}, class: 'delete-all-from-offset-button'
|
9
|
+
|
10
|
+
#import-modal.reveal-modal data-reveal=true
|
11
|
+
a.close-reveal-modal ×
|
12
|
+
= form_tag({action: :import}, multipart: true) do
|
13
|
+
.modal-header
|
14
|
+
h3= t('couch_i18n.import.label')
|
15
|
+
.modal-body
|
16
|
+
p= t('couch_i18n.import.description')
|
17
|
+
= file_field_tag :importfile
|
18
|
+
.modal-footer
|
19
|
+
= submit_tag I18n.t('couch_i18n.import.button'), class: 'warning button'
|
20
|
+
#export-modal.reveal-modal data-reveal=true
|
21
|
+
a.close-reveal-modal ×
|
22
|
+
= form_tag action: :export do
|
23
|
+
= hidden_field_tag :offset, params[:offset]
|
24
|
+
.modal-header
|
25
|
+
- if params[:offset].present?
|
26
|
+
h3= t('couch_i18n.export.from_offset', offset: params[:offset])
|
27
|
+
- else
|
28
|
+
h3= t('couch_i18n.export.label')
|
29
|
+
.row.modal-body
|
30
|
+
.small-6.columns= select_tag :exportformat, options_for_select(%w[yml csv json], params[:exportformat])
|
31
|
+
.small-6.columns
|
32
|
+
= check_box_tag :untranslated
|
33
|
+
= label_tag :untranslated, t('couch_i18n.export.untranslated'), class: 'untranslated-label'
|
34
|
+
.modal-footer
|
35
|
+
= submit_tag I18n.t('couch_i18n.export.execute'), class: 'success button'
|
36
|
+
.offset-navigation-block.block
|
37
|
+
.row
|
38
|
+
.small-12.columns
|
39
|
+
ul.button-group
|
40
|
+
- for offset in @available_higher_offsets
|
41
|
+
li= link_to offset[:name], {offset: offset[:offset], untranslated: params[:untranslated]}, class: 'secondary tiny button'
|
42
|
+
= form_tag({}, method: :get )do
|
43
|
+
.row
|
44
|
+
.small-5.columns
|
45
|
+
.row.collapse
|
46
|
+
.small-2.columns
|
47
|
+
- if params[:offset].present?
|
48
|
+
= link_to 'x' || I18n.t('couch_i18n.general.go_to_zero_offset'), {offset: nil}, class: 'prefix button'
|
49
|
+
.small-10.columns= text_field_tag :offset, params[:offset], size: 60
|
50
|
+
.small-4.columns
|
51
|
+
ul.button-group
|
52
|
+
li: input.tiny.button type="submit" name="commit" value=I18n.t('couch_i18n.general.go_to_offset')
|
53
|
+
li: input.tiny.button type="submit" name="partfinder" value=I18n.t('couch_i18n.general.find_part')
|
54
|
+
li: input.tiny.button type="submit" name="valuefinder" value=I18n.t('couch_i18n.general.find_value')
|
55
|
+
.small-3.columns
|
56
|
+
= "(#{@translations.total_count})"
|
57
|
+
= check_box_tag :untranslated, 1, untranslated?, id: :untranslated_listing
|
58
|
+
= label_tag :untranslated_listing, I18n.t('couch_i18n.general.untranslated_label'), class: 'untranslated-label'
|
59
|
+
.row
|
60
|
+
.small-12.columns
|
61
|
+
ul.button-group
|
62
|
+
- for offset in @available_deeper_offsets
|
63
|
+
li= link_to offset[:name], {offset: offset[:offset], untranslated: params[:untranslated]}, class: 'secondary tiny button'
|
64
|
+
- if @translations.any?
|
65
|
+
.row: .small-12.columns= paginate @translations, right: 3, left: 3, theme: 'couch_i18n'
|
66
|
+
.row: .small-12.columns
|
67
|
+
table.table.table-striped
|
68
|
+
thead
|
69
|
+
tr
|
70
|
+
th= CouchI18n::Translation.human_attribute_name(:translation_key)
|
71
|
+
th= CouchI18n::Translation.human_attribute_name(:translation_value)
|
72
|
+
th= CouchI18n::Translation.human_attribute_name(:translated)
|
73
|
+
th.action.edit
|
74
|
+
th.action.destroy
|
75
|
+
tbody
|
76
|
+
- @translations.each do |translation|
|
77
|
+
tr class=cycle('odd', 'even')
|
78
|
+
td
|
79
|
+
- if partfinder? || valuefinder?
|
80
|
+
= link_to translation.translation_key.to_s.sub(/^\./, ''), couch_i18n.edit_translation_path(translation, offset: params[:offset])
|
81
|
+
- else
|
82
|
+
= link_to translation.translation_key.to_s[(params[:offset].try(:size) || 0)..-1].sub(/^\./, ''), couch_i18n.edit_translation_path(translation, offset: params[:offset])
|
83
|
+
td= link_to translation.translation_value, couch_i18n.edit_translation_path(translation, offset: params[:offset])
|
84
|
+
td.boolean= boolean_show(translation.translated)
|
85
|
+
td.action.edit= link_to link_to_edit_content(translation), couch_i18n.edit_translation_path(translation, offset: params[:offset]), class: 'tiny warning button'
|
86
|
+
td.action.destroy= link_to link_to_destroy_content(translation),couch_i18n.translation_path(translation, offset: params[:offset]), data: {confirm: are_you_sure}, method: :delete, class: 'destroy-translation-button'
|
87
|
+
- else
|
88
|
+
.row: .small-12.columns: h3= t("couch_i18n.general.none_found")
|
89
|
+
|
90
|
+
- content_for :page_links do
|
91
|
+
= link_to link_to_new_content(:translation), couch_i18n.new_translation_path(offset: params[:offset]), class: 'button'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= paginator.render do -%>
|
2
|
+
<div class="pagination-centered">
|
3
|
+
<ul class="pagination">
|
4
|
+
<%= first_page_tag unless current_page.first? %>
|
5
|
+
<%= prev_page_tag unless current_page.first? %>
|
6
|
+
<% each_page do |page| -%>
|
7
|
+
<% if page.left_outer? || page.right_outer? || page.inside_window? -%>
|
8
|
+
<%= page_tag page %>
|
9
|
+
<% elsif !page.was_truncated? -%>
|
10
|
+
<%= gap_tag %>
|
11
|
+
<% end -%>
|
12
|
+
<% end -%>
|
13
|
+
<%= next_page_tag unless current_page.last? %>
|
14
|
+
<%= last_page_tag unless current_page.last? %>
|
15
|
+
</ul>
|
16
|
+
</div>
|
17
|
+
<% end -%>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
= paginator.render do
|
2
|
+
.pagination-centered
|
3
|
+
ul.pagination
|
4
|
+
= first_page_tag unless current_page.first?
|
5
|
+
= prev_page_tag unless current_page.first?
|
6
|
+
- each_page do |page|
|
7
|
+
- if page.left_outer? || page.right_outer? || page.inside_window?
|
8
|
+
= page_tag page
|
9
|
+
- elsif !page.was_truncated?
|
10
|
+
= gap_tag
|
11
|
+
= next_page_tag unless current_page.last?
|
12
|
+
= last_page_tag unless current_page.last?
|
@@ -0,0 +1,28 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
title= defined?(site_title) ? site_title : I18n.t('couch_i18n.general.site_title')
|
5
|
+
/![if lt IE 9]
|
6
|
+
| <script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script
|
7
|
+
= csrf_meta_tags
|
8
|
+
= stylesheet_link_tag 'couch_i18n/application'
|
9
|
+
= javascript_include_tag 'couch_i18n/application'
|
10
|
+
meta name="viewport" content="width=device-width, initial-scale=1.0"
|
11
|
+
= yield :head
|
12
|
+
body
|
13
|
+
- if defined?(Cmtool)
|
14
|
+
= render 'cmtool/application/menu'
|
15
|
+
- else
|
16
|
+
nav.top-bar data-topbar="" role="navigation"
|
17
|
+
ul.title-area
|
18
|
+
li.name
|
19
|
+
h1
|
20
|
+
a href=couch_i18n.root_path = yield :title
|
21
|
+
li.toggle-topbar.menu-icon
|
22
|
+
a href="#"
|
23
|
+
span Menu
|
24
|
+
.container
|
25
|
+
= render 'alerts'
|
26
|
+
= yield
|
27
|
+
.row: .small-12.columns
|
28
|
+
.form-actions=yield :page_links
|
@@ -0,0 +1 @@
|
|
1
|
+
Rails.application.config.assets.precompile += %w[ couch_i18n/application.css couch_i18n/application.js ]
|
@@ -13,6 +13,7 @@ en:
|
|
13
13
|
label: Translations
|
14
14
|
title: Translations
|
15
15
|
new:
|
16
|
+
title: New translation
|
16
17
|
label: New
|
17
18
|
update:
|
18
19
|
button_text: Update
|
@@ -31,6 +32,7 @@ en:
|
|
31
32
|
boolean_true: 'yes'
|
32
33
|
go_to_offset: Go to offset
|
33
34
|
go_to_zero_offset: x
|
35
|
+
offset_deleted_notice: There were %{count} translations deleted having key offset %{offset}
|
34
36
|
find_part: Find key part
|
35
37
|
find_value: Find value
|
36
38
|
none_found: No translations found
|
@@ -42,6 +44,10 @@ en:
|
|
42
44
|
button: Import
|
43
45
|
label: Import
|
44
46
|
description: If you import keys, existing keys will be overwritten
|
47
|
+
notice: File imported
|
48
|
+
extension_not_valid: Please use the YAML file format for uploads
|
49
|
+
cannot_parse: The uploaded file cannot be parsed as valid translations
|
50
|
+
no_file_given: Please supply a file for upload
|
45
51
|
activemodel:
|
46
52
|
models:
|
47
53
|
couch_i18n:
|
@@ -52,6 +58,6 @@ en:
|
|
52
58
|
attributes:
|
53
59
|
couch_i18n:
|
54
60
|
translation:
|
55
|
-
|
56
|
-
|
61
|
+
translation_key: Key
|
62
|
+
translation_value: Value
|
57
63
|
translated: 'Translated?'
|
data/config/routes.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
CouchI18n::Engine.routes.draw do
|
2
2
|
root :to => "translations#index"
|
3
|
-
|
3
|
+
# allow escaped forms (%+) and unescaped forms (: ) (note the space!!) as id
|
4
|
+
resources :translations, constraints: {id: /[\w:% \.\+]+/} do
|
4
5
|
collection do
|
5
6
|
post :export
|
6
7
|
post :import
|