couch_i18n 0.2.0 → 0.2.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.
- data/app/assets/javascripts/couch_i18n/application.js +2 -1
- data/app/assets/javascripts/couch_i18n/structure.js +1 -0
- data/app/assets/stylesheets/couch_i18n/application.css +2 -2
- data/app/assets/stylesheets/couch_i18n/bootstrap_and_override.css.less +5 -0
- data/app/assets/stylesheets/couch_i18n/structure.css.scss +15 -10
- data/app/controllers/couch_i18n/application_controller.rb +3 -1
- data/app/models/couch_i18n/translation.rb +4 -4
- data/app/models/couch_i18n/translation.rb~ +77 -0
- data/app/views/couch_i18n/translations/_form.html.haml +14 -11
- data/app/views/couch_i18n/translations/edit.html.haml +1 -1
- data/app/views/couch_i18n/translations/index.html.haml +39 -23
- data/app/views/layouts/couch_i18n/application.html.haml +21 -2
- data/config/locales/couch_i18n.en.yml +10 -3
- metadata +4 -2
@@ -3,5 +3,5 @@
|
|
3
3
|
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
|
4
4
|
* the top of the compiled file, but it's generally better to create a new file per style scope.
|
5
5
|
*= require_self
|
6
|
-
*=
|
7
|
-
*/
|
6
|
+
*= require_directory .
|
7
|
+
*/
|
@@ -1,16 +1,13 @@
|
|
1
1
|
html, body{
|
2
|
-
margin: 0;
|
3
|
-
padding: 0;
|
4
2
|
}
|
5
3
|
body{
|
6
|
-
background-color: #ddf;
|
7
4
|
}
|
8
5
|
h1, h2, h3, h4, h5, h6{
|
9
|
-
margin: 0;
|
10
|
-
padding: 0;
|
11
6
|
}
|
12
7
|
h1{
|
13
|
-
|
8
|
+
}
|
9
|
+
form{
|
10
|
+
margin-bottom: 0; /* bootstrap fix */
|
14
11
|
}
|
15
12
|
#page-wrapper{
|
16
13
|
width: 922px;
|
@@ -34,9 +31,6 @@ h1{
|
|
34
31
|
}
|
35
32
|
}
|
36
33
|
}
|
37
|
-
tr.even{
|
38
|
-
background-color: #ddf;
|
39
|
-
}
|
40
34
|
#page-links{
|
41
35
|
margin-top: 8px;
|
42
36
|
margin-bottom: 8px;
|
@@ -49,7 +43,9 @@ tr.even{
|
|
49
43
|
}
|
50
44
|
}
|
51
45
|
}
|
52
|
-
|
46
|
+
.untranslated-label{
|
47
|
+
display: inline;
|
48
|
+
}
|
53
49
|
.offset-navigation-block{
|
54
50
|
border-style: double;
|
55
51
|
border-color: #444;
|
@@ -77,3 +73,12 @@ tr.even{
|
|
77
73
|
.clearing{
|
78
74
|
clear: both;
|
79
75
|
}
|
76
|
+
|
77
|
+
.pagination{
|
78
|
+
ul{
|
79
|
+
list-style: none;
|
80
|
+
li{
|
81
|
+
float: left;
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
@@ -6,7 +6,9 @@ module CouchI18n
|
|
6
6
|
private
|
7
7
|
|
8
8
|
def authorize_user
|
9
|
-
if respond_to?(:
|
9
|
+
if respond_to?(:authorize_couch_i18n)
|
10
|
+
authorize_couch_i18n
|
11
|
+
elsif respond_to?(:current_user) && current_user.present? && current_user.respond_to?(:is_admin) && !current_user.is_admin.present?
|
10
12
|
redirect_to '/', :alert => I18n.t('couch_i18n.general.not_authorized')
|
11
13
|
end
|
12
14
|
end
|
@@ -18,7 +18,7 @@ module CouchI18n
|
|
18
18
|
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation') {
|
19
19
|
emit(doc.key.split('.').slice(0, -1), 1);
|
20
20
|
}
|
21
|
-
}|, type: :raw, reduce_function:
|
21
|
+
}|, type: :raw, reduce_function: '_sum'
|
22
22
|
|
23
23
|
view :untranslated_view, key: :key, conditions: "!doc['translated']"
|
24
24
|
view :by_value, key: :value
|
@@ -69,9 +69,9 @@ module CouchI18n
|
|
69
69
|
|
70
70
|
# Expire I18n when record is update
|
71
71
|
def reload_i18n
|
72
|
-
Rails.cache.write(key, value)
|
73
|
-
I18n.reload!
|
74
|
-
I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store.respond_to?(:clear)
|
72
|
+
Rails.cache.write("couch_i18n-#{key}", value)
|
73
|
+
#I18n.reload!
|
74
|
+
#I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store.respond_to?(:clear)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module CouchI18n
|
2
|
+
class Translation
|
3
|
+
include SimplyStored::Couch
|
4
|
+
per_page_method :limit_value
|
5
|
+
|
6
|
+
property :key
|
7
|
+
property :value
|
8
|
+
property :translated, type: :boolean, default: true
|
9
|
+
|
10
|
+
validates_uniqueness_of :key
|
11
|
+
|
12
|
+
after_save :reload_i18n
|
13
|
+
|
14
|
+
view :all_documents, :key => :key
|
15
|
+
view :by_key, :key => :key
|
16
|
+
|
17
|
+
view :with_key_array, map_function: %|function(doc){
|
18
|
+
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation') {
|
19
|
+
emit(doc.key.split('.').slice(0, -1), 1);
|
20
|
+
}
|
21
|
+
}|, type: :raw, reduce_function: '_sum'
|
22
|
+
|
23
|
+
view :untranslated_view, key: :key, conditions: "!doc['translated']"
|
24
|
+
view :by_value, key: :value
|
25
|
+
view :by_key_part, type: :custom, map_function: %|function(doc){
|
26
|
+
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation') {
|
27
|
+
var parts = doc.key.split('.');
|
28
|
+
for(var i = 0; i < parts.length; i++){
|
29
|
+
emit(parts[i], 1);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}|, reduce_function: '_count'
|
33
|
+
|
34
|
+
def self.get_keys_by_level(level = 0, options = {})
|
35
|
+
data = database.view(with_key_array(options.merge(:group_level => level.succ)))["rows"]
|
36
|
+
# data = data.select{|h| h["key"].size > level } # Only select ones that have a deeper nesting
|
37
|
+
data.map{|h| h['key'][level].try(:to_sym)}.compact
|
38
|
+
end
|
39
|
+
|
40
|
+
# Shorthand for selecting all stored with a given offset
|
41
|
+
def self.with_offset(offset, options = {})
|
42
|
+
CouchI18n::Translation.find_all_by_key("#{offset}.".."#{offset}.ZZZZZZZZZ", options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Find all records having the term part in their key
|
46
|
+
# nl.action.one
|
47
|
+
# en.action.two
|
48
|
+
# en.activemodel.plural.models.user
|
49
|
+
# and using
|
50
|
+
# find_all_by_part('action')
|
51
|
+
# will return the first two since they have action as key part
|
52
|
+
def self.find_all_by_key_part(part, options = {})
|
53
|
+
total_entries = database.view(by_key_part(key: part, reduce: true))
|
54
|
+
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
55
|
+
database.view(by_key_part(options.merge(key: part, reduce: false, include_docs: true)))
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.untranslated(options = {})
|
60
|
+
total_entries = database.view(untranslated_view(options.select{|k,v| [:key, :keys, :startkey, :endkey].include?(k)}.merge(reduce: true)))
|
61
|
+
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
62
|
+
database.view(untranslated_view(options))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.untranslated_with_offset(offset, options = {})
|
67
|
+
CouchI18n::Translation.untranslated(options.merge(key: "#{offset}.".."#{offset}.ZZZZZZZZZ"))
|
68
|
+
end
|
69
|
+
|
70
|
+
# Expire I18n when record is update
|
71
|
+
def reload_i18n
|
72
|
+
Rails.cache.write(key, value)
|
73
|
+
I18n.reload!
|
74
|
+
I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store.respond_to?(:clear)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,13 +1,16 @@
|
|
1
|
-
= form_for @translation do |f|
|
1
|
+
= form_for @translation, html: {class: 'form-horizontal'} do |f|
|
2
2
|
= render 'error_messages', :target => @translation
|
3
|
-
.
|
4
|
-
= f.label :key
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
= f.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
.control-group
|
4
|
+
= f.label :key, class: 'control-label'
|
5
|
+
.controls
|
6
|
+
= f.text_field :key, :size => 70, class: 'input-xxlarge'
|
7
|
+
.control-group
|
8
|
+
= f.label :value, class: 'control-label'
|
9
|
+
.controls
|
10
|
+
= f.text_field :value, :size => 70, class: 'input-xxlarge'
|
11
|
+
.control-group
|
12
|
+
= label_tag :is_json, t('couch_i18n.general.is_json'), class: 'control-label'
|
13
|
+
.controls
|
14
|
+
= check_box_tag :is_json, 1, f.object.value.to_s =~ /^\{|^\[/
|
15
|
+
.form-actions
|
13
16
|
= f.submit @submit || update_button_text
|
@@ -1,4 +1,4 @@
|
|
1
|
-
- title t("couch_i18n.action
|
1
|
+
- title t("couch_i18n.action.edit.title")
|
2
2
|
= render 'form'
|
3
3
|
- content_for :page_links do
|
4
4
|
= link_to link_to_index_content(:translations), couch_i18n.translations_path(:offset => params[:offset] || @translation.key.to_s.sub(/\.[\w\s-]+$/, ''))
|
@@ -2,26 +2,42 @@
|
|
2
2
|
- title params[:offset]
|
3
3
|
- else
|
4
4
|
- title t("couch_i18n.action.index.title")
|
5
|
-
|
6
|
-
|
7
|
-
.
|
5
|
+
- content_for :navbar do
|
6
|
+
%a.btn.btn-warning{data: {toggle: "modal"}, href: ".import-form"}= t('couch_i18n.import.label')
|
7
|
+
%a.btn.btn-success{data: {toggle: "modal"}, href: ".export-form"}= t('couch_i18n.export.label')
|
8
|
+
.pull-right
|
9
|
+
= link_to t('couch_i18n.action.destroy.offset_link'), couch_i18n.destroy_offset_translations_path(:offset => params[:offset]), :method => :delete, :confirm => (defined?(:are_you_sure) ? are_you_sure : t('couch_i18n.general.are_you_sure')), class: [:btn, 'btn-danger']
|
10
|
+
|
11
|
+
.modal.hide.import-form
|
8
12
|
= form_tag({:action => :import}, :multipart => true) do
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
.
|
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
|
+
%a.btn{data: {dismiss: :modal}, href: '#'}= t('couch_i18n.general.close')
|
20
|
+
= submit_tag I18n.t('couch_i18n.import.button')
|
21
|
+
.modal.hide.export-form
|
13
22
|
= form_tag :action => :export do
|
14
23
|
= hidden_field_tag :offset, params[:offset]
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
+
.modal-body
|
30
|
+
= select_tag :exportformat, options_for_select(%w[yml csv json], params[:exportformat])
|
31
|
+
= check_box_tag :untranslated
|
32
|
+
= label_tag :untranslated, t('couch_i18n.export.untranslated'), class: 'untranslated-label'
|
33
|
+
.modal-footer
|
34
|
+
%a.btn{data: {dismiss: :modal}, href: '#'}= t('couch_i18n.general.close')
|
35
|
+
= submit_tag I18n.t('couch_i18n.export.execute')
|
20
36
|
.offset-navigation-block.block
|
21
|
-
.
|
37
|
+
.btn-toolbar
|
22
38
|
- for offset in @available_higher_offsets
|
23
|
-
|
24
|
-
|
39
|
+
.btn-group
|
40
|
+
= link_to offset[:name], {:offset => offset[:offset], untranslated: params[:untranslated]}, class: :btn
|
25
41
|
.offset-navigation-form
|
26
42
|
= form_tag({}, :method => :get )do
|
27
43
|
- if params[:offset].present?
|
@@ -31,15 +47,15 @@
|
|
31
47
|
%input{:type => :submit, :name => :commit, :value => I18n.t('couch_i18n.general.go_to_offset')}
|
32
48
|
%input{:type => :submit, :name => :partfinder, :value => I18n.t('couch_i18n.general.find_part')}
|
33
49
|
%input{:type => :submit, :name => :valuefinder, :value => I18n.t('couch_i18n.general.find_value')}
|
34
|
-
= check_box_tag :untranslated, 1, untranslated
|
35
|
-
= label_tag :
|
36
|
-
.
|
50
|
+
= check_box_tag :untranslated, 1, untranslated?, id: :untranslated_listing
|
51
|
+
= label_tag :untranslated_listing, I18n.t('couch_i18n.general.untranslated_label'), class: 'untranslated-label'
|
52
|
+
.btn-toolbar
|
37
53
|
- for offset in @available_deeper_offsets
|
38
|
-
|
39
|
-
|
54
|
+
.btn-group
|
55
|
+
= link_to(offset[:name], {:offset => offset[:offset], untranslated: params[:untranslated]}, class: :btn)
|
40
56
|
- if @translations.any?
|
41
57
|
= paginate @translations, :right => 3, :left => 3
|
42
|
-
%table.
|
58
|
+
%table.table.table-striped
|
43
59
|
%thead
|
44
60
|
%tr
|
45
61
|
%th= CouchI18n::Translation.human_attribute_name(:key)
|
@@ -57,8 +73,8 @@
|
|
57
73
|
= link_to translation.key[(params[:offset].try(:size) || 0)..-1].sub(/^\./, ''), couch_i18n.edit_translation_path(translation)
|
58
74
|
%td= link_to translation.value, couch_i18n.edit_translation_path(translation)
|
59
75
|
%td.boolean= boolean_show(translation.translated)
|
60
|
-
%td.action.edit= link_to link_to_edit_content(translation), couch_i18n.edit_translation_path(translation)
|
61
|
-
%td.action.destroy= link_to link_to_destroy_content(translation),couch_i18n.translation_path(translation), :confirm => are_you_sure, :method => :delete
|
76
|
+
%td.action.edit= link_to link_to_edit_content(translation), couch_i18n.edit_translation_path(translation), class: [:btn]
|
77
|
+
%td.action.destroy= link_to link_to_destroy_content(translation),couch_i18n.translation_path(translation), :confirm => are_you_sure, :method => :delete, class: [:btn, 'btn-danger']
|
62
78
|
- else
|
63
79
|
%h3= t("couch_i18n.general.none_found")
|
64
80
|
|
@@ -2,12 +2,31 @@
|
|
2
2
|
%html
|
3
3
|
%head
|
4
4
|
%title= defined?(site_title) ? site_title : I18n.t('couch_i18n.general.site_title')
|
5
|
-
|
5
|
+
/[if lt IE 9]
|
6
|
+
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
|
7
|
+
= csrf_meta_tags
|
6
8
|
= stylesheet_link_tag 'couch_i18n/application'
|
7
9
|
= javascript_include_tag 'couch_i18n/application'
|
10
|
+
%meta{:name => "viewport", :content => "width=device-width, initial-scale=1.0"}
|
8
11
|
= yield :head
|
9
12
|
%body
|
10
|
-
|
13
|
+
.navbar.navbar-fixed-top
|
14
|
+
.navbar-inner
|
15
|
+
.container
|
16
|
+
%a.btn.btn-navbar{data: {toggle: "collapse", target: ".nav-collapse"}}
|
17
|
+
%span.icon-bar
|
18
|
+
%span.icon-bar
|
19
|
+
%span.icon-bar
|
20
|
+
%a.brand{href: couch_i18n.root_path}= yield :title
|
21
|
+
-#.nav-collapse
|
22
|
+
%ul.nav
|
23
|
+
%li= link_to 'Clear', couch_i18n.root_path
|
24
|
+
= yield :navbar
|
25
|
+
.container
|
26
|
+
= render 'alerts'
|
27
|
+
= yield
|
28
|
+
|
29
|
+
-#page-wrapper
|
11
30
|
#page-header
|
12
31
|
%h1= yield :title
|
13
32
|
#page-content
|
@@ -4,11 +4,11 @@ en:
|
|
4
4
|
action:
|
5
5
|
edit:
|
6
6
|
title: Edit translation
|
7
|
+
label: Edit
|
7
8
|
destroy:
|
8
9
|
label: Delete
|
9
10
|
offset_link: Delete all from offset
|
10
|
-
|
11
|
-
label: Edit
|
11
|
+
successful: '%{model} is successfully removed'
|
12
12
|
index:
|
13
13
|
label: Translations
|
14
14
|
title: Translations
|
@@ -16,10 +16,14 @@ en:
|
|
16
16
|
label: New
|
17
17
|
update:
|
18
18
|
button_text: Update
|
19
|
+
successful: '%{model} is successfully updated'
|
20
|
+
create:
|
21
|
+
successful: '%{model} is successfully created'
|
19
22
|
export:
|
20
23
|
execute: Execute
|
21
24
|
untranslated: Untranslated
|
22
25
|
label: Export
|
26
|
+
from_offset: 'Export from offset: "%{offset}"'
|
23
27
|
general:
|
24
28
|
are_you_sure: 'Are you sure?'
|
25
29
|
boolean_false: 'no'
|
@@ -30,10 +34,13 @@ en:
|
|
30
34
|
find_value: Find value
|
31
35
|
none_found: No translations found
|
32
36
|
site_title: CouchI18n translations
|
33
|
-
|
37
|
+
untranslated_label: Untranslated
|
38
|
+
close: Close
|
39
|
+
is_json: 'Is JSON?'
|
34
40
|
import:
|
35
41
|
button: Import
|
36
42
|
label: Import
|
43
|
+
description: If you import keys, existing keys will be overwritten
|
37
44
|
activemodel:
|
38
45
|
models:
|
39
46
|
couch_i18n:
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: couch_i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -62,11 +62,13 @@ files:
|
|
62
62
|
- app/assets/javascripts/couch_i18n/structure.js
|
63
63
|
- app/assets/stylesheets/couch_i18n/alerts.css.scss
|
64
64
|
- app/assets/stylesheets/couch_i18n/application.css
|
65
|
+
- app/assets/stylesheets/couch_i18n/bootstrap_and_override.css.less
|
65
66
|
- app/assets/stylesheets/couch_i18n/structure.css.scss
|
66
67
|
- app/controllers/couch_i18n/application_controller.rb
|
67
68
|
- app/controllers/couch_i18n/translations_controller.rb
|
68
69
|
- app/helpers/couch_i18n/application_helper.rb
|
69
70
|
- app/models/couch_i18n/translation.rb
|
71
|
+
- app/models/couch_i18n/translation.rb~
|
70
72
|
- app/views/couch_i18n/application/_alerts.html.haml
|
71
73
|
- app/views/couch_i18n/application/_error_messages.html.haml
|
72
74
|
- app/views/couch_i18n/translations/_form.html.haml
|