billy_cms 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/billy_cms/backend/app.js.erb +31 -212
- data/app/assets/javascripts/billy_cms/backend/controllers/application.controller.js.erb +188 -0
- data/app/assets/javascripts/billy_cms/backend/controllers/page_types.controller.js +19 -0
- data/app/assets/javascripts/billy_cms/backend/directives/header.directive.js +7 -0
- data/app/assets/javascripts/billy_cms/backend/factories/additional_attribute.js +12 -0
- data/app/assets/javascripts/billy_cms/backend/factories/page_type.js +18 -0
- data/app/assets/stylesheets/billy_cms/backend/index.scss +4 -0
- data/app/controllers/api/page_types_controller.rb +1 -1
- data/app/controllers/api/pages_controller.rb +57 -53
- data/app/models/billy_cms/additional_attribute.rb +2 -0
- data/app/models/billy_cms/page.rb +2 -0
- data/app/models/billy_cms/page_type.rb +2 -0
- data/app/serializers/billy_cms/additional_attribute_serializer.rb +3 -3
- data/app/serializers/billy_cms/page_type_serializer.rb +1 -0
- data/app/views/billy_cms/backend/_page_types.html.erb +48 -0
- data/app/views/billy_cms/backend/index.html.erb +1 -1
- data/config/initializers/active_model_serializers.rb +5 -0
- data/config/initializers/friendly_id.rb +90 -0
- data/lib/billy_cms/version.rb +1 -1
- metadata +10 -4
- data/app/assets/javascripts/billy_cms/backend/page_type.js +0 -11
- /data/app/assets/javascripts/billy_cms/backend/{billy_object.js → factories/billy_object.js} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 619314e33692f6ce71b51ade84cdc51d0903c5d5
|
4
|
+
data.tar.gz: 2fe41171a67e95a210ba083fc5e6116087cd633f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b229af480394c3be2e069c97b10de2e9b3f19c837bbb01a18d503b78d73d08b6739b27f7b4b87b5548b8e02725fd2ef36eab1aaaa9527bb44fcf8f7610abdc9
|
7
|
+
data.tar.gz: 732487a213014d6b4bed97e20d4184a9d7f8fc28a7ece74d4187b3f0af4db4bcd45281300bca9ec63a25bc957ffb6c8bf4049747748e6e7e9145c6be91a203e3
|
@@ -1,217 +1,36 @@
|
|
1
|
-
var app = angular.module('BillyCmsBackend', [
|
2
|
-
'ngJsTree',
|
3
|
-
'ui.tinymce',
|
4
|
-
'ngMaterial',
|
5
|
-
'ngFileUpload',
|
6
|
-
'ui.router'
|
7
|
-
]);
|
8
|
-
|
9
|
-
app.run(function() {
|
10
|
-
|
11
|
-
});
|
12
|
-
|
13
|
-
app.config(function($stateProvider, $urlRouterProvider) {
|
14
|
-
$urlRouterProvider.otherwise('/tree');
|
15
|
-
|
16
|
-
$stateProvider
|
17
|
-
.state('tree', {
|
18
|
-
url: '/tree',
|
19
|
-
templateUrl: 'tree/tree.html'
|
20
|
-
})
|
21
|
-
.state('page_types', {
|
22
|
-
url: '/system/types',
|
23
|
-
templateUrl: 'page_types/page_types.html'
|
24
|
-
})
|
25
|
-
.state('additional_attributes', {
|
26
|
-
url: '/system/attributes',
|
27
|
-
templateUrl: 'attributes/attributes.html',
|
28
|
-
controller: 'AttributesCtrl as attrs'
|
29
|
-
})
|
30
|
-
});
|
31
|
-
|
32
1
|
$(function() {
|
33
2
|
$.jstree.defaults.types['Binary'] = { icon: 'binary-type' };
|
34
3
|
});
|
35
4
|
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
5
|
+
angular.module('BillyCmsBackend',
|
6
|
+
[
|
7
|
+
'ngJsTree',
|
8
|
+
'ui.tinymce',
|
9
|
+
'ngMaterial',
|
10
|
+
'ngFileUpload',
|
11
|
+
'ui.router'
|
12
|
+
])
|
13
|
+
|
14
|
+
.run(function() {
|
15
|
+
|
16
|
+
})
|
17
|
+
|
18
|
+
.config(function($stateProvider, $urlRouterProvider) {
|
19
|
+
$urlRouterProvider.otherwise('/tree');
|
20
|
+
|
21
|
+
$stateProvider
|
22
|
+
.state('tree', {
|
23
|
+
url: '/tree',
|
24
|
+
templateUrl: 'tree/tree.html'
|
25
|
+
})
|
26
|
+
.state('page_types', {
|
27
|
+
url: '/system/types',
|
28
|
+
templateUrl: 'page_types/page_types.html',
|
29
|
+
controller: 'PageTypesCtrl as ptctrl'
|
30
|
+
})
|
31
|
+
.state('additional_attributes', {
|
32
|
+
url: '/system/attributes',
|
33
|
+
templateUrl: 'attributes/attributes.html',
|
34
|
+
controller: 'AttributesCtrl as attrs'
|
35
|
+
})
|
65
36
|
});
|
66
|
-
this.tree = [];
|
67
|
-
|
68
|
-
this.recreateTreeFromRawData = function() {
|
69
|
-
ctrl.tree = ctrl.rawPagesData.map(function(page) { return page.jsTreeRepresentation(); });
|
70
|
-
ctrl.tree.push({
|
71
|
-
id: 'root',
|
72
|
-
parent: '#',
|
73
|
-
text: 'Rechtsanwaltskanzlei Arbeitsrecht Sabine Geilen'
|
74
|
-
});
|
75
|
-
ctrl.treeConfig.version++;
|
76
|
-
};
|
77
|
-
|
78
|
-
this.onTreeReady = function() {
|
79
|
-
$(this).on('changed.jstree', function(node, action) {
|
80
|
-
var jstree = $(this).jstree();
|
81
|
-
if (action.action !== 'select_node') {
|
82
|
-
return;
|
83
|
-
}
|
84
|
-
ctrl.selectedNode = ctrl.findPageById(jstree.get_selected()[0]);
|
85
|
-
$scope.$apply();
|
86
|
-
});
|
87
|
-
};
|
88
|
-
|
89
|
-
this.findPageById = function(id) {
|
90
|
-
return this.rawPagesData.filter(function(page) {
|
91
|
-
return id.toString() === page.id.toString();
|
92
|
-
})[0];
|
93
|
-
};
|
94
|
-
|
95
|
-
this.tinymceOptions = {
|
96
|
-
content_css: '<%= stylesheet_path 'application' %>',
|
97
|
-
plugins: 'advlist autolink anchor fullscreen code',
|
98
|
-
toolbar: 'undo redo bold italic underline fullscreen code',
|
99
|
-
menubar: '',
|
100
|
-
height: 350
|
101
|
-
};
|
102
|
-
|
103
|
-
this.saveNode = function(page) {
|
104
|
-
$http({
|
105
|
-
method: 'PATCH',
|
106
|
-
url: '/billy_cms/api/pages/' + page.id,
|
107
|
-
data: {
|
108
|
-
page: page
|
109
|
-
}
|
110
|
-
}).then(
|
111
|
-
function(response) {
|
112
|
-
if (response.status === 200) {
|
113
|
-
console.log('page saved');
|
114
|
-
console.log(response.data.page);
|
115
|
-
ctrl.recreateTreeFromRawData();
|
116
|
-
}
|
117
|
-
},
|
118
|
-
function(err) {
|
119
|
-
alert('Ein Fehler ist beim Speichern aufgetreten.');
|
120
|
-
console.error(err);
|
121
|
-
}
|
122
|
-
);
|
123
|
-
};
|
124
|
-
|
125
|
-
this.createNewPageForNode = function(node) {
|
126
|
-
var title = prompt('Titel der neuen Seite');
|
127
|
-
if (!title) {
|
128
|
-
return;
|
129
|
-
}
|
130
|
-
var pageData = {
|
131
|
-
title: title,
|
132
|
-
parent_page_id: node && node.id
|
133
|
-
};
|
134
|
-
$http.post('/billy_cms/api/pages', {
|
135
|
-
page: pageData
|
136
|
-
}).then(function(response) {
|
137
|
-
if (response.status === 200) {
|
138
|
-
ctrl.rawPagesData.push(new BillyObject(response.data.page));
|
139
|
-
ctrl.recreateTreeFromRawData();
|
140
|
-
}
|
141
|
-
}, function(response) {
|
142
|
-
alert('Fehler beim Erstellen der Seite: ', response.statusText);
|
143
|
-
});
|
144
|
-
};
|
145
|
-
|
146
|
-
this.createNewFileForNode = function(node) {
|
147
|
-
var title = prompt('Titel der Datei');
|
148
|
-
if (!title) {
|
149
|
-
return;
|
150
|
-
}
|
151
|
-
var pageData = {
|
152
|
-
title: title,
|
153
|
-
parent_page_id: node && node.id,
|
154
|
-
page_type: 'Binary'
|
155
|
-
};
|
156
|
-
$http.post('/billy_cms/api/pages', {
|
157
|
-
page: pageData
|
158
|
-
}).then(function(response) {
|
159
|
-
if (response.status === 200) {
|
160
|
-
ctrl.rawPagesData.push(new BillyObject(response.data.page));
|
161
|
-
ctrl.recreateTreeFromRawData();
|
162
|
-
}
|
163
|
-
}, function(response) {
|
164
|
-
alert('Fehler beim Erstellen der Datei: ', response.statusText);
|
165
|
-
});
|
166
|
-
};
|
167
|
-
|
168
|
-
this.deleteNode = function(node) {
|
169
|
-
if (!node || !node.id) {
|
170
|
-
alert('Keine gültige Seite ausgewählt!');
|
171
|
-
return;
|
172
|
-
}
|
173
|
-
var message = 'Die Seite "' + node.title + '" wirklich löschen? Das ist unwiederruflich!';
|
174
|
-
if (window.confirm(message)) {
|
175
|
-
$http.delete('/billy_cms/api/pages/' + node.id).then(function(response) {
|
176
|
-
if (response.status === 200) {
|
177
|
-
var page = ctrl.findPageById(node.id);
|
178
|
-
if (!page) {
|
179
|
-
return;
|
180
|
-
}
|
181
|
-
var pageIndex = ctrl.rawPagesData.indexOf(page);
|
182
|
-
if (pageIndex > -1) {
|
183
|
-
ctrl.rawPagesData.splice(pageIndex, 1);
|
184
|
-
ctrl.recreateTreeFromRawData();
|
185
|
-
}
|
186
|
-
}
|
187
|
-
}, function(response) {
|
188
|
-
alert('Fehler beim Löschen der Datei: ', response.status);
|
189
|
-
});
|
190
|
-
}
|
191
|
-
};
|
192
|
-
|
193
|
-
this.setBinaryContent = function($file, node) {
|
194
|
-
if (!$file) {
|
195
|
-
node.content = '';
|
196
|
-
return;
|
197
|
-
}
|
198
|
-
var reader = new FileReader();
|
199
|
-
|
200
|
-
reader.onloadend = function() {
|
201
|
-
var result = reader.result;
|
202
|
-
node.content = result;
|
203
|
-
$scope.$apply();
|
204
|
-
}
|
205
|
-
reader.readAsDataURL($file);
|
206
|
-
};
|
207
|
-
|
208
|
-
this.openInPreview = function(node) {
|
209
|
-
window.open(node.cms_path || ('/' + node.id));
|
210
|
-
};
|
211
|
-
}]);
|
212
|
-
|
213
|
-
app.directive('billyHeaderToolbar', function() {
|
214
|
-
return {
|
215
|
-
templateUrl: 'header/header.html'
|
216
|
-
};
|
217
|
-
});
|
@@ -0,0 +1,188 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
window.angular.module('BillyCmsBackend').controller('ApplicationCtrl', ['$scope', '$http', 'BillyObject', 'PageType', 'AdditionalAttribute', function($scope, $http, BillyObject, PageType, AdditionalAttribute) {
|
4
|
+
var ctrl = this;
|
5
|
+
|
6
|
+
// data
|
7
|
+
this.rawPagesData = [];
|
8
|
+
this.allPageTypes = [];
|
9
|
+
this.allAdditionalAttributes = [];
|
10
|
+
|
11
|
+
this.treeConfig = {
|
12
|
+
core : {
|
13
|
+
multiple : false,
|
14
|
+
animation: true,
|
15
|
+
error : function(error) {
|
16
|
+
console.error('treeCtrl: error from js tree - ' + angular.toJson(error));
|
17
|
+
},
|
18
|
+
check_callback : true,
|
19
|
+
worker : true
|
20
|
+
},
|
21
|
+
plugins: ['sort', 'state', 'types'],
|
22
|
+
sort: function(node1, node2) {
|
23
|
+
var sortkey1 = ctrl.findPageById(node1).order_key || 0;
|
24
|
+
var sortkey2 = ctrl.findPageById(node2).order_key || 0;
|
25
|
+
return (sortkey2 < sortkey1) ? 1 : -1;
|
26
|
+
},
|
27
|
+
version : 1
|
28
|
+
};
|
29
|
+
$http.get('/billy_cms/api/page_types.json').then(function(result) {
|
30
|
+
ctrl.allPageTypes = result.data.map(function(pageTypeData) {
|
31
|
+
return new PageType(pageTypeData);
|
32
|
+
});
|
33
|
+
});
|
34
|
+
$http.get('/billy_cms/api/attributes.json').then(function(result) {
|
35
|
+
ctrl.allAdditionalAttributes = result.data.map(function(attributeData) {
|
36
|
+
return new AdditionalAttribute(attributeData);
|
37
|
+
});
|
38
|
+
});
|
39
|
+
$http.get('/billy_cms/api/pages.json').then(function(result) {
|
40
|
+
ctrl.rawPagesData = result.data.map(function(page) { return new BillyObject(page); });
|
41
|
+
ctrl.recreateTreeFromRawData();
|
42
|
+
});
|
43
|
+
this.tree = [];
|
44
|
+
|
45
|
+
this.recreateTreeFromRawData = function() {
|
46
|
+
ctrl.tree = ctrl.rawPagesData.map(function(page) { return page.jsTreeRepresentation(); });
|
47
|
+
ctrl.tree.push({
|
48
|
+
id: 'root',
|
49
|
+
parent: '#',
|
50
|
+
text: 'Rechtsanwaltskanzlei Arbeitsrecht Sabine Geilen'
|
51
|
+
});
|
52
|
+
ctrl.treeConfig.version++;
|
53
|
+
};
|
54
|
+
|
55
|
+
this.onTreeReady = function() {
|
56
|
+
$(this).on('changed.jstree', function(node, action) {
|
57
|
+
var jstree = $(this).jstree();
|
58
|
+
if (action.action !== 'select_node') {
|
59
|
+
return;
|
60
|
+
}
|
61
|
+
ctrl.selectedNode = ctrl.findPageById(jstree.get_selected()[0]);
|
62
|
+
$scope.$apply();
|
63
|
+
});
|
64
|
+
};
|
65
|
+
|
66
|
+
this.findPageById = function(id) {
|
67
|
+
return this.rawPagesData.filter(function(page) {
|
68
|
+
return id.toString() === page.id.toString();
|
69
|
+
})[0];
|
70
|
+
};
|
71
|
+
|
72
|
+
this.tinymceOptions = {
|
73
|
+
content_css: '<%= stylesheet_path 'application' %>',
|
74
|
+
plugins: 'advlist autolink anchor fullscreen code',
|
75
|
+
toolbar: 'undo redo bold italic underline fullscreen code',
|
76
|
+
menubar: '',
|
77
|
+
height: 350
|
78
|
+
};
|
79
|
+
|
80
|
+
this.saveNode = function(page) {
|
81
|
+
$http({
|
82
|
+
method: 'PATCH',
|
83
|
+
url: '/billy_cms/api/pages/' + page.id,
|
84
|
+
data: {
|
85
|
+
page: page
|
86
|
+
}
|
87
|
+
}).then(
|
88
|
+
function(response) {
|
89
|
+
if (response.status === 200) {
|
90
|
+
console.log('page saved');
|
91
|
+
console.log(response.data.page);
|
92
|
+
ctrl.recreateTreeFromRawData();
|
93
|
+
}
|
94
|
+
},
|
95
|
+
function(err) {
|
96
|
+
alert('Ein Fehler ist beim Speichern aufgetreten.');
|
97
|
+
console.error(err);
|
98
|
+
}
|
99
|
+
);
|
100
|
+
};
|
101
|
+
|
102
|
+
this.createNewPageForNode = function(node) {
|
103
|
+
var title = prompt('Titel der neuen Seite');
|
104
|
+
if (!title) {
|
105
|
+
return;
|
106
|
+
}
|
107
|
+
var pageData = {
|
108
|
+
title: title,
|
109
|
+
parent_page_id: node && node.id
|
110
|
+
};
|
111
|
+
$http.post('/billy_cms/api/pages', {
|
112
|
+
page: pageData
|
113
|
+
}).then(function(response) {
|
114
|
+
if (response.status === 200) {
|
115
|
+
ctrl.rawPagesData.push(new BillyObject(response.data.page));
|
116
|
+
ctrl.recreateTreeFromRawData();
|
117
|
+
}
|
118
|
+
}, function(response) {
|
119
|
+
alert('Fehler beim Erstellen der Seite: ', response.statusText);
|
120
|
+
});
|
121
|
+
};
|
122
|
+
|
123
|
+
this.createNewFileForNode = function(node) {
|
124
|
+
var title = prompt('Titel der Datei');
|
125
|
+
if (!title) {
|
126
|
+
return;
|
127
|
+
}
|
128
|
+
var pageData = {
|
129
|
+
title: title,
|
130
|
+
parent_page_id: node && node.id,
|
131
|
+
page_type: 'Binary'
|
132
|
+
};
|
133
|
+
$http.post('/billy_cms/api/pages', {
|
134
|
+
page: pageData
|
135
|
+
}).then(function(response) {
|
136
|
+
if (response.status === 200) {
|
137
|
+
ctrl.rawPagesData.push(new BillyObject(response.data.page));
|
138
|
+
ctrl.recreateTreeFromRawData();
|
139
|
+
}
|
140
|
+
}, function(response) {
|
141
|
+
alert('Fehler beim Erstellen der Datei: ', response.statusText);
|
142
|
+
});
|
143
|
+
};
|
144
|
+
|
145
|
+
this.deleteNode = function(node) {
|
146
|
+
if (!node || !node.id) {
|
147
|
+
alert('Keine gültige Seite ausgewählt!');
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
var message = 'Die Seite "' + node.title + '" wirklich löschen? Das ist unwiederruflich!';
|
151
|
+
if (window.confirm(message)) {
|
152
|
+
$http.delete('/billy_cms/api/pages/' + node.id).then(function(response) {
|
153
|
+
if (response.status === 200) {
|
154
|
+
var page = ctrl.findPageById(node.id);
|
155
|
+
if (!page) {
|
156
|
+
return;
|
157
|
+
}
|
158
|
+
var pageIndex = ctrl.rawPagesData.indexOf(page);
|
159
|
+
if (pageIndex > -1) {
|
160
|
+
ctrl.rawPagesData.splice(pageIndex, 1);
|
161
|
+
ctrl.recreateTreeFromRawData();
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}, function(response) {
|
165
|
+
alert('Fehler beim Löschen der Datei: ', response.status);
|
166
|
+
});
|
167
|
+
}
|
168
|
+
};
|
169
|
+
|
170
|
+
this.setBinaryContent = function($file, node) {
|
171
|
+
if (!$file) {
|
172
|
+
node.content = '';
|
173
|
+
return;
|
174
|
+
}
|
175
|
+
var reader = new FileReader();
|
176
|
+
|
177
|
+
reader.onloadend = function() {
|
178
|
+
var result = reader.result;
|
179
|
+
node.content = result;
|
180
|
+
$scope.$apply();
|
181
|
+
};
|
182
|
+
reader.readAsDataURL($file);
|
183
|
+
};
|
184
|
+
|
185
|
+
this.openInPreview = function(node) {
|
186
|
+
window.open(node.cms_path || ('/' + node.id));
|
187
|
+
};
|
188
|
+
}]);
|
@@ -0,0 +1,19 @@
|
|
1
|
+
window.angular.module('BillyCmsBackend').controller('PageTypesCtrl', ['$scope', function($scope) {
|
2
|
+
var self = this;
|
3
|
+
$scope.$watch(
|
4
|
+
function() { return $scope.app.allPageTypes; },
|
5
|
+
function(newPageTypes, oldPageTypes) {
|
6
|
+
if ((oldPageTypes === undefined || !oldPageTypes.length) && newPageTypes && newPageTypes.length) {
|
7
|
+
self.selectPageType(newPageTypes[0]);
|
8
|
+
}
|
9
|
+
}
|
10
|
+
);
|
11
|
+
|
12
|
+
this.selectPageType = function(pageType) {
|
13
|
+
this.selectedPageType = pageType;
|
14
|
+
};
|
15
|
+
|
16
|
+
if ($scope.app.allPageTypes && $scope.app.allPageTypes.length > 0) {
|
17
|
+
this.selectPageType($scope.app.allPageTypes[0]);
|
18
|
+
}
|
19
|
+
}]);
|
@@ -0,0 +1,12 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
angular.module('BillyCmsBackend').factory('AdditionalAttribute', [function() {
|
4
|
+
var AdditionalAttribute = function(options) {
|
5
|
+
this.id = options.id || null;
|
6
|
+
this.name = options.name || null;
|
7
|
+
this.title = options.title || '';
|
8
|
+
this.attribute_type = options.attribute_type || 'string';
|
9
|
+
};
|
10
|
+
|
11
|
+
return AdditionalAttribute;
|
12
|
+
}]);
|
@@ -0,0 +1,18 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
angular.module('BillyCmsBackend').factory('PageType', ['AdditionalAttribute', function(AdditionalAttribute) {
|
4
|
+
var PageType = function(options) {
|
5
|
+
this.id = options.id || null;
|
6
|
+
this.name = options.name || null;
|
7
|
+
this.title = options.title || '';
|
8
|
+
|
9
|
+
this.additional_attributes = (options.additional_attributes || []).map(function(attributeOptions) {
|
10
|
+
return new AdditionalAttribute(attributeOptions);
|
11
|
+
})
|
12
|
+
};
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
return PageType;
|
17
|
+
|
18
|
+
}]);
|
@@ -1,61 +1,65 @@
|
|
1
1
|
module Api
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
class PagesController < ApiController
|
3
|
+
def index
|
4
|
+
render json: BillyCms::Page.all
|
5
|
+
end
|
6
|
+
|
7
|
+
def show
|
8
|
+
render json: BillyCms::Page.find(params[:id])
|
9
|
+
end
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
def update
|
12
|
+
render nothing: true, status: 400 unless params[:page]
|
13
|
+
page = BillyCms::Page.find params[:id]
|
14
|
+
if page.update_attributes page_params
|
15
|
+
render json: {
|
16
|
+
success: true,
|
17
|
+
page: page
|
18
|
+
}
|
19
|
+
else
|
20
|
+
render json: {
|
21
|
+
success: false,
|
22
|
+
error: page.errors.full_messages,
|
23
|
+
}, status: 500
|
24
|
+
end
|
25
|
+
end
|
22
26
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
27
|
+
def create
|
28
|
+
render nothing: true, status: 400 unless params[:page]
|
29
|
+
page = BillyCms::Page.new page_params
|
30
|
+
if page.save
|
31
|
+
render json: {
|
32
|
+
success: true,
|
33
|
+
page: page
|
34
|
+
}
|
35
|
+
else
|
36
|
+
render json: {
|
37
|
+
success: false,
|
38
|
+
error: page.error_messages,
|
39
|
+
}, status: 500
|
40
|
+
end
|
41
|
+
end
|
38
42
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
def destroy
|
44
|
+
render :nothing, status: 400 unless params[:id]
|
45
|
+
if BillyCms::Page.delete(params[:id])
|
46
|
+
render json: {
|
47
|
+
success: true
|
48
|
+
}
|
49
|
+
else
|
50
|
+
render json: {
|
51
|
+
success: false,
|
52
|
+
error: page.error_messages,
|
53
|
+
}, status: 500
|
54
|
+
end
|
55
|
+
end
|
52
56
|
|
53
|
-
|
57
|
+
private
|
54
58
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
59
|
+
def page_params
|
60
|
+
page = BillyCms::Page.find(params[:id]) if params[:id].present?
|
61
|
+
allowed_types = page ? page.additional_attributes.map(&:name).map(&:to_sym) : []
|
62
|
+
params.require(:page).permit(:title, :content, :parent_page_id, :order_key, :hide_from_navigation, :page_type, additional_attributes_values: allowed_types) if current_user.admin?
|
60
63
|
end
|
64
|
+
end
|
61
65
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module BillyCms
|
2
2
|
class AdditionalAttribute < ActiveRecord::Base
|
3
|
+
include ActiveModel::Serialization
|
4
|
+
|
3
5
|
has_many :additional_attributes_page_types, class_name: 'BillyCms::AdditionalAttributesPageTypes'
|
4
6
|
has_many :page_types, through: :additional_attributes_page_types
|
5
7
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module BillyCms
|
2
2
|
class PageType < ActiveRecord::Base
|
3
|
+
include ActiveModel::Serialization
|
4
|
+
|
3
5
|
has_many :additional_attributes_page_types, class_name: 'BillyCms::AdditionalAttributesPageTypes'
|
4
6
|
has_many :additional_attributes, through: :additional_attributes_page_types
|
5
7
|
belongs_to :page
|
@@ -0,0 +1,48 @@
|
|
1
|
+
<div layout="row" layout-wrap>
|
2
|
+
<aside flex="30">
|
3
|
+
<md-list>
|
4
|
+
<md-list-item class="md-2-line" ng-repeat="pageType in app.allPageTypes" ng-click="ptctrl.selectPageType(pageType)" ng-class="{selected: pageType.id == ptctrl.selectedPageType.id}">
|
5
|
+
<div class="md-list-item-text" layout="column">
|
6
|
+
<h3>{{ pageType.title }}</h3>
|
7
|
+
<h4>{{ pageType.name }}</h4>
|
8
|
+
</div>
|
9
|
+
</md-list-item>
|
10
|
+
</md-list>
|
11
|
+
</aside>
|
12
|
+
<form flex="70" ng-show="ptctrl.selectedPageType" ng-submit="ptctrl.savePageType(ptctrl.selectedPageType)">
|
13
|
+
<md-toolbar>
|
14
|
+
<div class="md-toolbar-tools">
|
15
|
+
<h3>
|
16
|
+
<span>{{ptctrl.selectedPageType.title}}</span>
|
17
|
+
</h3>
|
18
|
+
</div>
|
19
|
+
</md-toolbar>
|
20
|
+
<md-content>
|
21
|
+
<md-input-container class="md-block">
|
22
|
+
<label>ID: {{ptctrl.selectedPageType.id}}</label>
|
23
|
+
</md-input-container>
|
24
|
+
<md-input-container class="md-block">
|
25
|
+
<label>Titel</label>
|
26
|
+
<input type="text" ng-model="ptctrl.selectedPageType.title" />
|
27
|
+
</md-input-container>
|
28
|
+
<md-input-container class="md-block">
|
29
|
+
<label>Name</label>
|
30
|
+
<input type="text" ng-model="ptctrl.selectedPageType.name" />
|
31
|
+
</md-input-container>
|
32
|
+
</md-content>
|
33
|
+
<h2>
|
34
|
+
Zusätzliche Eigenschaften
|
35
|
+
</h2>
|
36
|
+
<md-input-container>
|
37
|
+
<label>Hinzufügen:</label>
|
38
|
+
<md-select ng-model="ptctrl.attributeToAdd">
|
39
|
+
<md-option ng-repeat="attribute in app.allAdditionalAttributes" value="{{attribute}}">{{attribute.title}}</md-option>
|
40
|
+
</md-select>
|
41
|
+
</md-input-container>
|
42
|
+
<ul>
|
43
|
+
<li ng-repeat="attribute in ptctrl.selectedPageType.additional_attributes">
|
44
|
+
{{attribute.title}}
|
45
|
+
</li>
|
46
|
+
</ul>
|
47
|
+
</form>
|
48
|
+
</div>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<%= render partial: 'tree' %>
|
7
7
|
</script>
|
8
8
|
<script type="text/ng-template" id="page_types/page_types.html">
|
9
|
-
|
9
|
+
<%= render partial: 'page_types' %>
|
10
10
|
</script>
|
11
11
|
<script type="text/ng-template" id="attributes/attributes.html">
|
12
12
|
<%= render partial: 'attributes' %>
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'friendly_id'
|
2
|
+
|
3
|
+
# FriendlyId Global Configuration
|
4
|
+
#
|
5
|
+
# Use this to set up shared configuration options for your entire application.
|
6
|
+
# Any of the configuration options shown here can also be applied to single
|
7
|
+
# models by passing arguments to the `friendly_id` class method or defining
|
8
|
+
# methods in your model.
|
9
|
+
#
|
10
|
+
# To learn more, check out the guide:
|
11
|
+
#
|
12
|
+
# http://norman.github.io/friendly_id/file.Guide.html
|
13
|
+
|
14
|
+
FriendlyId.defaults do |config|
|
15
|
+
# ## Reserved Words
|
16
|
+
#
|
17
|
+
# Some words could conflict with Rails's routes when used as slugs, or are
|
18
|
+
# undesirable to allow as slugs. Edit this list as needed for your app.
|
19
|
+
config.use :reserved
|
20
|
+
|
21
|
+
config.reserved_words = %w(new edit index session login logout users admin
|
22
|
+
stylesheets assets javascripts images)
|
23
|
+
|
24
|
+
# ## Friendly Finders
|
25
|
+
#
|
26
|
+
# Uncomment this to use friendly finders in all models. By default, if
|
27
|
+
# you wish to find a record by its friendly id, you must do:
|
28
|
+
#
|
29
|
+
# MyModel.friendly.find('foo')
|
30
|
+
#
|
31
|
+
# If you uncomment this, you can do:
|
32
|
+
#
|
33
|
+
# MyModel.find('foo')
|
34
|
+
#
|
35
|
+
# This is significantly more convenient but may not be appropriate for
|
36
|
+
# all applications, so you must explicity opt-in to this behavior. You can
|
37
|
+
# always also configure it on a per-model basis if you prefer.
|
38
|
+
#
|
39
|
+
# Something else to consider is that using the :finders addon boosts
|
40
|
+
# performance because it will avoid Rails-internal code that makes runtime
|
41
|
+
# calls to `Module.extend`.
|
42
|
+
#
|
43
|
+
# config.use :finders
|
44
|
+
#
|
45
|
+
# ## Slugs
|
46
|
+
#
|
47
|
+
# Most applications will use the :slugged module everywhere. If you wish
|
48
|
+
# to do so, uncomment the following line.
|
49
|
+
#
|
50
|
+
# config.use :slugged
|
51
|
+
#
|
52
|
+
# By default, FriendlyId's :slugged addon expects the slug column to be named
|
53
|
+
# 'slug', but you can change it if you wish.
|
54
|
+
#
|
55
|
+
# config.slug_column = 'slug'
|
56
|
+
#
|
57
|
+
# When FriendlyId can not generate a unique ID from your base method, it appends
|
58
|
+
# a UUID, separated by a single dash. You can configure the character used as the
|
59
|
+
# separator. If you're upgrading from FriendlyId 4, you may wish to replace this
|
60
|
+
# with two dashes.
|
61
|
+
#
|
62
|
+
# config.sequence_separator = '-'
|
63
|
+
#
|
64
|
+
# ## Tips and Tricks
|
65
|
+
#
|
66
|
+
# ### Controlling when slugs are generated
|
67
|
+
#
|
68
|
+
# As of FriendlyId 5.0, new slugs are generated only when the slug field is
|
69
|
+
# nil, but if you're using a column as your base method can change this
|
70
|
+
# behavior by overriding the `should_generate_new_friendly_id` method that
|
71
|
+
# FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave
|
72
|
+
# more like 4.0.
|
73
|
+
#
|
74
|
+
# config.use Module.new {
|
75
|
+
# def should_generate_new_friendly_id?
|
76
|
+
# slug.blank? || <your_column_name_here>_changed?
|
77
|
+
# end
|
78
|
+
# }
|
79
|
+
#
|
80
|
+
# FriendlyId uses Rails's `parameterize` method to generate slugs, but for
|
81
|
+
# languages that don't use the Roman alphabet, that's not usually sufficient.
|
82
|
+
# Here we use the Babosa library to transliterate Russian Cyrillic slugs to
|
83
|
+
# ASCII. If you use this, don't forget to add "babosa" to your Gemfile.
|
84
|
+
#
|
85
|
+
# config.use Module.new {
|
86
|
+
# def normalize_friendly_id(text)
|
87
|
+
# text.to_slug.normalize! :transliterations => [:russian, :latin]
|
88
|
+
# end
|
89
|
+
# }
|
90
|
+
end
|
data/lib/billy_cms/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: billy_cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- unsdrei GbR
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -127,11 +127,15 @@ files:
|
|
127
127
|
- app/assets/javascripts/billy_cms/backend.js
|
128
128
|
- app/assets/javascripts/billy_cms/backend/app.js.erb
|
129
129
|
- app/assets/javascripts/billy_cms/backend/attributes.js
|
130
|
-
- app/assets/javascripts/billy_cms/backend/
|
130
|
+
- app/assets/javascripts/billy_cms/backend/controllers/application.controller.js.erb
|
131
|
+
- app/assets/javascripts/billy_cms/backend/controllers/page_types.controller.js
|
132
|
+
- app/assets/javascripts/billy_cms/backend/directives/header.directive.js
|
131
133
|
- app/assets/javascripts/billy_cms/backend/directives/ng-jstree.js
|
134
|
+
- app/assets/javascripts/billy_cms/backend/factories/additional_attribute.js
|
135
|
+
- app/assets/javascripts/billy_cms/backend/factories/billy_object.js
|
136
|
+
- app/assets/javascripts/billy_cms/backend/factories/page_type.js
|
132
137
|
- app/assets/javascripts/billy_cms/backend/jstree.js
|
133
138
|
- app/assets/javascripts/billy_cms/backend/ngfileupload.js
|
134
|
-
- app/assets/javascripts/billy_cms/backend/page_type.js
|
135
139
|
- app/assets/javascripts/billy_cms/backend/ui-router.js
|
136
140
|
- app/assets/javascripts/billy_cms/frontend/api_connector.js
|
137
141
|
- app/assets/javascripts/billy_cms/frontend/editing.es6
|
@@ -166,12 +170,14 @@ files:
|
|
166
170
|
- app/views/billy_cms/_settings_page_button.html.erb
|
167
171
|
- app/views/billy_cms/backend/_attributes.html.erb
|
168
172
|
- app/views/billy_cms/backend/_header.html.erb
|
173
|
+
- app/views/billy_cms/backend/_page_types.html.erb
|
169
174
|
- app/views/billy_cms/backend/_tree.html.erb
|
170
175
|
- app/views/billy_cms/backend/index.html.erb
|
171
176
|
- billy_cms.gemspec
|
172
177
|
- bin/console
|
173
178
|
- bin/setup
|
174
179
|
- config/initializers/active_model_serializers.rb
|
180
|
+
- config/initializers/friendly_id.rb
|
175
181
|
- config/routes.rb
|
176
182
|
- lib/billy_cms.rb
|
177
183
|
- lib/billy_cms/version.rb
|
@@ -1,11 +0,0 @@
|
|
1
|
-
'use strict';
|
2
|
-
|
3
|
-
angular.module('BillyCmsBackend').factory('PageType', function() {
|
4
|
-
var PageType = function(options) {
|
5
|
-
this.id = options.id || null;
|
6
|
-
this.name = options.name || null;
|
7
|
-
this.title = options.title || '';
|
8
|
-
};
|
9
|
-
|
10
|
-
return PageType;
|
11
|
-
});
|
/data/app/assets/javascripts/billy_cms/backend/{billy_object.js → factories/billy_object.js}
RENAMED
File without changes
|