1 | var _ = require('lodash');
|
2 | var async = require('async');
|
3 |
|
4 | module.exports = blocks;
|
5 |
|
6 | function blocks(options, callback) {
|
7 | return new blocks.Blocks(options, callback);
|
8 | }
|
9 |
|
10 | function Blocks(options, callback) {
|
11 | var self = this;
|
12 | self._app = options.app;
|
13 | self._apos = options.apos;
|
14 | self._pages = options.pages;
|
15 | self._types = options.types;
|
16 | self._action = '/apos-blocks';
|
17 |
|
18 |
|
19 | self._apos.mixinModuleAssets(self, 'blocks', __dirname, options);
|
20 |
|
21 | self.pushAsset('script', 'editor', { when: 'user' });
|
22 | self.pushAsset('stylesheet', 'editor', { when: 'user' });
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | self._apos.addLocal('aposBlocks', function() {
|
39 | var options = {};
|
40 | if (!arguments.length) {
|
41 | throw new Error('You must pass at least one argument to aposBlocks. Typical usage is aposBlocks(page, "body", [ "blockTypeOne", "blockTypeTwo"]).');
|
42 | }
|
43 | if (arguments.length === 1) {
|
44 | options = arguments[0];
|
45 | } else {
|
46 | options.page = arguments[0];
|
47 | options.group = arguments[1];
|
48 | if (arguments[2]) {
|
49 | if (Array.isArray(arguments[2])) {
|
50 | options.types = arguments[2];
|
51 | if (arguments[3]) {
|
52 | _.extend(options, arguments[3]);
|
53 | }
|
54 | } else {
|
55 | _.extend(options, arguments[2]);
|
56 | }
|
57 | }
|
58 | }
|
59 | var data = {};
|
60 | _.extend(data, options);
|
61 | data.blocks = (options.page.blockGroups && options.page.blockGroups[options.group] && options.page.blockGroups[options.group].blocks) || [];
|
62 | data.types = _.filter(self._types, function(type) {
|
63 | return _.contains(options.types, type.name);
|
64 | });
|
65 | data.groupLabel = options.groupLabel;
|
66 | return self.render('blocks', data);
|
67 | });
|
68 |
|
69 | self._app.post(self._action + '/new', function(req, res) {
|
70 | var page;
|
71 | var result;
|
72 | var group = self._apos.sanitizeString(req.body.group);
|
73 | var type = self._apos.sanitizeString(req.body.type);
|
74 | var id = self._apos.generateId();
|
75 | var slug = self._apos.sanitizeString(req.body.slug);
|
76 | if (!type) {
|
77 | return res.send({ status: 'invalid' });
|
78 | }
|
79 | var typeConfig = _.find(self._types, function(typeConfig) {
|
80 | return typeConfig.name === type;
|
81 | });
|
82 | if (!typeConfig) {
|
83 | return res.send({ status: 'nosuchblock' });
|
84 | }
|
85 | return async.series({
|
86 | get: function(callback) {
|
87 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
88 | if (err) {
|
89 | console.log(err);
|
90 | return callback('error');
|
91 | }
|
92 | if (!_page) {
|
93 | return callback('notfound');
|
94 | }
|
95 | page = _page;
|
96 | return callback(null);
|
97 | });
|
98 | },
|
99 | render: function(callback) {
|
100 | result = {
|
101 | status: 'ok',
|
102 | type: type,
|
103 | id: id,
|
104 | html: self.render(type, {
|
105 | page: page,
|
106 | type: type,
|
107 | group: group,
|
108 |
|
109 |
|
110 | user: req.user,
|
111 | permissions: (req.user && req.user.permissions) || {},
|
112 | id: id,
|
113 | prefix: group + '_' + id + '_'
|
114 | }, req)
|
115 | };
|
116 | return callback(null);
|
117 | },
|
118 | insert: function(callback) {
|
119 | if (!page.blockGroups) {
|
120 | page.blockGroups = {};
|
121 | }
|
122 | if (!page.blockGroups[group]) {
|
123 | page.blockGroups[group] = {
|
124 | blocks: []
|
125 | };
|
126 | }
|
127 | page.blockGroups[group].blocks.push({
|
128 | type: type,
|
129 | id: id
|
130 | });
|
131 | return self._apos.putPage(req, slug, page, callback);
|
132 | }
|
133 | }, function(err) {
|
134 | if (err) {
|
135 | return res.send({ status: err });
|
136 | }
|
137 | return res.send(result);
|
138 | });
|
139 | });
|
140 |
|
141 | self._app.post(self._action + '/switch', function(req, res) {
|
142 | var page;
|
143 | var result;
|
144 | var group = self._apos.sanitizeString(req.body.group);
|
145 | var type = self._apos.sanitizeString(req.body.type);
|
146 | var id = self._apos.sanitizeId(req.body.id);
|
147 | var slug = self._apos.sanitizeString(req.body.slug);
|
148 | if (!type) {
|
149 | return res.send({ status: 'invalid' });
|
150 | }
|
151 | var typeConfig = _.find(self._types, function(typeConfig) {
|
152 | return typeConfig.name === type;
|
153 | });
|
154 | if (!typeConfig) {
|
155 | return res.send({ status: 'nosuchblock' });
|
156 | }
|
157 | return async.series({
|
158 | get: function(callback) {
|
159 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
160 | if (err) {
|
161 | console.log(err);
|
162 | return callback('error');
|
163 | }
|
164 | if (!_page) {
|
165 | return callback('notfound');
|
166 | }
|
167 | page = _page;
|
168 | return callback(null);
|
169 | });
|
170 | },
|
171 | render: function(callback) {
|
172 | result = {
|
173 | status: 'ok',
|
174 | type: type,
|
175 | id: id,
|
176 | html: self.render(type, {
|
177 | page: page,
|
178 | type: type,
|
179 | group: group,
|
180 | id: id,
|
181 | prefix: group + '_' + id + '_'
|
182 | }, req)
|
183 | };
|
184 | return callback(null);
|
185 | },
|
186 | update: function(callback) {
|
187 | _.each(page.blockGroups[group].blocks, function(block) {
|
188 | if (block.id === id) {
|
189 | block.type = type;
|
190 | }
|
191 | });
|
192 | return self._apos.putPage(req, slug, page, callback);
|
193 | }
|
194 | }, function(err) {
|
195 | if (err) {
|
196 | return res.send({ status: err });
|
197 | }
|
198 | return res.send(result);
|
199 | });
|
200 | });
|
201 |
|
202 | self._app.post(self._action + '/remove', function(req, res) {
|
203 | var group = self._apos.sanitizeString(req.body.group);
|
204 | var id = self._apos.sanitizeId(req.body.id);
|
205 | var slug = self._apos.sanitizeString(req.body.slug);
|
206 | return async.series({
|
207 | get: function(callback) {
|
208 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
209 | if (err) {
|
210 | console.log(err);
|
211 | return callback('error');
|
212 | }
|
213 | if (!_page) {
|
214 | return callback('notfound');
|
215 | }
|
216 | page = _page;
|
217 | return callback(null);
|
218 | });
|
219 | },
|
220 | remove: function(callback) {
|
221 | if (!page.blockGroups) {
|
222 | return callback('notfound');
|
223 | }
|
224 | if (!page.blockGroups[group]) {
|
225 | return callback('notfound');
|
226 | }
|
227 |
|
228 | page.blockGroups[group].blocks = _.filter(page.blockGroups[group].blocks, function(block) {
|
229 | return (block.id !== id);
|
230 | });
|
231 | return self._apos.putPage(req, slug, page, callback);
|
232 | }
|
233 | }, function(err) {
|
234 | if (err) {
|
235 | return res.send({ status: err });
|
236 | }
|
237 | return res.send({ status: 'ok' });
|
238 | });
|
239 | });
|
240 |
|
241 | self._app.post(self._action + '/order', function(req, res) {
|
242 | var group = self._apos.sanitizeString(req.body.group);
|
243 | var ids = self._apos.sanitizeIds(req.body.ids);
|
244 | var slug = self._apos.sanitizeString(req.body.slug);
|
245 | return async.series({
|
246 | get: function(callback) {
|
247 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
248 | if (err) {
|
249 | console.log(err);
|
250 | return callback('error');
|
251 | }
|
252 | if (!_page) {
|
253 | return callback('notfound');
|
254 | }
|
255 | page = _page;
|
256 | return callback(null);
|
257 | });
|
258 | },
|
259 | update: function(callback) {
|
260 | if (!page.blockGroups) {
|
261 | return callback('notfound');
|
262 | }
|
263 | if (!page.blockGroups[group]) {
|
264 | return callback('notfound');
|
265 | }
|
266 | page.blockGroups[group].blocks = self._apos.orderById(ids, page.blockGroups[group].blocks, 'id');
|
267 | return self._apos.putPage(req, slug, page, callback);
|
268 | }
|
269 | }, function(err) {
|
270 | if (err) {
|
271 | return res.send({ status: err });
|
272 | }
|
273 | return res.send({ status: 'ok' });
|
274 | });
|
275 | });
|
276 |
|
277 |
|
278 |
|
279 | self._apos.on('diff', function(page, lines) {
|
280 | _.each(page.blockGroups || {}, function(value, group) {
|
281 | var prefix = group + ' block: ';
|
282 | _.each(value.blocks, function(block) {
|
283 | lines.push(prefix + block.type);
|
284 | });
|
285 | });
|
286 | });
|
287 |
|
288 | return process.nextTick(function() {
|
289 | return callback(null);
|
290 | });
|
291 | }
|
292 |
|
293 | blocks.Blocks = Blocks;
|