phrasing 3.2.1 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/Gemfile.lock +23 -26
- data/README.md +1 -0
- data/app/assets/javascripts/phrasing.js.erb +23 -31
- data/app/controllers/phrasing_phrases_controller.rb +4 -3
- data/app/helpers/inline_helper.rb +4 -4
- data/app/models/phrasing_phrase.rb +6 -6
- data/app/views/phrasing/_initializer.html.haml +5 -4
- data/lib/phrasing/implementation.rb +5 -4
- data/lib/phrasing/version.rb +1 -1
- data/lib/tasks/phrasing_tasks.rake +38 -39
- data/phrasing.gemspec +1 -0
- data/spec/dummy/app/assets/javascripts/application.js +1 -0
- data/spec/dummy/app/assets/stylesheets/application.css +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +3 -2
- data/spec/dummy/app/views/site/index.html.erb +8 -2
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20131120000856_create_phrasing_phrase_versions.phrasing_rails_engine.rb +1 -1
- data/spec/dummy/log/development.log +7380 -0
- data/spec/features/dummy_spec.rb +6 -2
- data/spec/features/phrasing_spec.rb +56 -2
- metadata +54 -22
- checksums.yaml +0 -7
- data/app/assets/javascripts/head.js +0 -423
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
phrasing (3.2.
|
4
|
+
phrasing (3.2.2)
|
5
5
|
haml-rails
|
6
6
|
jquery-cookie-rails
|
7
7
|
jquery-rails
|
@@ -39,15 +39,12 @@ GEM
|
|
39
39
|
arel (4.0.1)
|
40
40
|
atomic (1.1.13)
|
41
41
|
builder (3.1.4)
|
42
|
-
capybara (2.
|
42
|
+
capybara (2.2.1)
|
43
43
|
mime-types (>= 1.16)
|
44
44
|
nokogiri (>= 1.3.3)
|
45
45
|
rack (>= 1.0.0)
|
46
46
|
rack-test (>= 0.5.4)
|
47
|
-
|
48
|
-
xpath (~> 1.0.0)
|
49
|
-
childprocess (0.3.9)
|
50
|
-
ffi (~> 1.0, >= 1.0.11)
|
47
|
+
xpath (~> 2.0)
|
51
48
|
coderay (1.1.0)
|
52
49
|
columnize (0.3.6)
|
53
50
|
debugger (1.6.5)
|
@@ -56,15 +53,14 @@ GEM
|
|
56
53
|
debugger-ruby_core_source (~> 1.3.1)
|
57
54
|
debugger-linecache (1.2.0)
|
58
55
|
debugger-ruby_core_source (1.3.1)
|
59
|
-
diff-lcs (1.2.
|
56
|
+
diff-lcs (1.2.5)
|
60
57
|
erubis (2.7.0)
|
61
|
-
factory_girl (4.
|
58
|
+
factory_girl (4.3.0)
|
62
59
|
activesupport (>= 3.0.0)
|
63
|
-
factory_girl_rails (4.
|
64
|
-
factory_girl (~> 4.
|
60
|
+
factory_girl_rails (4.3.0)
|
61
|
+
factory_girl (~> 4.3.0)
|
65
62
|
railties (>= 3.0.0)
|
66
|
-
|
67
|
-
haml (4.0.3)
|
63
|
+
haml (4.0.4)
|
68
64
|
tilt
|
69
65
|
haml-rails (0.4)
|
70
66
|
actionpack (>= 3.1, < 4.1)
|
@@ -73,9 +69,15 @@ GEM
|
|
73
69
|
railties (>= 3.1, < 4.1)
|
74
70
|
hike (1.2.3)
|
75
71
|
i18n (0.6.5)
|
72
|
+
jasmine-core (1.3.1)
|
73
|
+
jasmine-rails (0.5.6)
|
74
|
+
jasmine-core (~> 1.3)
|
75
|
+
phantomjs
|
76
|
+
rails (>= 3.1.0)
|
77
|
+
sprockets-rails
|
76
78
|
jquery-cookie-rails (1.3.1.1)
|
77
79
|
railties (>= 3.2.0, < 5.0)
|
78
|
-
jquery-rails (3.0
|
80
|
+
jquery-rails (3.1.0)
|
79
81
|
railties (>= 3.0, < 5.0)
|
80
82
|
thor (>= 0.14, < 2.0)
|
81
83
|
mail (2.5.4)
|
@@ -88,6 +90,7 @@ GEM
|
|
88
90
|
multi_json (1.7.9)
|
89
91
|
nokogiri (1.6.0)
|
90
92
|
mini_portile (~> 0.5.0)
|
93
|
+
phantomjs (1.9.2.1)
|
91
94
|
polyglot (0.3.3)
|
92
95
|
pry (0.9.12.4)
|
93
96
|
coderay (~> 1.0)
|
@@ -113,10 +116,10 @@ GEM
|
|
113
116
|
rake (>= 0.8.7)
|
114
117
|
thor (>= 0.18.1, < 2.0)
|
115
118
|
rake (10.1.0)
|
116
|
-
rspec-core (2.14.
|
117
|
-
rspec-expectations (2.14.
|
119
|
+
rspec-core (2.14.7)
|
120
|
+
rspec-expectations (2.14.4)
|
118
121
|
diff-lcs (>= 1.1.3, < 2.0)
|
119
|
-
rspec-mocks (2.14.
|
122
|
+
rspec-mocks (2.14.4)
|
120
123
|
rspec-rails (2.14.0)
|
121
124
|
actionpack (>= 3.0)
|
122
125
|
activesupport (>= 3.0)
|
@@ -124,13 +127,7 @@ GEM
|
|
124
127
|
rspec-core (~> 2.14.0)
|
125
128
|
rspec-expectations (~> 2.14.0)
|
126
129
|
rspec-mocks (~> 2.14.0)
|
127
|
-
|
128
|
-
sass (3.2.13)
|
129
|
-
selenium-webdriver (2.35.0)
|
130
|
-
childprocess (>= 0.2.5)
|
131
|
-
multi_json (~> 1.0)
|
132
|
-
rubyzip
|
133
|
-
websocket (~> 1.0.4)
|
130
|
+
sass (3.2.14)
|
134
131
|
slop (3.4.7)
|
135
132
|
sprockets (2.10.1)
|
136
133
|
hike (~> 1.2)
|
@@ -150,17 +147,17 @@ GEM
|
|
150
147
|
polyglot
|
151
148
|
polyglot (>= 0.3.1)
|
152
149
|
tzinfo (0.3.37)
|
153
|
-
|
154
|
-
xpath (1.0.0)
|
150
|
+
xpath (2.0.0)
|
155
151
|
nokogiri (~> 1.3)
|
156
152
|
|
157
153
|
PLATFORMS
|
158
154
|
ruby
|
159
155
|
|
160
156
|
DEPENDENCIES
|
161
|
-
capybara (~> 2.
|
157
|
+
capybara (~> 2.2.0)
|
162
158
|
factory_girl_rails
|
163
159
|
haml-rails
|
160
|
+
jasmine-rails
|
164
161
|
phrasing!
|
165
162
|
pry-debugger
|
166
163
|
rspec-rails
|
data/README.md
CHANGED
@@ -115,6 +115,7 @@ url: custom_url # point Phrasing to other actions in other controllers
|
|
115
115
|
inverse: true # change the hovered background and underline colors to better fit darker backgrounds
|
116
116
|
class: custom_class # add custom CSS classes to your phrases to change the appearance of phrases in your application
|
117
117
|
interpolation: { %min: 10 } # add variables to your translations just like w/ I18n
|
118
|
+
scope: 'homepage.footer' # add scopes just like you would w/ I18.n. If the first argument is 'test', than the key would be 'homepage.footer.test'
|
118
119
|
```
|
119
120
|
|
120
121
|
## Credits
|
@@ -1,32 +1,27 @@
|
|
1
|
-
//= require
|
1
|
+
//= require editor
|
2
2
|
//= require jquery
|
3
3
|
//= require jquery_ujs
|
4
4
|
//= require jquery.cookie
|
5
5
|
|
6
6
|
var phrasing_setup = function(){
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
var size = 0, key;
|
23
|
-
for (key in obj) {
|
24
|
-
if (obj.hasOwnProperty(key)) size++;
|
25
|
-
}
|
26
|
-
return size;
|
8
|
+
// Initialize the editing bubble
|
9
|
+
editor.init();
|
10
|
+
|
11
|
+
// Making sure to send csrf token from layout file.
|
12
|
+
$(document).ajaxSend(function(e, xhr, options) {
|
13
|
+
var token = $("meta[name='csrf-token']").attr("content");
|
14
|
+
xhr.setRequestHeader("X-CSRF-Token", token);
|
15
|
+
});
|
16
|
+
|
17
|
+
// Hash size function
|
18
|
+
Object.size = function(obj){
|
19
|
+
var size = 0, key;
|
20
|
+
for (key in obj) { if (obj.hasOwnProperty(key)) size++; }
|
21
|
+
return size;
|
27
22
|
};
|
28
23
|
|
29
|
-
|
24
|
+
// Trigger AJAX on textchange
|
30
25
|
var trigger_binded_events_for_phrasable_class = 1;
|
31
26
|
var timer = {}
|
32
27
|
var timer_status = {}
|
@@ -39,8 +34,6 @@ var phrasing_setup = function(){
|
|
39
34
|
if (trigger_binded_events_for_phrasable_class == 1){
|
40
35
|
|
41
36
|
var record = this;
|
42
|
-
|
43
|
-
// console.log(timer)
|
44
37
|
|
45
38
|
clearTimeout(timer[$(record).data("url")]);
|
46
39
|
timer_status[$(record).data("url")] = 0;
|
@@ -54,7 +47,7 @@ var phrasing_setup = function(){
|
|
54
47
|
|
55
48
|
});
|
56
49
|
|
57
|
-
|
50
|
+
// AJAX Request
|
58
51
|
function savePhraseViaAjax(record){
|
59
52
|
|
60
53
|
var url = $(record).data("url");
|
@@ -90,15 +83,15 @@ var phrasing_setup = function(){
|
|
90
83
|
});
|
91
84
|
}
|
92
85
|
|
93
|
-
//
|
86
|
+
// Edit Mode On/Off Button
|
94
87
|
$('#edit-mode-onoffswitch').on('change', function(){
|
95
88
|
if(this.checked){
|
96
|
-
|
97
|
-
|
89
|
+
$('.phrasable').addClass("phrasable_on").attr("contenteditable", "true");
|
90
|
+
$.cookie("editing_mode", "true");
|
98
91
|
}
|
99
92
|
else{
|
100
|
-
|
101
|
-
|
93
|
+
$('.phrasable').removeClass("phrasable_on").attr("contenteditable", "false");
|
94
|
+
$.cookie("editing_mode", "false");
|
102
95
|
}
|
103
96
|
});
|
104
97
|
|
@@ -114,5 +107,4 @@ var phrasing_setup = function(){
|
|
114
107
|
|
115
108
|
};
|
116
109
|
|
117
|
-
$(document).ready(phrasing_setup)
|
118
|
-
// $(document).on('page:load', phrasing_setup)
|
110
|
+
$(document).ready(phrasing_setup)
|
@@ -11,14 +11,15 @@ class PhrasingPhrasesController < ActionController::Base
|
|
11
11
|
def index
|
12
12
|
params[:locale] ||= I18n.default_locale
|
13
13
|
query = PhrasingPhrase
|
14
|
+
query = query.order("#{query.table_name}.key")
|
14
15
|
query = query.where(locale: params[:locale]) unless params[:locale].blank?
|
15
|
-
|
16
|
+
|
16
17
|
if params[:search] and !params[:search].blank?
|
17
18
|
key_like = PhrasingPhrase.arel_table[:key].matches("%#{params[:search]}%")
|
18
19
|
value_like = PhrasingPhrase.arel_table[:value].matches("%#{params[:search]}%")
|
19
|
-
@phrasing_phrases = query.where(key_like.or(value_like))
|
20
|
+
@phrasing_phrases = query.where(key_like.or(value_like))
|
20
21
|
else
|
21
|
-
@phrasing_phrases = query.where("value is not null")
|
22
|
+
@phrasing_phrases = query.where("value is not null") + query.where("value is null")
|
22
23
|
end
|
23
24
|
|
24
25
|
@locale_names = PhrasingPhrase.uniq.pluck(:locale)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module InlineHelper
|
2
2
|
# Normal phrase
|
3
|
-
# phrase("headline", url: www.infinum.co/yabadaba, inverse: true, interpolation: {min: 15, max: 20})
|
3
|
+
# phrase("headline", url: www.infinum.co/yabadaba, inverse: true, interpolation: {min: 15, max: 20}, scope: "models.errors")
|
4
4
|
|
5
5
|
# Data model phrase
|
6
6
|
# phrase(@record, :title, inverse: true, class: phrase-record-title)
|
@@ -8,7 +8,7 @@ module InlineHelper
|
|
8
8
|
def phrase(*args)
|
9
9
|
if args[0].class == String or args[0].class == Symbol
|
10
10
|
key, options = args[0].to_s, args[1]
|
11
|
-
phrasing_phrase(key,options)
|
11
|
+
phrasing_phrase(key,options || {})
|
12
12
|
else
|
13
13
|
record, field_name, options = args[0], args[1], args[2]
|
14
14
|
inline(record, field_name, options || {})
|
@@ -35,10 +35,10 @@ module InlineHelper
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def phrasing_phrase(key, options = {})
|
38
|
-
key = key.to_s
|
38
|
+
key = options[:scope] ? "#{options[:scope]}.#{key}" : key.to_s
|
39
39
|
if can_edit_phrases?
|
40
40
|
@record = PhrasingPhrase.where(key: key, locale: I18n.locale.to_s).first || PhrasingPhrase.search_i18n_and_create_phrase(key)
|
41
|
-
inline(@record, :value, options
|
41
|
+
inline(@record, :value, options)
|
42
42
|
else
|
43
43
|
options.try(:[], :interpolation) ? t(key, options[:interpolation]).html_safe : t(key).html_safe
|
44
44
|
end
|
@@ -18,12 +18,12 @@ class PhrasingPhrase < ActiveRecord::Base
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.create_phrase key, value = nil
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
phrasing_phrase = PhrasingPhrase.new
|
22
|
+
phrasing_phrase.locale = I18n.locale.to_s
|
23
|
+
phrasing_phrase.key = key.to_s
|
24
|
+
phrasing_phrase.value = value || key.to_s
|
25
|
+
phrasing_phrase.save
|
26
|
+
phrasing_phrase
|
27
27
|
end
|
28
28
|
|
29
29
|
module Serialize
|
@@ -8,8 +8,11 @@
|
|
8
8
|
%button.bold b
|
9
9
|
%button.italic i
|
10
10
|
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
|
11
15
|
#phrasing-edit-mode-bubble
|
12
|
-
|
13
16
|
#phrasing-edit-mode
|
14
17
|
#phrasing-edit-mode-headline
|
15
18
|
%p Edit
|
@@ -19,15 +22,13 @@
|
|
19
22
|
%label.onoffswitch-label{for: "edit-mode-onoffswitch"}
|
20
23
|
.onoffswitch-inner
|
21
24
|
.onoffswitch-switch
|
22
|
-
|
23
25
|
#phrasing-saved-status
|
24
26
|
#phrasing-saved-status-headline
|
25
27
|
%p Saved
|
26
28
|
#phrasing-saved-status-indicator
|
27
29
|
#phrasing-saved-status-indicator-circle
|
28
|
-
|
29
30
|
#phrasing-edit-all-phrases
|
30
31
|
#phrasing-edit-all-phrases-headline
|
31
32
|
%p Edit all
|
32
33
|
#phrasing-edit-all-phrases-icon-container
|
33
|
-
= link_to image_tag("phrasing_icon_edit_all.png", class: 'phrasing-edit-all-phrases-icon'), phrasing_phrases_path, data: { no_turbolink: true }
|
34
|
+
= link_to image_tag("phrasing_icon_edit_all.png", class: 'phrasing-edit-all-phrases-icon'), phrasing_phrases_path, data: { no_turbolink: true }, class: "phrasing-edit-all-phrases-link"
|
@@ -6,12 +6,13 @@ module Phrasing
|
|
6
6
|
|
7
7
|
scoped_key = I18n.normalize_keys(nil, key, scope, options[:separator]).join(".")
|
8
8
|
|
9
|
-
|
10
|
-
return
|
9
|
+
phrase = PhrasingPhrase.where(locale: locale.to_s, key: scoped_key).first
|
10
|
+
return phrase.value if phrase
|
11
11
|
|
12
12
|
value = super(locale, key, scope, options)
|
13
|
-
|
14
|
-
|
13
|
+
|
14
|
+
if value and (value.is_a? String or value.is_a? Symbol)
|
15
|
+
# creation in background no matter if developer user the I18n#t or phrase helper
|
15
16
|
PhrasingPhrase.create_phrase(scoped_key, value)
|
16
17
|
end
|
17
18
|
value
|
data/lib/phrasing/version.rb
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
CONFIG_FILE = <<-CONFIG
|
2
|
+
Phrasing.setup do |config|
|
3
|
+
config.route = 'phrasing'
|
4
|
+
end
|
5
|
+
|
6
|
+
# List all the model attributes you wish to edit with Phrasing, example:
|
7
|
+
# Phrasing.whitelist = ["Post.title", "Post.description"]
|
8
|
+
Phrasing.whitelist = []
|
9
|
+
# Phrasing.allow_update_on_all_models_and_attributes = true;
|
10
|
+
CONFIG
|
11
|
+
|
12
|
+
MODULE_FILE = <<-MODULE
|
13
|
+
module PhrasingHelper
|
14
|
+
# You must implement the can_edit_phrases? method.
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# def can_edit_phrases?
|
18
|
+
# current_user.is_admin?
|
19
|
+
# end
|
20
|
+
|
21
|
+
def can_edit_phrases?
|
22
|
+
raise NotImplementedError.new("You must implement the can_edit_phrases? method")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
MODULE
|
26
|
+
|
1
27
|
namespace :phrasing do
|
2
28
|
desc "Install the plugin, including the migration."
|
3
29
|
task :install do
|
@@ -10,61 +36,34 @@ namespace :phrasing do
|
|
10
36
|
task :install_initializer do
|
11
37
|
filepath = Rails.root.join *%w(config initializers phrasing.rb)
|
12
38
|
if File.exists?(filepath)
|
13
|
-
alert "Phrasing config file already exists
|
39
|
+
alert "Phrasing config file already exists."
|
14
40
|
else
|
15
41
|
File.open(filepath, 'w') do |f|
|
16
|
-
f <<
|
17
|
-
Phrasing.setup do |config|
|
18
|
-
config.route = 'phrasing'
|
19
|
-
end
|
20
|
-
|
21
|
-
# List all the model attributes you wish to edit with Phrasing, example:
|
22
|
-
# Phrasing.whitelist = ["Post.title", "Post.description"]
|
23
|
-
Phrasing.whitelist = []
|
24
|
-
# Phrasing.allow_update_on_all_models_and_attributes = true;
|
25
|
-
CONFIG
|
42
|
+
f << CONFIG_FILE
|
26
43
|
end
|
27
|
-
notice
|
28
|
-
puts " config/intiializers/phrasing.rb"
|
44
|
+
notice "created", " config/intiializers/phrasing.rb"
|
29
45
|
end
|
30
46
|
end
|
31
47
|
|
32
|
-
|
33
48
|
desc "Create the PhrasingHelper file"
|
34
49
|
task :install_phrasing_helper do
|
35
50
|
filepath = Rails.root.join *%w(app helpers phrasing_helper.rb)
|
36
51
|
if File.exists?(filepath)
|
37
|
-
alert "Phrasing helper file already exists
|
52
|
+
alert "Phrasing helper file already exists."
|
38
53
|
else
|
39
54
|
File.open(filepath, 'w') do |f|
|
40
|
-
f <<
|
41
|
-
module PhrasingHelper
|
42
|
-
# You must implement the can_edit_phrases? method.
|
43
|
-
# Example:
|
44
|
-
#
|
45
|
-
# def can_edit_phrases?
|
46
|
-
# current_user.is_admin?
|
47
|
-
# end
|
48
|
-
|
49
|
-
def can_edit_phrases?
|
50
|
-
raise NotImplementedError.new("You must implement the can_edit_phrases? method")
|
51
|
-
end
|
52
|
-
end
|
53
|
-
MODULE
|
55
|
+
f << MODULE_FILE
|
54
56
|
end
|
55
|
-
notice
|
56
|
-
|
57
|
-
notice "Now run 'rake db:migrate'.\n"
|
57
|
+
notice "created", "app/helpers/phrasing_helper.rb"
|
58
|
+
notice "Now run 'rake db:migrate'."
|
58
59
|
end
|
59
60
|
end
|
60
|
-
|
61
|
-
|
62
61
|
end
|
63
62
|
|
64
|
-
def notice(
|
65
|
-
|
63
|
+
def notice(colored_text, tailing_text = nil)
|
64
|
+
puts "\033[#{32}m#{colored_text}\033[0m #{tailing_text}"
|
66
65
|
end
|
67
66
|
|
68
|
-
def alert(
|
69
|
-
|
70
|
-
end
|
67
|
+
def alert(colored_text, tailing_text = nil)
|
68
|
+
puts "\033[#{31}m#{colored_text}\033[0m #{tailing_text}"
|
69
|
+
end
|