caboose-cms 0.5.28 → 0.5.30
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Rakefile +10 -25
- data/app/assets/javascripts/caboose/admin_page_edit_content.js +68 -43
- data/app/assets/stylesheets/caboose/admin_page_edit_content.css +18 -9
- data/app/controllers/caboose/blocks_controller.rb +24 -17
- data/app/models/caboose/block.rb +54 -19
- data/app/models/caboose/user.rb +2 -0
- data/app/views/caboose/pages/admin_edit_content.html.erb +12 -9
- data/lib/caboose.rb +4 -0
- data/lib/caboose/engine.rb +10 -1
- data/lib/caboose/version.rb +1 -1
- data/lib/tasks/caboose.rake +6 -22
- data/lib/tasks/caboose_sync.rake +112 -0
- data/spec/factories/caboose_blocks.rb +20 -0
- data/spec/factories/caboose_users.rb +19 -0
- data/spec/models/block_spec.rb +114 -0
- data/spec/models/user_spec.rb +9 -0
- metadata +109 -68
- data/test/caboose_test.rb +0 -7
- data/test/dummy/README.rdoc +0 -261
- data/test/dummy/Rakefile +0 -7
- data/test/dummy/app/assets/javascripts/application.js +0 -15
- data/test/dummy/app/assets/stylesheets/application.css +0 -13
- data/test/dummy/app/controllers/application_controller.rb +0 -3
- data/test/dummy/app/helpers/application_helper.rb +0 -2
- data/test/dummy/app/views/layouts/application.html.erb +0 -14
- data/test/dummy/config.ru +0 -4
- data/test/dummy/config/application.rb +0 -59
- data/test/dummy/config/boot.rb +0 -10
- data/test/dummy/config/database.yml +0 -25
- data/test/dummy/config/environment.rb +0 -5
- data/test/dummy/config/environments/development.rb +0 -37
- data/test/dummy/config/environments/production.rb +0 -67
- data/test/dummy/config/environments/test.rb +0 -37
- data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/test/dummy/config/initializers/inflections.rb +0 -15
- data/test/dummy/config/initializers/mime_types.rb +0 -5
- data/test/dummy/config/initializers/secret_token.rb +0 -7
- data/test/dummy/config/initializers/session_store.rb +0 -8
- data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/test/dummy/config/locales/en.yml +0 -5
- data/test/dummy/config/routes.rb +0 -4
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/test.log +0 -25
- data/test/dummy/public/404.html +0 -26
- data/test/dummy/public/422.html +0 -26
- data/test/dummy/public/500.html +0 -25
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +0 -6
- data/test/integration/navigation_test.rb +0 -10
- data/test/test_helper.rb +0 -15
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YmJiNzg3OTk5YWQxNWNmM2NhMTU0ZTMzN2FjNDMxODk4NjgwZTVkMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjA0MWM2Mjc5YzNkOWE0MjEyYTFiMzBkYzc5MzliOTYxNjQ1Y2I3ZA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MmE1ZWFkYzk1NjM1NDYxY2MzODJkMmMwNzJiOTg3NzIzZDk1NDBiNGQwZjg1
|
10
|
+
ODI1NjMyOWZkZDVkYTMwMjA1NWZhZWVkMTE1NDNhY2QwOGJiYTBmYTQzMDli
|
11
|
+
ZjFhMjgyMGZlYmMwOTQyY2Q3YTk3MjYwNjlmYTQ0MWYwNDRjZmQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MjQwNzc0M2E3NjVlMTZiMDQ1NmVhZjIyOTRlZjc3NjQzZjY2ODY5NGZhZDc2
|
14
|
+
ZmE3ZjA3YzBkOGFmZThjNTYwNTZjNTQ5YTVmODZmZGU0ZTYyMmE0ZGVlODBk
|
15
|
+
ODQ4YmVlOTY0YWQ1ZjYzNzc3YWY3NzQzZGZhZjgzOWJlMDdmYzU=
|
data/Rakefile
CHANGED
@@ -1,38 +1,23 @@
|
|
1
1
|
#!/usr/bin/env rake
|
2
2
|
begin
|
3
|
-
require 'bundler/setup'
|
3
|
+
require 'bundler/setup'; Bundler.setup(:default, :development)
|
4
4
|
rescue LoadError
|
5
5
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
6
|
end
|
7
|
-
begin
|
8
|
-
require 'rdoc/task'
|
9
|
-
rescue LoadError
|
10
|
-
require 'rdoc/rdoc'
|
11
|
-
require 'rake/rdoctask'
|
12
|
-
RDoc::Task = Rake::RDocTask
|
13
|
-
end
|
14
7
|
|
15
|
-
|
16
|
-
rdoc.rdoc_dir = 'rdoc'
|
17
|
-
rdoc.title = 'Caboose'
|
18
|
-
rdoc.options << '--line-numbers'
|
19
|
-
rdoc.rdoc_files.include('README.rdoc')
|
20
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
-
end
|
22
|
-
|
23
|
-
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
8
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
24
9
|
load 'rails/tasks/engine.rake'
|
25
10
|
|
26
11
|
Bundler::GemHelper.install_tasks
|
27
12
|
|
28
|
-
|
13
|
+
Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
|
29
14
|
|
30
|
-
|
31
|
-
|
32
|
-
t.libs << 'test'
|
33
|
-
t.pattern = 'test/**/*_test.rb'
|
34
|
-
t.verbose = false
|
35
|
-
end
|
15
|
+
require 'rspec/core'
|
16
|
+
require 'rspec/core/rake_task'
|
36
17
|
|
18
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
19
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
37
20
|
|
38
|
-
task :default => :test
|
21
|
+
#task :default => :test
|
22
|
+
task :default => :spec
|
23
|
+
task :test => :spec
|
@@ -19,45 +19,45 @@ PageContentController.prototype = {
|
|
19
19
|
|
20
20
|
sortable_blocks: function()
|
21
21
|
{
|
22
|
-
var that = this;
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
});
|
22
|
+
//var that = this;
|
23
|
+
//$('.sortable').sortable({
|
24
|
+
// //hoverClass: "ui-state-active",
|
25
|
+
// placeholder: 'sortable-placeholder',
|
26
|
+
// forcePlaceholderSize: true,
|
27
|
+
// handle: '.sort_handle',
|
28
|
+
// receive: function(e, ui) {
|
29
|
+
// that.new_block_type_id = ui.item.attr('id').replace('new_block_', '');
|
30
|
+
// },
|
31
|
+
// update: function(e, ui) {
|
32
|
+
// if (that.new_block_type_id)
|
33
|
+
// {
|
34
|
+
// $.ajax({
|
35
|
+
// url: '/admin/pages/' + that.page_id + '/blocks',
|
36
|
+
// type: 'post',
|
37
|
+
// data: { block_type_id: that.new_block_type_id, index: ui.item.index() },
|
38
|
+
// success: function(resp) { that.render_blocks(function() { that.edit_block(resp.block.id); }); }
|
39
|
+
// });
|
40
|
+
// that.new_block_type_id = false;
|
41
|
+
// }
|
42
|
+
// else
|
43
|
+
// {
|
44
|
+
// var ids = [];
|
45
|
+
// $.each($(e.target).children(), function(i, el) {
|
46
|
+
// var id = $(el).attr('id');
|
47
|
+
// if (id && id.substr(0, 6) == 'block_') ids.push(id.substr(6));
|
48
|
+
// });
|
49
|
+
//
|
50
|
+
// $.ajax({
|
51
|
+
// url: '/admin/pages/' + that.page_id + '/block-order',
|
52
|
+
// type: 'put',
|
53
|
+
// data: {
|
54
|
+
// block_ids: ids,
|
55
|
+
// },
|
56
|
+
// success: function(resp) {}
|
57
|
+
// });
|
58
|
+
// }
|
59
|
+
// }
|
60
|
+
//});
|
61
61
|
},
|
62
62
|
|
63
63
|
draggable_blocks: function()
|
@@ -129,6 +129,30 @@ PageContentController.prototype = {
|
|
129
129
|
}
|
130
130
|
that.render_blocks();
|
131
131
|
},
|
132
|
+
|
133
|
+
move_block_up: function(block_id)
|
134
|
+
{
|
135
|
+
var that = this;
|
136
|
+
$.ajax({
|
137
|
+
url: '/admin/pages/' + this.page_id + '/blocks/' + block_id + '/move-up',
|
138
|
+
type: 'put',
|
139
|
+
success: function(resp) {
|
140
|
+
if (resp.success) that.render_blocks();
|
141
|
+
}
|
142
|
+
});
|
143
|
+
},
|
144
|
+
|
145
|
+
move_block_down: function(block_id)
|
146
|
+
{
|
147
|
+
var that = this;
|
148
|
+
$.ajax({
|
149
|
+
url: '/admin/pages/' + this.page_id + '/blocks/' + block_id + '/move-down',
|
150
|
+
type: 'put',
|
151
|
+
success: function(resp) {
|
152
|
+
if (resp.success) that.render_blocks();
|
153
|
+
}
|
154
|
+
});
|
155
|
+
},
|
132
156
|
|
133
157
|
/*****************************************************************************
|
134
158
|
Block Rendering
|
@@ -148,7 +172,7 @@ PageContentController.prototype = {
|
|
148
172
|
that.selected_block_ids = [];
|
149
173
|
}
|
150
174
|
});
|
151
|
-
},
|
175
|
+
},
|
152
176
|
|
153
177
|
set_clickable: function()
|
154
178
|
{
|
@@ -168,9 +192,10 @@ PageContentController.prototype = {
|
|
168
192
|
var that = this;
|
169
193
|
|
170
194
|
$('#block_' + b.id)
|
171
|
-
.prepend($('<a/>').attr('id', 'block_' + b.id + '_select_handle'
|
172
|
-
.prepend($('<a/>').attr('id', 'block_' + b.id + '
|
173
|
-
.prepend($('<a/>').attr('id', 'block_' + b.id + '
|
195
|
+
.prepend($('<a/>').attr('id', 'block_' + b.id + '_select_handle' ).addClass('select_handle' ).append($('<span/>').addClass('ui-icon ui-icon-check' )).click(function(e) { e.preventDefault(); e.stopPropagation(); that.select_block(b.id); }))
|
196
|
+
.prepend($('<a/>').attr('id', 'block_' + b.id + '_move_up_handle' ).addClass('move_up_handle' ).append($('<span/>').addClass('ui-icon ui-icon-arrow-1-n' )).click(function(e) { e.preventDefault(); e.stopPropagation(); that.move_block_up(b.id); }))
|
197
|
+
.prepend($('<a/>').attr('id', 'block_' + b.id + '_move_down_handle' ).addClass('move_down_handle' ).append($('<span/>').addClass('ui-icon ui-icon-arrow-1-s' )).click(function(e) { e.preventDefault(); e.stopPropagation(); that.move_block_down(b.id); }))
|
198
|
+
.prepend($('<a/>').attr('id', 'block_' + b.id + '_delete_handle' ).addClass('delete_handle' ).append($('<span/>').addClass('ui-icon ui-icon-close' )).click(function(e) { e.preventDefault(); e.stopPropagation(); that.delete_block(b.id); }));
|
174
199
|
|
175
200
|
if (parent_allows_child_blocks && (!b.name || b.name.length == 0))
|
176
201
|
{
|
@@ -11,15 +11,24 @@
|
|
11
11
|
#blocks .ui-selected { background: #fff799; }
|
12
12
|
#blocks .sortable-placeholder { height: 40px; background: #fff799; border: #ccc 1px solid; }
|
13
13
|
|
14
|
-
|
15
|
-
#blocks li .sort_handle
|
16
|
-
#blocks li .
|
17
|
-
#blocks li:hover .
|
18
|
-
|
19
|
-
|
20
|
-
#blocks li
|
21
|
-
#blocks li
|
22
|
-
#blocks li
|
14
|
+
/*
|
15
|
+
#blocks li .sort_handle { display: none; }
|
16
|
+
#blocks li:hover .sort_handle { position: absolute; top: 0; right: 22px; display: block; width: 20px; height: 20px; background-color: #ccc; }
|
17
|
+
#blocks li:hover .sort_handle span { margin: 2px 1px; }
|
18
|
+
*/
|
19
|
+
|
20
|
+
#blocks li .select_handle { display: none; }
|
21
|
+
#blocks li .move_up_handle { display: none; }
|
22
|
+
#blocks li .move_down_handle { display: none; }
|
23
|
+
#blocks li .delete_handle { display: none; }
|
24
|
+
#blocks li:hover .select_handle { position: absolute; top: 0; right: 66px; display: block; width: 20px; height: 20px; background-color: #ccc; }
|
25
|
+
#blocks li:hover .move_up_handle { position: absolute; top: 0; right: 44px; display: block; width: 20px; height: 20px; background-color: #ccc; }
|
26
|
+
#blocks li:hover .move_down_handle { position: absolute; top: 0; right: 22px; display: block; width: 20px; height: 20px; background-color: #ccc; }
|
27
|
+
#blocks li:hover .delete_handle { position: absolute; top: 0; right: 0px; display: block; width: 20px; height: 20px; background-color: #ccc; }
|
28
|
+
#blocks li:hover .select_handle span { margin: 2px 1px; }
|
29
|
+
#blocks li:hover .move_up_handle span { margin: 2px 1px; }
|
30
|
+
#blocks li:hover .move_down_handle span { margin: 2px 1px; }
|
31
|
+
#blocks li:hover .delete_handle span { margin: 2px 1px; }
|
23
32
|
|
24
33
|
.sortable_placeholder {
|
25
34
|
background: #ccc;
|
@@ -353,27 +353,34 @@ module Caboose
|
|
353
353
|
|
354
354
|
resp = StdClass.new
|
355
355
|
b = Block.find(params[:id])
|
356
|
-
|
356
|
+
changed = b.move_up
|
357
|
+
if !changed
|
357
358
|
resp.error = "The block is already at the top."
|
358
359
|
else
|
359
|
-
b2 = nil
|
360
|
-
|
361
|
-
new_sort_order = b.sort_order - 1
|
362
|
-
while new_sort_order > 0 do
|
363
|
-
b2 = Block.where("parent_id = ? and sort_order = ?", b.parent_id, new_sort_order).first
|
364
|
-
break if b2
|
365
|
-
new_sort_order = new_sort_order - 1
|
366
|
-
end
|
367
|
-
if b2
|
368
|
-
b2.sort_order = new_sort_order + 1
|
369
|
-
b2.save
|
370
|
-
else
|
371
|
-
new_sort_order = 1
|
372
|
-
end
|
373
|
-
b.sort_order = new_sort_order
|
374
|
-
b.save
|
375
360
|
resp.success = "The block has been moved up successfully."
|
376
361
|
end
|
362
|
+
|
363
|
+
#if b.sort_order == 0
|
364
|
+
# resp.error = "The block is already at the top."
|
365
|
+
#else
|
366
|
+
# b2 = nil
|
367
|
+
#
|
368
|
+
# new_sort_order = b.sort_order - 1
|
369
|
+
# while new_sort_order > 0 do
|
370
|
+
# b2 = Block.where("parent_id = ? and sort_order = ?", b.parent_id, new_sort_order).first
|
371
|
+
# break if b2
|
372
|
+
# new_sort_order = new_sort_order - 1
|
373
|
+
# end
|
374
|
+
# if b2
|
375
|
+
# b2.sort_order = new_sort_order + 1
|
376
|
+
# b2.save
|
377
|
+
# else
|
378
|
+
# new_sort_order = 1
|
379
|
+
# end
|
380
|
+
# b.sort_order = new_sort_order
|
381
|
+
# b.save
|
382
|
+
# resp.success = "The block has been moved up successfully."
|
383
|
+
#end
|
377
384
|
|
378
385
|
render :json => resp
|
379
386
|
end
|
data/app/models/caboose/block.rb
CHANGED
@@ -29,29 +29,24 @@ class Caboose::Block < ActiveRecord::Base
|
|
29
29
|
:name,
|
30
30
|
:value
|
31
31
|
|
32
|
-
after_initialize
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
after_initialize :caste_value
|
33
|
+
before_save :caste_value
|
34
|
+
|
35
|
+
def caste_value
|
36
|
+
if self.block_type.nil?
|
36
37
|
bt = Caboose::BlockType.where(:field_type => 'text').first
|
37
|
-
|
38
|
+
if bt.nil?
|
39
|
+
bt = Caboose::BlockType.create(:name => 'text', :description => 'Text', :field_type => 'text', :default => '', :width => 800, :height => 400, :fixed_placeholder => false)
|
40
|
+
end
|
41
|
+
self.block_type_id = bt.id
|
38
42
|
end
|
39
|
-
if
|
40
|
-
|
41
|
-
b.save
|
43
|
+
if self.block_type.field_type.nil?
|
44
|
+
self.block_type.field_type = 'text'
|
42
45
|
end
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
before_save :caste_value
|
49
|
-
def caste_value
|
50
|
-
case self.block_type.field_type
|
46
|
+
v = self.value
|
47
|
+
case self.block_type.field_type
|
51
48
|
when 'checkbox'
|
52
|
-
|
53
|
-
else self.value = (self.value == 1 || self.value == '1' || self.value == true ? 1 : 0)
|
54
|
-
end
|
49
|
+
self.value = v ? (v == 1 || v == '1' || v == true ? 1 : 0) : 0
|
55
50
|
end
|
56
51
|
end
|
57
52
|
|
@@ -359,5 +354,45 @@ class Caboose::Block < ActiveRecord::Base
|
|
359
354
|
end
|
360
355
|
return current_value.join('|')
|
361
356
|
end
|
357
|
+
|
358
|
+
# Move a block up
|
359
|
+
def move_up
|
360
|
+
siblings = Caboose::Block.where(:parent_id => self.parent_id).reorder(:sort_order).all
|
361
|
+
siblings.each_with_index do |b2, i|
|
362
|
+
b2.sort_order = i
|
363
|
+
b2.save
|
364
|
+
end
|
365
|
+
changed = false
|
366
|
+
siblings.each_with_index do |b2, i|
|
367
|
+
if i > 0 && b2.id == self.id
|
368
|
+
siblings[i-1].sort_order = i
|
369
|
+
siblings[i-1].save
|
370
|
+
b2.sort_order = i - 1
|
371
|
+
b2.save
|
372
|
+
changed = true
|
373
|
+
end
|
374
|
+
end
|
375
|
+
return changed
|
376
|
+
end
|
377
|
+
|
378
|
+
# Move a block down
|
379
|
+
def move_down
|
380
|
+
siblings = Caboose::Block.where(:parent_id => self.parent_id).reorder(:sort_order).all
|
381
|
+
siblings.each_with_index do |b2, i|
|
382
|
+
b2.sort_order = i
|
383
|
+
b2.save
|
384
|
+
end
|
385
|
+
changed = false
|
386
|
+
siblings.each_with_index do |b2, i|
|
387
|
+
if i < (siblings.count-1) && b2.id == self.id
|
388
|
+
siblings[i+1].sort_order = i
|
389
|
+
siblings[i+1].save
|
390
|
+
b2.sort_order = i + 1
|
391
|
+
b2.save
|
392
|
+
changed = true
|
393
|
+
end
|
394
|
+
end
|
395
|
+
return changed
|
396
|
+
end
|
362
397
|
|
363
398
|
end
|
data/app/models/caboose/user.rb
CHANGED
@@ -14,6 +14,8 @@ class Caboose::User < ActiveRecord::Base
|
|
14
14
|
do_not_validate_attachment_file_type :image
|
15
15
|
attr_accessible :id, :email, :first_name, :last_name, :username, :token, :password, :phone, :timezone
|
16
16
|
|
17
|
+
validates :email, :presence => true
|
18
|
+
|
17
19
|
ADMIN_USER_ID = 1
|
18
20
|
LOGGED_OUT_USER_ID = 2
|
19
21
|
|
@@ -23,15 +23,18 @@
|
|
23
23
|
padding: 16px 10px;
|
24
24
|
}
|
25
25
|
.block_over { background: #e3e3e3; }
|
26
|
-
.select_handle
|
27
|
-
.
|
28
|
-
.
|
29
|
-
.
|
30
|
-
.block_over > .
|
31
|
-
.block_over > .
|
32
|
-
.block_over > .
|
33
|
-
.block_over > .
|
34
|
-
.block_over > .
|
26
|
+
.select_handle { display: none; }
|
27
|
+
.move_up_handle { display: none; }
|
28
|
+
.move_down_handle { display: none; }
|
29
|
+
.delete_handle { display: none; }
|
30
|
+
.block_over > .select_handle { display: block; position: relative; }
|
31
|
+
.block_over > .move_up_handle { display: block; position: relative; }
|
32
|
+
.block_over > .move_down_handle { display: block; position: relative; }
|
33
|
+
.block_over > .delete_handle { display: block; position: relative; }
|
34
|
+
.block_over > .select_handle span { position: absolute; top: 0; right: 54px; width: 18px; height: 18px; background-color: #fff; border: #ccc 1px solid; }
|
35
|
+
.block_over > .move_up_handle span { position: absolute; top: 0; right: 36px; width: 18px; height: 18px; background-color: #fff; border: #ccc 1px solid; }
|
36
|
+
.block_over > .move_down_handle span { position: absolute; top: 0; right: 18px; width: 18px; height: 18px; background-color: #fff; border: #ccc 1px solid; }
|
37
|
+
.block_over > .delete_handle span { position: absolute; top: 0; right: 0px; width: 18px; height: 18px; background-color: #fff; border: #ccc 1px solid; }
|
35
38
|
|
36
39
|
.selected { background: #fff799; }
|
37
40
|
|
data/lib/caboose.rb
CHANGED
data/lib/caboose/engine.rb
CHANGED
@@ -209,7 +209,16 @@ module Caboose
|
|
209
209
|
'*/css/application.js'
|
210
210
|
|
211
211
|
]
|
212
|
-
end
|
212
|
+
end
|
213
|
+
|
214
|
+
# Configure rspec
|
215
|
+
config.generators do |g|
|
216
|
+
g.test_framework :rspec, :fixture => false
|
217
|
+
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
218
|
+
g.assets false
|
219
|
+
g.helper false
|
220
|
+
end
|
221
|
+
|
213
222
|
end
|
214
223
|
end
|
215
224
|
|