caboose-cms 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/app/assets/javascripts/caboose/admin_page_edit_content.js +123 -0
- data/app/assets/javascripts/caboose/model/attribute.js +6 -4
- data/app/assets/javascripts/caboose/model/bound_richtext.js +16 -6
- data/app/assets/javascripts/caboose/model/model_binder.js +41 -3
- data/app/assets/javascripts/tinymce/plugins/caboose/plugin.js +47 -0
- data/app/assets/stylesheets/caboose/admin_page_edit_content.css +1 -0
- data/app/controllers/caboose/page_blocks_controller.rb +9 -2
- data/app/models/caboose/page_block.rb +4 -2
- data/app/views/caboose/page_blocks/admin_edit.html.erb +34 -0
- data/app/views/caboose/page_blocks/admin_edit_h1.html.erb +35 -0
- data/app/views/caboose/page_blocks/admin_edit_h2.html.erb +35 -0
- data/app/views/caboose/page_blocks/admin_edit_richtext.html.erb +37 -0
- data/app/views/caboose/pages/admin_edit_content.html.erb +11 -16
- data/config/routes.rb +8 -7
- data/lib/caboose/version.rb +1 -1
- metadata +9 -4
- data/app/models/caboose/page_block_renderer.rb +0 -12
- data/app/models/caboose/page_block_renderer_richtext.rb +0 -68
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODVkYTdlZTk0ZWE0ZGYwOGZhMjZmNTVhY2FiYjBlMmU3OWJmZTllZQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjE4NWNhNTU3MmQ3YjEzZDY2ZDYyMDU2NjNhMmEzNWFjYzU0MTk2Zg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjQ1NzI1ZWQ1MDhlN2ExNDBlN2VmZmIzMDgzZDI0ZjEzZGY2ODlkNGU5YjFl
|
10
|
+
MjAyNmY2MjNmZjUzZTQxNzNiYTk1YWU4MWNhOTgyZjQ1YzA1ZmVkNjk0OGUy
|
11
|
+
MTYzNTkwM2UxMjliMjQ0YjBjOTljOGQwN2YxOGE0ZjQ2ZjE2YmE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OGFmYjEyNDJmNzY5ZGJmNmQ4NjVkNTJiZDFlNThkMzA0MjAyMDdjOWY3YzBk
|
14
|
+
MTlmZmZjMDE3ZjkzYjY3MjhhZDBhZjRlODEzZTA5MTEyM2JhMTY1ZmU4MDY3
|
15
|
+
MjEyYzU2NzJlMmMzYmRhNmUwMjExNGYwZmQ0NzUzYjkzZWM2OTE=
|
@@ -0,0 +1,123 @@
|
|
1
|
+
|
2
|
+
var PageContentEditor = function(page_id, auth_token) {
|
3
|
+
this.page_id = page_id;
|
4
|
+
this.auth_token = auth_token;
|
5
|
+
this.render_blocks();
|
6
|
+
};
|
7
|
+
|
8
|
+
PageContentEditor.prototype = {
|
9
|
+
|
10
|
+
page_id: false,
|
11
|
+
current_block_id: false,
|
12
|
+
|
13
|
+
render_blocks: function()
|
14
|
+
{
|
15
|
+
var that = this;
|
16
|
+
$.ajax({
|
17
|
+
url: '/admin/pages/' + this.page_id + '/blocks',
|
18
|
+
success: function(blocks) {
|
19
|
+
$(blocks).each(function(i,b) { that.render_block(b.id); });
|
20
|
+
}
|
21
|
+
});
|
22
|
+
},
|
23
|
+
|
24
|
+
render_block: function(block_id, after)
|
25
|
+
{
|
26
|
+
var that = this;
|
27
|
+
$.ajax({
|
28
|
+
url: '/admin/pages/' + this.page_id + '/blocks/' + block_id + '/render?empty_text=[Empty, click to edit]',
|
29
|
+
success: function(html) {
|
30
|
+
$('#pageblock_' + block_id).empty().html(html);
|
31
|
+
$('#pageblock_' + block_id).attr('onclick','').unbind('click');
|
32
|
+
$('#pageblock_' + block_id).click(function(e) { that.edit_block(block_id); });
|
33
|
+
if (that.current_block_id == block_id) that.current_block_id = false;
|
34
|
+
if (after) after();
|
35
|
+
}
|
36
|
+
});
|
37
|
+
},
|
38
|
+
|
39
|
+
edit_block: function(block_id)
|
40
|
+
{
|
41
|
+
var that = this;
|
42
|
+
if (this.current_block_id && this.current_block_id != block_id)
|
43
|
+
{
|
44
|
+
this.render_block(this.current_block_id, function() { that.edit_block(block_id); });
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
this.current_block_id = block_id;
|
49
|
+
$('#pageblock_' + block_id).attr('onclick','').unbind('click');
|
50
|
+
$.ajax({
|
51
|
+
url: '/admin/pages/' + this.page_id + '/blocks/' + block_id,
|
52
|
+
success: function(block) {
|
53
|
+
$('#pageblock_' + block.id).empty().append($('<div/>').attr('id', 'pageblock_' + block.id + '_value'));
|
54
|
+
that["edit_" + block.block_type + "_block"](block);
|
55
|
+
}
|
56
|
+
});
|
57
|
+
},
|
58
|
+
|
59
|
+
edit_h1_block: function(block) { return this.edit_text_block(block); },
|
60
|
+
edit_h2_block: function(block) { return this.edit_text_block(block); },
|
61
|
+
edit_h3_block: function(block) { return this.edit_text_block(block); },
|
62
|
+
edit_h4_block: function(block) { return this.edit_text_block(block); },
|
63
|
+
edit_h5_block: function(block) { return this.edit_text_block(block); },
|
64
|
+
edit_h6_block: function(block) { return this.edit_text_block(block); },
|
65
|
+
|
66
|
+
edit_text_block: function(block) {
|
67
|
+
var that = this;
|
68
|
+
m = new ModelBinder({
|
69
|
+
name: 'PageBlock',
|
70
|
+
id: block.id,
|
71
|
+
update_url: '/admin/pages/' + this.page_id + '/blocks/' + block.id,
|
72
|
+
authenticity_token: this.auth_token,
|
73
|
+
attributes: [{
|
74
|
+
name: 'value',
|
75
|
+
nice_name: 'Content',
|
76
|
+
type: 'text',
|
77
|
+
value: block.value,
|
78
|
+
width: 800,
|
79
|
+
fixed_placeholder: false,
|
80
|
+
after_update: this.after_block_update,
|
81
|
+
after_cancel: this.after_block_cancel
|
82
|
+
}],
|
83
|
+
});
|
84
|
+
},
|
85
|
+
|
86
|
+
edit_richtext_block: function(block) {
|
87
|
+
var that = this;
|
88
|
+
m = new ModelBinder({
|
89
|
+
name: 'PageBlock',
|
90
|
+
id: block.id,
|
91
|
+
update_url: '/admin/pages/' + this.page_id + '/blocks/' + block.id,
|
92
|
+
authenticity_token: this.auth_token,
|
93
|
+
attributes: [{
|
94
|
+
name: 'value',
|
95
|
+
nice_name: 'Content',
|
96
|
+
type: 'richtext',
|
97
|
+
value: block.value,
|
98
|
+
width: 800,
|
99
|
+
height: 300,
|
100
|
+
fixed_placeholder: false,
|
101
|
+
after_update: function() {
|
102
|
+
//that.after_block_update(that);
|
103
|
+
that.render_block(that.current_block_id);
|
104
|
+
ModelBinder.remove_from_all_model_binders('PageBlock', that.current_block_id);
|
105
|
+
that.current_block_id = false;
|
106
|
+
},
|
107
|
+
after_cancel: function() { that.after_block_cancel(that); }
|
108
|
+
}],
|
109
|
+
});
|
110
|
+
},
|
111
|
+
|
112
|
+
after_block_update: function(pce) {
|
113
|
+
pce.render_block(pce.current_block_id);
|
114
|
+
ModelBinder.remove_from_all_model_binders('PageBlock', pce.current_block_id);
|
115
|
+
pce.current_block_id = false;
|
116
|
+
},
|
117
|
+
|
118
|
+
after_block_cancel: function(pce) {
|
119
|
+
pce.render_block(pce.current_block_id);
|
120
|
+
ModelBinder.remove_from_all_model_binders('PageBlock', pce.current_block_id);
|
121
|
+
pce.current_block_id = false;
|
122
|
+
}
|
123
|
+
}
|
@@ -17,6 +17,8 @@ Attribute.prototype = {
|
|
17
17
|
align: 'left',
|
18
18
|
before_update: false,
|
19
19
|
after_update: false,
|
20
|
+
before_cancel: false,
|
21
|
+
after_cancel: false,
|
20
22
|
debug: false,
|
21
23
|
|
22
24
|
update_url: false,
|
@@ -30,16 +32,16 @@ Attribute.prototype = {
|
|
30
32
|
url: this.update_url,
|
31
33
|
type: 'put',
|
32
34
|
data: this.name + '=' + encodeURIComponent(this.value),
|
33
|
-
success: function(resp) {
|
35
|
+
success: function(resp) {
|
34
36
|
if (resp.success)
|
35
37
|
{
|
36
38
|
if (resp.attributes && resp.attributes[this2.name])
|
37
39
|
for (var thing in resp.attributes[this2.name])
|
38
40
|
this2[thing] = resp.attributes[this2.name][thing];
|
39
41
|
this2.value_clean = this2.value;
|
40
|
-
}
|
41
|
-
if (after) after(resp);
|
42
|
-
if (this2.after_update) this2.after_update();
|
42
|
+
}
|
43
|
+
if (after) after(resp);
|
44
|
+
if (this2.after_update) this2.after_update();
|
43
45
|
},
|
44
46
|
error: function() {
|
45
47
|
if (after) after(false);
|
@@ -37,8 +37,16 @@ BoundRichText = BoundControl.extend({
|
|
37
37
|
$('#'+this2.el).removeClass('dirty');
|
38
38
|
});
|
39
39
|
|
40
|
-
setTimeout(function() {
|
41
|
-
|
40
|
+
setTimeout(function() {
|
41
|
+
tinymce.execCommand("mceAddEditor", false, this2.el);
|
42
|
+
var ed = tinymce.EditorManager.createEditor(this2.el);
|
43
|
+
|
44
|
+
//var ed = tinymce.EditorManager.get(this2.el);
|
45
|
+
//if (!ed)
|
46
|
+
//{
|
47
|
+
// tinymce.execCommand("mceAddEditor", false, this2.el);
|
48
|
+
// ed = tinymce.EditorManager.createEditor(this2.el);
|
49
|
+
//}
|
42
50
|
ed.on('blur', function(e) { this2.save(); });
|
43
51
|
ed.on('keyup', function(e) {
|
44
52
|
tinymce.triggerSave();
|
@@ -48,7 +56,7 @@ BoundRichText = BoundControl.extend({
|
|
48
56
|
else
|
49
57
|
ed.getBody().style.backgroundColor = "#fff";
|
50
58
|
});
|
51
|
-
},
|
59
|
+
}, 100);
|
52
60
|
},
|
53
61
|
|
54
62
|
show_controls: function() {
|
@@ -115,7 +123,7 @@ BoundRichText = BoundControl.extend({
|
|
115
123
|
},
|
116
124
|
|
117
125
|
cancel: function() {
|
118
|
-
|
126
|
+
if (this.attribute.before_cancel) this.attribute.before_cancel();
|
119
127
|
if ($('#'+this.el).val() != this.attribute.value_clean)
|
120
128
|
{
|
121
129
|
if (confirm('This box has unsaved changes. Hit OK to save changes, Cancel to discard.'))
|
@@ -124,13 +132,15 @@ BoundRichText = BoundControl.extend({
|
|
124
132
|
this.attribute.value_clean = $('#'+this.el).val();
|
125
133
|
this.save();
|
126
134
|
}
|
127
|
-
}
|
135
|
+
}
|
128
136
|
this.attribute.value = this.attribute.value_clean;
|
129
137
|
$('#'+this.el).val(this.attribute.value);
|
130
138
|
$('#'+this.el).removeClass('dirty');
|
131
139
|
|
132
140
|
if ($('#'+this.el+'_check').length)
|
133
|
-
this.hide_check();
|
141
|
+
this.hide_check();
|
142
|
+
tinymce.execCommand("mceRemoveEditor", false, this.el);
|
143
|
+
if (this.attribute.after_cancel) this.attribute.after_cancel();
|
134
144
|
},
|
135
145
|
|
136
146
|
error: function(str) {
|
@@ -1,5 +1,30 @@
|
|
1
1
|
|
2
|
-
var
|
2
|
+
var all_model_binders = [];
|
3
|
+
var ModelBinder = function(params) {
|
4
|
+
this.init(params);
|
5
|
+
all_model_binders[all_model_binders.length] = this;
|
6
|
+
};
|
7
|
+
|
8
|
+
ModelBinder.remove_from_all_model_binders = function(model_name, id) {
|
9
|
+
var arr = [];
|
10
|
+
$.each(all_model_binders, function(i, mb) {
|
11
|
+
if (mb.model.name != model_name || mb.model.id != id)
|
12
|
+
arr[arr.length] = mb;
|
13
|
+
});
|
14
|
+
all_model_binders = arr;
|
15
|
+
};
|
16
|
+
|
17
|
+
ModelBinder.tinymce_current_control = function() {
|
18
|
+
var id = tinymce.activeEditor.id.toLowerCase();
|
19
|
+
var control = false;
|
20
|
+
$.each(all_model_binders, function(i, mb) {
|
21
|
+
$.each(mb.controls, function(i, c) {
|
22
|
+
if (id == (mb.model.name + "_" + mb.model.id + "_" + c.attribute.name).toLowerCase())
|
23
|
+
{ control = c; return false; }
|
24
|
+
});
|
25
|
+
});
|
26
|
+
return control;
|
27
|
+
};
|
3
28
|
|
4
29
|
ModelBinder.prototype = {
|
5
30
|
model: false,
|
@@ -40,11 +65,24 @@ ModelBinder.prototype = {
|
|
40
65
|
else if (attrib.type == 'textarea') control = new BoundTextarea(opts);
|
41
66
|
else if (attrib.type == 'richtext') control = new BoundRichText(opts);
|
42
67
|
else if (attrib.type == 'image') control = new BoundImage(opts);
|
43
|
-
|
44
|
-
this2.controls.push();
|
68
|
+
this2.controls.push(control);
|
45
69
|
});
|
46
70
|
|
47
71
|
if (this.on_load)
|
48
72
|
this.on_load();
|
49
73
|
},
|
74
|
+
|
75
|
+
control_with_id: function(id)
|
76
|
+
{
|
77
|
+
attrib = false
|
78
|
+
var this2 = this;
|
79
|
+
$.each(this.controls, function(i, c) {
|
80
|
+
if (id == (this2.model.name + "_" + this2.model.id + "_" + c.attribute.name).toLowerCase())
|
81
|
+
{
|
82
|
+
attrib = c.attribute;
|
83
|
+
return false;
|
84
|
+
}
|
85
|
+
});
|
86
|
+
return attrib;
|
87
|
+
}
|
50
88
|
};
|
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
tinymce.PluginManager.add('caboose', function(editor, url) {
|
3
|
+
|
4
|
+
editor.addButton('caboose_save', {
|
5
|
+
text: 'Save',
|
6
|
+
icon: false,
|
7
|
+
onclick: function() {
|
8
|
+
tinymce.activeEditor.plugins.autosave.storeDraft();
|
9
|
+
|
10
|
+
var control = ModelBinder.tinymce_current_control();
|
11
|
+
if (!control) return;
|
12
|
+
control.save();
|
13
|
+
control.cancel();
|
14
|
+
}
|
15
|
+
});
|
16
|
+
|
17
|
+
editor.addButton('caboose_cancel', {
|
18
|
+
text: 'Cancel',
|
19
|
+
icon: false,
|
20
|
+
onclick: function() {
|
21
|
+
tinymce.activeEditor.plugins.autosave.storeDraft();
|
22
|
+
|
23
|
+
var control = ModelBinder.tinymce_current_control();
|
24
|
+
if (!control) return;
|
25
|
+
control.cancel();
|
26
|
+
}
|
27
|
+
});
|
28
|
+
|
29
|
+
// Adds a menu item to the tools menu
|
30
|
+
//editor.addMenuItem('example', {
|
31
|
+
// text: 'Example plugin',
|
32
|
+
// context: 'tools',
|
33
|
+
// onclick: function() {
|
34
|
+
// // Open window with a specific url
|
35
|
+
// editor.windowManager.open({
|
36
|
+
// title: 'TinyMCE site',
|
37
|
+
// url: 'http://www.tinymce.com',
|
38
|
+
// width: 800,
|
39
|
+
// height: 600,
|
40
|
+
// buttons: [{
|
41
|
+
// text: 'Close',
|
42
|
+
// onclick: 'close'
|
43
|
+
// }]
|
44
|
+
// });
|
45
|
+
// }
|
46
|
+
//});
|
47
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
2
|
module Caboose
|
3
|
-
class
|
3
|
+
class PageBlocksController < ApplicationController
|
4
4
|
|
5
5
|
#===========================================================================
|
6
6
|
# Admin actions
|
@@ -28,12 +28,19 @@ module Caboose
|
|
28
28
|
render :json => block
|
29
29
|
end
|
30
30
|
|
31
|
+
# GET /admin/pages/:page_id/blocks/:id/render
|
32
|
+
def admin_render
|
33
|
+
return unless user_is_allowed('pages', 'edit')
|
34
|
+
block = PageBlock.find(params[:id])
|
35
|
+
render :text => block.render(params[:empty_text])
|
36
|
+
end
|
37
|
+
|
31
38
|
# GET /admin/pages/:page_id/blocks/:id/edit
|
32
39
|
def admin_edit
|
33
40
|
return unless user_is_allowed('pages', 'edit')
|
34
41
|
@page = Page.find(params[:page_id])
|
35
42
|
@block = PageBlock.find(params[:id])
|
36
|
-
render :layout => 'caboose/admin'
|
43
|
+
render "caboose/page_blocks/admin_edit_#{@block.block_type}", :layout => 'caboose/admin'
|
37
44
|
end
|
38
45
|
|
39
46
|
# POST /admin/pages/:page_id/blocks
|
@@ -5,8 +5,10 @@ class Caboose::PageBlock < ActiveRecord::Base
|
|
5
5
|
belongs_to :page
|
6
6
|
attr_accessible :id, :page_id, :block_type, :sort_order, :name, :value
|
7
7
|
|
8
|
-
def render
|
9
|
-
|
8
|
+
def render(empty_text = nil)
|
9
|
+
str = self.send("render_#{self.block_type.downcase}")
|
10
|
+
return empty_text if empty_text && (str.nil? || str.length == 0)
|
11
|
+
return str
|
10
12
|
end
|
11
13
|
|
12
14
|
def render_richtext() return self.value end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
<%= render :partial => 'caboose/pages/admin_header' %>
|
3
|
+
|
4
|
+
<p>Page block type: <%= @block.block_type %></p>
|
5
|
+
<div id='pageblock_<%= @block.id %>_value'></div>
|
6
|
+
|
7
|
+
<%= render :partial => 'caboose/pages/admin_footer' %>
|
8
|
+
<% content_for :caboose_js do %>
|
9
|
+
<script type='text/javascript'>
|
10
|
+
|
11
|
+
var modal = false;
|
12
|
+
$(window).load(function() {
|
13
|
+
modal = new CabooseModal(800);
|
14
|
+
});
|
15
|
+
|
16
|
+
$(document).ready(function() {
|
17
|
+
<% @page.blocks.each do |b| %>
|
18
|
+
m = new ModelBinder({
|
19
|
+
name: 'PageBlock',
|
20
|
+
id: <%= b.id %>,
|
21
|
+
update_url: '/admin/page-blocks/<%= b.id %>',
|
22
|
+
authenticity_token: '<%= form_authenticity_token %>',
|
23
|
+
attributes: [
|
24
|
+
{ name: 'name' , nice_name: 'Name' , type: 'text' , value: <%= raw Caboose.json(b.name) %>, width: 784 },
|
25
|
+
{ name: 'value', nice_name: 'Content', type: 'richtext', value: <%= raw Caboose.json(b.value) %>, width: 800, height: 300 }
|
26
|
+
]
|
27
|
+
});
|
28
|
+
<% end %>
|
29
|
+
});
|
30
|
+
|
31
|
+
</script>
|
32
|
+
<%= tinymce_assets %>
|
33
|
+
<%= tinymce :caboose, width: '800px', height:'300px' %>
|
34
|
+
<% end %>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
<%= render :partial => 'caboose/pages/admin_header' %>
|
3
|
+
|
4
|
+
<p>Page block type: <%= @block.block_type %></p>
|
5
|
+
<div id='pageblock_<%= @block.id %>_value'></div>
|
6
|
+
<p><input type='button' value='Back to page' onclick="window.location='/admin/pages/<%= @page.id %>/content';" /></p>
|
7
|
+
|
8
|
+
<%= render :partial => 'caboose/pages/admin_footer' %>
|
9
|
+
<% content_for :caboose_js do %>
|
10
|
+
<script type='text/javascript'>
|
11
|
+
|
12
|
+
var modal = false;
|
13
|
+
$(window).load(function() {
|
14
|
+
modal = new CabooseModal(800);
|
15
|
+
});
|
16
|
+
|
17
|
+
$(document).ready(function() {
|
18
|
+
m = new ModelBinder({
|
19
|
+
name: 'PageBlock',
|
20
|
+
id: <%= @block.id %>,
|
21
|
+
update_url: '/admin/pages/<%= @page.id %>/blocks/<%= @block.id %>',
|
22
|
+
authenticity_token: '<%= form_authenticity_token %>',
|
23
|
+
attributes: [{
|
24
|
+
name: 'value',
|
25
|
+
nice_name: 'Content',
|
26
|
+
type: 'text',
|
27
|
+
value: <%= raw Caboose.json(@block.value) %>,
|
28
|
+
width: 800,
|
29
|
+
fixed_placeholder: false
|
30
|
+
}]
|
31
|
+
});
|
32
|
+
});
|
33
|
+
|
34
|
+
</script>
|
35
|
+
<% end %>
|
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
<%= render :partial => 'caboose/pages/admin_header' %>
|
3
|
+
|
4
|
+
<p>Page block type: <%= @block.block_type %></p>
|
5
|
+
<div id='pageblock_<%= @block.id %>_value'></div>
|
6
|
+
<p><input type='button' value='Back to page' onclick="window.location='/admin/pages/<%= @page.id %>/content';" /></p>
|
7
|
+
|
8
|
+
<%= render :partial => 'caboose/pages/admin_footer' %>
|
9
|
+
<% content_for :caboose_js do %>
|
10
|
+
<script type='text/javascript'>
|
11
|
+
|
12
|
+
var modal = false;
|
13
|
+
$(window).load(function() {
|
14
|
+
modal = new CabooseModal(800);
|
15
|
+
});
|
16
|
+
|
17
|
+
$(document).ready(function() {
|
18
|
+
m = new ModelBinder({
|
19
|
+
name: 'PageBlock',
|
20
|
+
id: <%= @block.id %>,
|
21
|
+
update_url: '/admin/pages/<%= @page.id %>/blocks/<%= @block.id %>',
|
22
|
+
authenticity_token: '<%= form_authenticity_token %>',
|
23
|
+
attributes: [{
|
24
|
+
name: 'value',
|
25
|
+
nice_name: 'Content',
|
26
|
+
type: 'text',
|
27
|
+
value: <%= raw Caboose.json(@block.value) %>,
|
28
|
+
width: 800,
|
29
|
+
fixed_placeholder: false
|
30
|
+
}]
|
31
|
+
});
|
32
|
+
});
|
33
|
+
|
34
|
+
</script>
|
35
|
+
<% end %>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
<%= render :partial => 'caboose/pages/admin_header' %>
|
3
|
+
|
4
|
+
<p>Page block type: <%= @block.block_type %></p>
|
5
|
+
<div id='pageblock_<%= @block.id %>_value'></div>
|
6
|
+
<p><input type='button' value='Back to page' onclick="window.location='/admin/pages/<%= @page.id %>/content';" /></p>
|
7
|
+
|
8
|
+
<%= render :partial => 'caboose/pages/admin_footer' %>
|
9
|
+
<% content_for :caboose_js do %>
|
10
|
+
<script type='text/javascript'>
|
11
|
+
|
12
|
+
var modal = false;
|
13
|
+
$(window).load(function() {
|
14
|
+
modal = new CabooseModal(800);
|
15
|
+
});
|
16
|
+
|
17
|
+
$(document).ready(function() {
|
18
|
+
m = new ModelBinder({
|
19
|
+
name: 'PageBlock',
|
20
|
+
id: <%= @block.id %>,
|
21
|
+
update_url: '/admin/pages/<%= @page.id %>/blocks/<%= @block.id %>',
|
22
|
+
authenticity_token: '<%= form_authenticity_token %>',
|
23
|
+
attributes: [{
|
24
|
+
name: 'value',
|
25
|
+
nice_name: 'Content',
|
26
|
+
type: 'richtext',
|
27
|
+
value: <%= raw Caboose.json(@block.value) %>,
|
28
|
+
width: 800,
|
29
|
+
fixed_placeholder: false
|
30
|
+
}]
|
31
|
+
});
|
32
|
+
});
|
33
|
+
|
34
|
+
</script>
|
35
|
+
<%= tinymce_assets %>
|
36
|
+
<%= tinymce :caboose, width: '800px', height:'300px' %>
|
37
|
+
<% end %>
|
@@ -1,12 +1,18 @@
|
|
1
1
|
|
2
2
|
<%= render :partial => 'caboose/pages/admin_header' %>
|
3
|
-
|
4
|
-
<% @page.blocks.each do |b| %>
|
5
|
-
<div id='pageblock_<%= b.id %>
|
3
|
+
|
4
|
+
<% @page.blocks.each do |b| %>
|
5
|
+
<div id='pageblock_<%= b.id %>'></div>
|
6
6
|
<% end %>
|
7
7
|
|
8
8
|
<%= render :partial => 'caboose/pages/admin_footer' %>
|
9
|
+
|
10
|
+
<% content_for :caboose_css do %>
|
11
|
+
<%= stylesheet_link_tag 'caboose/admin_page_edit_content', :media => 'all' %>
|
12
|
+
<% end %>
|
13
|
+
|
9
14
|
<% content_for :caboose_js do %>
|
15
|
+
<%= javascript_include_tag 'caboose/admin_page_edit_content' %>
|
10
16
|
<script type='text/javascript'>
|
11
17
|
|
12
18
|
var modal = false;
|
@@ -14,19 +20,8 @@ $(window).load(function() {
|
|
14
20
|
modal = new CabooseModal(800);
|
15
21
|
});
|
16
22
|
|
17
|
-
$(document).ready(function() {
|
18
|
-
|
19
|
-
m = new ModelBinder({
|
20
|
-
name: 'PageBlock',
|
21
|
-
id: <%= b.id %>,
|
22
|
-
update_url: '/admin/page-blocks/<%= b.id %>',
|
23
|
-
authenticity_token: '<%= form_authenticity_token %>',
|
24
|
-
attributes: [
|
25
|
-
{ name: 'name' , nice_name: 'Name' , type: 'text' , value: <%= raw Caboose.json(b.name) %>, width: 784 },
|
26
|
-
{ name: 'value', nice_name: 'Content', type: 'richtext', value: <%= raw Caboose.json(b.value) %>, width: 800, height: 300 }
|
27
|
-
]
|
28
|
-
});
|
29
|
-
<% end %>
|
23
|
+
$(document).ready(function() {
|
24
|
+
var ed = new PageContentEditor(<%= @page.id %>);
|
30
25
|
});
|
31
26
|
|
32
27
|
</script>
|
data/config/routes.rb
CHANGED
@@ -67,13 +67,14 @@ Caboose::Engine.routes.draw do
|
|
67
67
|
post "admin/pages" => "pages#admin_create"
|
68
68
|
delete "admin/pages/:id" => "pages#admin_delete"
|
69
69
|
|
70
|
-
get "admin/pages/:page_id/blocks/new"
|
71
|
-
get "admin/pages/:page_id/blocks/:id/
|
72
|
-
get "admin/pages/:page_id/blocks/:id"
|
73
|
-
get "admin/pages/:page_id/blocks"
|
74
|
-
|
75
|
-
|
76
|
-
|
70
|
+
get "admin/pages/:page_id/blocks/new" => "page_blocks#admin_new"
|
71
|
+
get "admin/pages/:page_id/blocks/:id/render" => "page_blocks#admin_render"
|
72
|
+
get "admin/pages/:page_id/blocks/:id/edit" => "page_blocks#admin_edit"
|
73
|
+
get "admin/pages/:page_id/blocks/:id" => "page_blocks#admin_show"
|
74
|
+
get "admin/pages/:page_id/blocks" => "page_blocks#admin_index"
|
75
|
+
post "admin/pages/:page_id/blocks" => "page_blocks#admin_create"
|
76
|
+
put "admin/pages/:page_id/blocks/:id" => "page_blocks#admin_update"
|
77
|
+
delete "admin/pages/:page_id/blocks/:id" => "page_blocks#admin_delete"
|
77
78
|
|
78
79
|
get "posts" => "posts#index"
|
79
80
|
get "posts/:id" => "posts#detail"
|
data/lib/caboose/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: caboose-cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- William Barry
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-12-
|
11
|
+
date: 2013-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -127,6 +127,7 @@ files:
|
|
127
127
|
- app/assets/images/caboose/loading_white_on_black.gif
|
128
128
|
- app/assets/images/caboose/search.png
|
129
129
|
- app/assets/javascripts/caboose/admin.js
|
130
|
+
- app/assets/javascripts/caboose/admin_page_edit_content.js
|
130
131
|
- app/assets/javascripts/caboose/application.js
|
131
132
|
- app/assets/javascripts/caboose/modal.js
|
132
133
|
- app/assets/javascripts/caboose/modal_integration.js
|
@@ -148,7 +149,9 @@ files:
|
|
148
149
|
- app/assets/javascripts/caboose/placeholder.js
|
149
150
|
- app/assets/javascripts/caboose/shortcut.js
|
150
151
|
- app/assets/javascripts/caboose/station.js
|
152
|
+
- app/assets/javascripts/tinymce/plugins/caboose/plugin.js
|
151
153
|
- app/assets/stylesheets/caboose/admin.css
|
154
|
+
- app/assets/stylesheets/caboose/admin_page_edit_content.css
|
152
155
|
- app/assets/stylesheets/caboose/application.css
|
153
156
|
- app/assets/stylesheets/caboose/bound_input.css
|
154
157
|
- app/assets/stylesheets/caboose/caboose.css
|
@@ -189,8 +192,6 @@ files:
|
|
189
192
|
- app/models/caboose/page.rb
|
190
193
|
- app/models/caboose/page_bar_generator.rb
|
191
194
|
- app/models/caboose/page_block.rb
|
192
|
-
- app/models/caboose/page_block_renderer.rb
|
193
|
-
- app/models/caboose/page_block_renderer_richtext.rb
|
194
195
|
- app/models/caboose/page_permission.rb
|
195
196
|
- app/models/caboose/pager.rb
|
196
197
|
- app/models/caboose/permission.rb
|
@@ -210,6 +211,10 @@ files:
|
|
210
211
|
- app/views/caboose/extras/error.html.erb
|
211
212
|
- app/views/caboose/extras/error404.html.erb
|
212
213
|
- app/views/caboose/login/index.html.erb
|
214
|
+
- app/views/caboose/page_blocks/admin_edit.html.erb
|
215
|
+
- app/views/caboose/page_blocks/admin_edit_h1.html.erb
|
216
|
+
- app/views/caboose/page_blocks/admin_edit_h2.html.erb
|
217
|
+
- app/views/caboose/page_blocks/admin_edit_richtext.html.erb
|
213
218
|
- app/views/caboose/pages/_admin_footer.html.erb
|
214
219
|
- app/views/caboose/pages/_admin_header.html.erb
|
215
220
|
- app/views/caboose/pages/admin_delete_form.html.erb
|
@@ -1,68 +0,0 @@
|
|
1
|
-
|
2
|
-
class Caboose::PageBlockRendererRichtext
|
3
|
-
|
4
|
-
self.table_name = "page_blocks"
|
5
|
-
|
6
|
-
belongs_to :page
|
7
|
-
attr_accessible :id, :page_id, :block_type, :sort_order, :name, :value
|
8
|
-
|
9
|
-
@_renderer
|
10
|
-
def renderer
|
11
|
-
if @_renderer.nil?
|
12
|
-
@_renderer = "Caboose::PageBlock#{self.block_type.upcase}Renderer".constantize.new
|
13
|
-
@_renderer.page_block = self
|
14
|
-
end
|
15
|
-
return @_renderer
|
16
|
-
end
|
17
|
-
|
18
|
-
def render
|
19
|
-
self.renderer.render
|
20
|
-
end
|
21
|
-
|
22
|
-
def content
|
23
|
-
a = self.name.nil? || self.name.length == 0 ? '' : "<a name='#{self.name}'></a>"
|
24
|
-
return "#{a}#{self.value}" if self.block_type == 'richtext'
|
25
|
-
return "#{a}<p>#{self.value}</p>" if self.block_type == 'p'
|
26
|
-
return "#{a}<h1>#{self.value}</h1>" if self.block_type == 'h1'
|
27
|
-
return "#{a}<h2>#{self.value}</h2>" if self.block_type == 'h2'
|
28
|
-
return "#{a}<h3>#{self.value}</h3>" if self.block_type == 'h3'
|
29
|
-
return "#{a}<h4>#{self.value}</h4>" if self.block_type == 'h4'
|
30
|
-
return "#{a}<h5>#{self.value}</h5>" if self.block_type == 'h5'
|
31
|
-
return "#{a}<h6>#{self.value}</h6>" if self.block_type == 'h6'
|
32
|
-
|
33
|
-
if self.block_type == 'posts'
|
34
|
-
obj = Caboose::StdClass(JSON.parse(self.value))
|
35
|
-
defaults = {
|
36
|
-
'limit' => 10,
|
37
|
-
'no_posts_message' => "<p>There are no posts right now.</p>",
|
38
|
-
'invalid_category_message' => "<p>Invalid post category.</p>",
|
39
|
-
'body_character_limit' => 0
|
40
|
-
}
|
41
|
-
defaults.each { |k,v| obj[k] = v if obj[k].nil? }
|
42
|
-
|
43
|
-
return obj.invalid_category_message if !Caboose::PostCategory.exists?(obj.category_id)
|
44
|
-
cat = Caboose::PostCategory.find(obj.category_id)
|
45
|
-
posts = obj.limit == 0 ? cat.posts.reorder('created_at DESC') : cat.posts.reorder('created_at DESC').limit(obj.limit)
|
46
|
-
return obj.no_posts_message posts.nil? || posts.count == 0
|
47
|
-
|
48
|
-
str = ""
|
49
|
-
posts.each do |p|
|
50
|
-
str = "<div class='post'>"
|
51
|
-
str << "<h2>#{raw p.title}</h2>"
|
52
|
-
str << "<div class='created_at'>#{p.created_at.strftime('%F %T')}</div>"
|
53
|
-
str << "<div class='post_content'>"
|
54
|
-
str << obj.body_character_limit > 0 ? Caboose.teaser_text(p.body, obj.body_character_limit) : p.body
|
55
|
-
str << "</div>"
|
56
|
-
str << "</div>"
|
57
|
-
end
|
58
|
-
|
59
|
-
assoc = cat
|
60
|
-
if Caboose
|
61
|
-
|
62
|
-
|
63
|
-
if Caboose::PostCategoryMembership.exists?(:post_category_id => cat.id)
|
64
|
-
Caboose::PostCategoryMembership.where(:post_category_id => cat.id)
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|