couch_i18n 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -1
- data/app/assets/javascripts/couch_i18n/application.js +1 -1
- data/app/assets/stylesheets/couch_i18n/bootstrap_and_override.css.sass +6 -0
- data/app/controllers/couch_i18n/application_controller.rb +11 -3
- data/app/controllers/couch_i18n/translations_controller.rb +13 -14
- data/app/models/couch_i18n/translation.rb +62 -1
- data/app/views/couch_i18n/translations/_form.html.haml +2 -1
- data/app/views/couch_i18n/translations/edit.html.haml +1 -1
- data/app/views/couch_i18n/translations/index.html.haml +13 -11
- data/app/views/couch_i18n/translations/new.html.haml +2 -2
- data/app/views/couch_i18n/translations/new.html.haml~ +4 -0
- data/app/views/layouts/couch_i18n/application.html.haml +12 -20
- data/config/locales/couch_i18n.en.yml +1 -0
- data/lib/couch_i18n/engine.rb +10 -0
- metadata +4 -3
- data/app/assets/stylesheets/couch_i18n/bootstrap_and_override.css.less +0 -5
data/README.rdoc
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
= CouchI18n
|
2
|
-
|
2
|
+
{<img src="https://travis-ci.org/bterkuile/couch_i18n.png?branch=master" alt="Build Status" />}[https://travis-ci.org/bterkuile/couch_i18n]
|
3
3
|
<b>Note this is a Rails >= 3.1 engine</b>
|
4
4
|
|
5
5
|
This projects is created to make translations editable. It is created using
|
@@ -1,14 +1,22 @@
|
|
1
1
|
module CouchI18n
|
2
|
-
class ApplicationController <
|
2
|
+
class ApplicationController < ::ApplicationController
|
3
3
|
before_filter :authorize_user
|
4
|
-
layout
|
4
|
+
layout :couch_i18n_layout
|
5
5
|
|
6
6
|
private
|
7
7
|
|
8
|
+
def couch_i18n_layout
|
9
|
+
defined?(Cmtool) ? 'cmtool/application' : 'couch_i18n/application'
|
10
|
+
# Does not integrate well with cmtool layout at the moment (2012-12-17)
|
11
|
+
'couch_i18n/application'
|
12
|
+
end
|
13
|
+
|
8
14
|
def authorize_user
|
9
15
|
if respond_to?(:authorize_couch_i18n)
|
10
16
|
authorize_couch_i18n
|
11
|
-
elsif
|
17
|
+
elsif defined?(Cmtool)
|
18
|
+
authorize_cmtool
|
19
|
+
elsif respond_to?(:current_user) && current_user.respond_to?(:is_admin) && !current_user.is_admin.present?
|
12
20
|
redirect_to '/', :alert => I18n.t('couch_i18n.general.not_authorized')
|
13
21
|
end
|
14
22
|
end
|
@@ -5,39 +5,38 @@ module CouchI18n
|
|
5
5
|
@available_deeper_offsets = []
|
6
6
|
per_page = params[:per_page].presence.try(:to_i) || 30
|
7
7
|
if params[:partfinder].present?
|
8
|
-
|
8
|
+
if untranslated?
|
9
|
+
@translations = CouchI18n::Translation.find_all_untranslated_by_key_part(params[:offset], page: params[:page], per_page: per_page)
|
10
|
+
else
|
11
|
+
@translations = CouchI18n::Translation.find_all_by_key_part(params[:offset], page: params[:page], per_page: per_page)
|
12
|
+
end
|
9
13
|
elsif params[:valuefinder].present?
|
10
|
-
|
14
|
+
if untranslated?
|
15
|
+
@translations = CouchI18n::Translation.find_all_untranslated_by_value(params[:offset], page: params[:page], per_page: per_page)
|
16
|
+
else
|
17
|
+
@translations = CouchI18n::Translation.find_all_by_value(params[:offset], page: params[:page], per_page: per_page)
|
18
|
+
end
|
11
19
|
else
|
12
20
|
if params[:offset].present?
|
13
|
-
@levels = params[:offset].split('.')
|
14
|
-
# Add higher levels. Do not add the last level, since it is the current one => 0..-2
|
15
|
-
@levels[0..-2].each_with_index do |level_name, i|
|
16
|
-
@available_higher_offsets << {
|
17
|
-
:name => level_name,
|
18
|
-
:offset => @levels[0..i].join('.')
|
19
|
-
}
|
20
|
-
end
|
21
21
|
if untranslated?
|
22
22
|
@translations = CouchI18n::Translation.untranslated_with_offset(params[:offset], :page => params[:page], :per_page => per_page)
|
23
23
|
else
|
24
24
|
@translations = CouchI18n::Translation.with_offset(params[:offset], :page => params[:page], :per_page => per_page)
|
25
25
|
end
|
26
|
-
@available_deeper_offsets = CouchI18n::Translation.get_keys_by_level(@levels.size, :startkey => @levels, :endkey => @levels + [{}]).
|
27
|
-
map{|dl| {:name => dl, :offset => [params[:offset], dl].join('.')}}
|
28
26
|
else
|
29
27
|
if untranslated?
|
30
28
|
@translations = CouchI18n::Translation.untranslated(:page => params[:page], :per_page => per_page)
|
31
29
|
else
|
32
30
|
@translations = CouchI18n::Translation.all(:page => params[:page], :per_page => per_page)
|
33
31
|
end
|
34
|
-
@available_deeper_offsets = CouchI18n::Translation.get_keys_by_level(0).map{|dl| {:name => dl, :offset => dl}}
|
35
32
|
end
|
33
|
+
@available_higher_offsets = CouchI18n::Translation.higher_keys_for_offset(params[:offset])
|
34
|
+
@available_deeper_offsets = CouchI18n::Translation.deeper_keys_for_offset(params[:offset])
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
38
|
def show
|
40
|
-
|
39
|
+
redirect_to action: :edit
|
41
40
|
end
|
42
41
|
|
43
42
|
def new
|
@@ -22,6 +22,7 @@ module CouchI18n
|
|
22
22
|
|
23
23
|
view :untranslated_view, key: :key, conditions: "!doc['translated']"
|
24
24
|
view :by_value, key: :value
|
25
|
+
view :untranslated_by_value, key: :value, conditions: "!doc['translated']"
|
25
26
|
view :by_key_part, type: :custom, map_function: %|function(doc){
|
26
27
|
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation') {
|
27
28
|
var parts = doc.key.split('.');
|
@@ -31,6 +32,15 @@ module CouchI18n
|
|
31
32
|
}
|
32
33
|
}|, reduce_function: '_count'
|
33
34
|
|
35
|
+
view :untranslated_by_key_part, type: :custom, map_function: %|function(doc){
|
36
|
+
if(doc.ruby_class && doc.ruby_class == 'CouchI18n::Translation' && !doc.translated) {
|
37
|
+
var parts = doc.key.split('.');
|
38
|
+
for(var i = 0; i < parts.length; i++){
|
39
|
+
emit(parts[i], 1);
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}|, reduce_function: '_count'
|
43
|
+
|
34
44
|
def self.get_keys_by_level(level = 0, options = {})
|
35
45
|
data = database.view(with_key_array(options.merge(:group_level => level.succ)))["rows"]
|
36
46
|
# data = data.select{|h| h["key"].size > level } # Only select ones that have a deeper nesting
|
@@ -56,8 +66,37 @@ module CouchI18n
|
|
56
66
|
end
|
57
67
|
end
|
58
68
|
|
69
|
+
# Find all untranslated records having the term part in their key
|
70
|
+
# nl.action.one
|
71
|
+
# en.action.two
|
72
|
+
# en.activemodel.plural.models.user
|
73
|
+
# and using
|
74
|
+
# find_all_by_part('action')
|
75
|
+
# will return the first two since they have action as key part
|
76
|
+
def self.find_all_untranslated_by_key_part(part, options = {})
|
77
|
+
total_entries = database.view(by_key_part(key: part, reduce: true))
|
78
|
+
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
79
|
+
database.view(untranslated_by_key_part(options.merge(key: part, reduce: false, include_docs: true)))
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Find all untranslated records having the term part as value
|
84
|
+
# nl.action.one: 'Value', translated: true
|
85
|
+
# en.action.two: 'Value', translated: false
|
86
|
+
# en.activemodel.plural.models.user: 'Other Value', translated: false
|
87
|
+
# and using
|
88
|
+
# find_all_untranslated_by_value('Value')
|
89
|
+
# will return en.action.two
|
90
|
+
def self.find_all_untranslated_by_value(part, options = {})
|
91
|
+
total_entries = database.view(untranslated_by_value(key: part, reduce: true))
|
92
|
+
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
93
|
+
database.view(untranslated_by_value(options.merge(key: part, reduce: false, include_docs: true)))
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
|
59
98
|
def self.untranslated(options = {})
|
60
|
-
total_entries = database.view(untranslated_view(options.
|
99
|
+
total_entries = database.view(untranslated_view(options.slice(:key, :keys, :startkey, :endkey).merge(reduce: true)))
|
61
100
|
with_pagination_options options.merge(total_entries: total_entries) do |options|
|
62
101
|
database.view(untranslated_view(options))
|
63
102
|
end
|
@@ -73,5 +112,27 @@ module CouchI18n
|
|
73
112
|
#I18n.reload!
|
74
113
|
#I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store.respond_to?(:clear)
|
75
114
|
end
|
115
|
+
|
116
|
+
def self.deeper_keys_for_offset( offset )
|
117
|
+
return get_keys_by_level(0).map{|dl| {:name => dl, :offset => dl}} unless offset.present?
|
118
|
+
levels = offset.split('.')
|
119
|
+
get_keys_by_level(levels.size, :startkey => levels, :endkey => levels + [{}]).
|
120
|
+
map{|dl| {:name => dl, :offset => [offset, dl].join('.')}}
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.higher_keys_for_offset( offset )
|
124
|
+
return [] unless offset.present?
|
125
|
+
higher_keys = []
|
126
|
+
levels = offset.split('.')
|
127
|
+
return [] unless levels.size > 1
|
128
|
+
# Add higher levels. Do not add the last level, since it is the current one => 0..-2
|
129
|
+
levels[0..-2].each_with_index do |level_name, i|
|
130
|
+
higher_keys<< {
|
131
|
+
:name => level_name,
|
132
|
+
:offset => levels[0..i].join('.')
|
133
|
+
}
|
134
|
+
end
|
135
|
+
higher_keys
|
136
|
+
end
|
76
137
|
end
|
77
138
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
= form_for @translation, html: {class: 'form-horizontal'} do |f|
|
2
|
+
= hidden_field_tag 'offset', params[:offset]
|
2
3
|
= render 'error_messages', :target => @translation
|
3
4
|
.control-group
|
4
5
|
= f.label :key, class: 'control-label'
|
@@ -13,4 +14,4 @@
|
|
13
14
|
.controls
|
14
15
|
= check_box_tag :is_json, 1, f.object.value.to_s =~ /^\{|^\[/
|
15
16
|
.form-actions
|
16
|
-
= f.submit
|
17
|
+
= f.submit local_assigns[:submit] || update_button_text
|
@@ -1,4 +1,4 @@
|
|
1
1
|
- title t("couch_i18n.action.edit.title")
|
2
2
|
= render 'form'
|
3
3
|
- content_for :page_links do
|
4
|
-
= link_to link_to_index_content(:translations), couch_i18n.translations_path(:offset => params[:offset] || @translation.key.to_s.sub(/\.[\w\s-]+$/, ''))
|
4
|
+
= link_to link_to_index_content(:translations), couch_i18n.translations_path(:offset => params[:offset] || @translation.key.to_s.sub(/\.[\w\s-]+$/, '')), class: 'btn'
|
@@ -2,15 +2,16 @@
|
|
2
2
|
- title params[:offset]
|
3
3
|
- else
|
4
4
|
- title t("couch_i18n.action.index.title")
|
5
|
-
-
|
6
|
-
%a.btn.btn-warning{data: {toggle: "modal"}, href: "
|
7
|
-
%a.btn.btn-success{data: {toggle: "modal"}, href: "
|
5
|
+
.top-buttons
|
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
8
|
.pull-right
|
9
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
10
|
|
11
|
-
.modal.hide
|
11
|
+
#import-form.modal.hide
|
12
12
|
= form_tag({:action => :import}, :multipart => true) do
|
13
13
|
.modal-header
|
14
|
+
%button.close{:type => "button", :data => {:dismiss => "modal"}, 'aria-hidden' => "true" } x
|
14
15
|
%h3= t('couch_i18n.import.label')
|
15
16
|
.modal-body
|
16
17
|
%p= t('couch_i18n.import.description')
|
@@ -18,10 +19,11 @@
|
|
18
19
|
.modal-footer
|
19
20
|
%a.btn{data: {dismiss: :modal}, href: '#'}= t('couch_i18n.general.close')
|
20
21
|
= submit_tag I18n.t('couch_i18n.import.button')
|
21
|
-
.modal.hide
|
22
|
+
#export-form.modal.hide
|
22
23
|
= form_tag :action => :export do
|
23
24
|
= hidden_field_tag :offset, params[:offset]
|
24
25
|
.modal-header
|
26
|
+
%button.close{:type => "button", :data => {:dismiss => "modal"}, 'aria-hidden' => "true" } x
|
25
27
|
- if params[:offset].present?
|
26
28
|
%h3= t('couch_i18n.export.from_offset', offset: params[:offset])
|
27
29
|
- else
|
@@ -68,15 +70,15 @@
|
|
68
70
|
%tr{:class => cycle('odd', 'even')}
|
69
71
|
%td
|
70
72
|
- if partfinder? || valuefinder?
|
71
|
-
= link_to translation.key.sub(/^\./, ''), couch_i18n.edit_translation_path(translation)
|
73
|
+
= link_to translation.key.sub(/^\./, ''), couch_i18n.edit_translation_path(translation, offset: params[:offset])
|
72
74
|
- else
|
73
|
-
= link_to translation.key[(params[:offset].try(:size) || 0)..-1].sub(/^\./, ''), couch_i18n.edit_translation_path(translation)
|
74
|
-
%td= link_to translation.value, couch_i18n.edit_translation_path(translation)
|
75
|
+
= link_to translation.key[(params[:offset].try(:size) || 0)..-1].sub(/^\./, ''), couch_i18n.edit_translation_path(translation, offset: params[:offset])
|
76
|
+
%td= link_to translation.value, couch_i18n.edit_translation_path(translation, offset: params[:offset])
|
75
77
|
%td.boolean= boolean_show(translation.translated)
|
76
|
-
%td.action.edit= link_to link_to_edit_content(translation), couch_i18n.edit_translation_path(translation), class:
|
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']
|
78
|
+
%td.action.edit= link_to link_to_edit_content(translation), couch_i18n.edit_translation_path(translation, offset: params[:offset]), class: 'btn btn-warning'
|
79
|
+
%td.action.destroy= link_to link_to_destroy_content(translation),couch_i18n.translation_path(translation, offset: params[:offset]), :confirm => are_you_sure, :method => :delete, class: [:btn, 'btn-danger']
|
78
80
|
- else
|
79
81
|
%h3= t("couch_i18n.general.none_found")
|
80
82
|
|
81
83
|
- content_for :page_links do
|
82
|
-
= link_to link_to_new_content(:translation), couch_i18n.new_translation_path(:offset => params[:offset])
|
84
|
+
= link_to link_to_new_content(:translation), couch_i18n.new_translation_path(:offset => params[:offset]), class: 'btn btn-primary'
|
@@ -1,4 +1,4 @@
|
|
1
1
|
- title t("couch_i18n.action.new.title")
|
2
|
-
= render 'form'
|
2
|
+
= render 'form', submit: create_button_text
|
3
3
|
- content_for :page_links do
|
4
|
-
= link_to link_to_index_content(:couch_i18n_translations), couch_i18n.translations_path(:offset => params[:offset])
|
4
|
+
= link_to link_to_index_content(:couch_i18n_translations), couch_i18n.translations_path(:offset => params[:offset]), class: 'btn'
|
@@ -10,26 +10,18 @@
|
|
10
10
|
%meta{:name => "viewport", :content => "width=device-width, initial-scale=1.0"}
|
11
11
|
= yield :head
|
12
12
|
%body
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
%
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
= yield :navbar
|
13
|
+
- if defined?(Cmtool)
|
14
|
+
= render 'cmtool/application/menu'
|
15
|
+
- else
|
16
|
+
.navbar.navbar-fixed-top
|
17
|
+
.navbar-inner
|
18
|
+
.container
|
19
|
+
%a.btn.btn-navbar{data: {toggle: "collapse", target: ".nav-collapse"}}
|
20
|
+
%span.icon-bar
|
21
|
+
%span.icon-bar
|
22
|
+
%span.icon-bar
|
23
|
+
%a.brand{href: couch_i18n.root_path}= yield :title
|
25
24
|
.container
|
26
25
|
= render 'alerts'
|
27
26
|
= yield
|
28
|
-
|
29
|
-
-#page-wrapper
|
30
|
-
#page-header
|
31
|
-
%h1= yield :title
|
32
|
-
#page-content
|
33
|
-
= render 'alerts'
|
34
|
-
= yield
|
35
|
-
#page-links= yield :page_links
|
27
|
+
.form-actions=yield :page_links
|
data/lib/couch_i18n/engine.rb
CHANGED
@@ -2,5 +2,15 @@ require 'i18n'
|
|
2
2
|
module CouchI18n
|
3
3
|
class Engine < ::Rails::Engine
|
4
4
|
isolate_namespace CouchI18n
|
5
|
+
initializer 'couch_i18n.cmtool', after: 'cmtool.build_menu' do
|
6
|
+
if defined? Cmtool
|
7
|
+
require 'cmtool'
|
8
|
+
Cmtool::Menu.register do
|
9
|
+
append_to :site do
|
10
|
+
resource_link CouchI18n::Translation, label: :couch_i18n
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
5
15
|
end
|
6
16
|
end
|
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.
|
4
|
+
version: 0.3.0
|
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-12-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|
@@ -62,7 +62,7 @@ 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.
|
65
|
+
- app/assets/stylesheets/couch_i18n/bootstrap_and_override.css.sass
|
66
66
|
- app/assets/stylesheets/couch_i18n/structure.css.scss
|
67
67
|
- app/controllers/couch_i18n/application_controller.rb
|
68
68
|
- app/controllers/couch_i18n/translations_controller.rb
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- app/views/couch_i18n/translations/edit.html.haml
|
76
76
|
- app/views/couch_i18n/translations/index.html.haml
|
77
77
|
- app/views/couch_i18n/translations/new.html.haml
|
78
|
+
- app/views/couch_i18n/translations/new.html.haml~
|
78
79
|
- app/views/layouts/couch_i18n/application.html.haml
|
79
80
|
- config/locales/couch_i18n.en.yml
|
80
81
|
- config/routes.rb
|