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 | _.merge(options, arguments[3]);
|
53 | }
|
54 | } else {
|
55 | _.merge(options, arguments[2]);
|
56 | }
|
57 | }
|
58 | }
|
59 | var data = {};
|
60 | _.merge(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 | return self.render('blocks', data);
|
66 | });
|
67 |
|
68 | self._app.post(self._action + '/new', function(req, res) {
|
69 | var page;
|
70 | var result;
|
71 | var group = self._apos.sanitizeString(req.body.group);
|
72 | var type = self._apos.sanitizeString(req.body.type);
|
73 | var id = self._apos.generateId();
|
74 | var slug = self._apos.sanitizeString(req.body.slug);
|
75 | if (!type) {
|
76 | return res.send({ status: 'invalid' });
|
77 | }
|
78 | var typeConfig = _.find(self._types, function(typeConfig) {
|
79 | return typeConfig.name === type;
|
80 | });
|
81 | if (!typeConfig) {
|
82 | return res.send({ status: 'nosuchblock' });
|
83 | }
|
84 | return async.series({
|
85 | get: function(callback) {
|
86 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
87 | if (err) {
|
88 | console.log(err);
|
89 | return callback('error');
|
90 | }
|
91 | if (!_page) {
|
92 | return callback('notfound');
|
93 | }
|
94 | page = _page;
|
95 | return callback(null);
|
96 | });
|
97 | },
|
98 | render: function(callback) {
|
99 | result = {
|
100 | status: 'ok',
|
101 | type: type,
|
102 | id: id,
|
103 | html: self.render(type, {
|
104 | page: page,
|
105 | type: type,
|
106 | group: group,
|
107 |
|
108 |
|
109 | user: req.user,
|
110 | permissions: (req.user && req.user.permissions) || {},
|
111 | id: id,
|
112 | prefix: group + '_' + id + '_'
|
113 | }, req)
|
114 | };
|
115 | return callback(null);
|
116 | },
|
117 | insert: function(callback) {
|
118 | if (!page.blockGroups) {
|
119 | page.blockGroups = {};
|
120 | }
|
121 | if (!page.blockGroups[group]) {
|
122 | page.blockGroups[group] = {
|
123 | blocks: []
|
124 | };
|
125 | }
|
126 | page.blockGroups[group].blocks.push({
|
127 | type: type,
|
128 | id: id
|
129 | });
|
130 | return self._apos.putPage(req, slug, page, callback);
|
131 | }
|
132 | }, function(err) {
|
133 | if (err) {
|
134 | return res.send({ status: err });
|
135 | }
|
136 | return res.send(result);
|
137 | });
|
138 | });
|
139 |
|
140 | self._app.post(self._action + '/switch', function(req, res) {
|
141 | var page;
|
142 | var result;
|
143 | var group = self._apos.sanitizeString(req.body.group);
|
144 | var type = self._apos.sanitizeString(req.body.type);
|
145 | var id = self._apos.sanitizeId(req.body.id);
|
146 | var slug = self._apos.sanitizeString(req.body.slug);
|
147 | if (!type) {
|
148 | return res.send({ status: 'invalid' });
|
149 | }
|
150 | var typeConfig = _.find(self._types, function(typeConfig) {
|
151 | return typeConfig.name === type;
|
152 | });
|
153 | if (!typeConfig) {
|
154 | return res.send({ status: 'nosuchblock' });
|
155 | }
|
156 | return async.series({
|
157 | get: function(callback) {
|
158 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
159 | if (err) {
|
160 | console.log(err);
|
161 | return callback('error');
|
162 | }
|
163 | if (!_page) {
|
164 | return callback('notfound');
|
165 | }
|
166 | page = _page;
|
167 | return callback(null);
|
168 | });
|
169 | },
|
170 | render: function(callback) {
|
171 | result = {
|
172 | status: 'ok',
|
173 | type: type,
|
174 | id: id,
|
175 | html: self.render(type, {
|
176 | page: page,
|
177 | type: type,
|
178 | group: group,
|
179 | id: id,
|
180 | prefix: group + '_' + id + '_'
|
181 | }, req)
|
182 | };
|
183 | return callback(null);
|
184 | },
|
185 | update: function(callback) {
|
186 | _.each(page.blockGroups[group].blocks, function(block) {
|
187 | if (block.id === id) {
|
188 | block.type = type;
|
189 | }
|
190 | });
|
191 | return self._apos.putPage(req, slug, page, callback);
|
192 | }
|
193 | }, function(err) {
|
194 | if (err) {
|
195 | return res.send({ status: err });
|
196 | }
|
197 | return res.send(result);
|
198 | });
|
199 | });
|
200 |
|
201 | self._app.post(self._action + '/remove', function(req, res) {
|
202 | var group = self._apos.sanitizeString(req.body.group);
|
203 | var id = self._apos.sanitizeId(req.body.id);
|
204 | var slug = self._apos.sanitizeString(req.body.slug);
|
205 | return async.series({
|
206 | get: function(callback) {
|
207 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
208 | if (err) {
|
209 | console.log(err);
|
210 | return callback('error');
|
211 | }
|
212 | if (!_page) {
|
213 | return callback('notfound');
|
214 | }
|
215 | page = _page;
|
216 | return callback(null);
|
217 | });
|
218 | },
|
219 | remove: function(callback) {
|
220 | if (!page.blockGroups) {
|
221 | return callback('notfound');
|
222 | }
|
223 | if (!page.blockGroups[group]) {
|
224 | return callback('notfound');
|
225 | }
|
226 |
|
227 | page.blockGroups[group].blocks = _.filter(page.blockGroups[group].blocks, function(block) {
|
228 | return (block.id !== id);
|
229 | });
|
230 | return self._apos.putPage(req, slug, page, callback);
|
231 | }
|
232 | }, function(err) {
|
233 | if (err) {
|
234 | return res.send({ status: err });
|
235 | }
|
236 | return res.send({ status: 'ok' });
|
237 | });
|
238 | });
|
239 |
|
240 | self._app.post(self._action + '/order', function(req, res) {
|
241 | var group = self._apos.sanitizeString(req.body.group);
|
242 | var ids = self._apos.sanitizeIds(req.body.ids);
|
243 | var slug = self._apos.sanitizeString(req.body.slug);
|
244 | return async.series({
|
245 | get: function(callback) {
|
246 | return self._apos.getPage(req, slug, {}, function(err, _page) {
|
247 | if (err) {
|
248 | console.log(err);
|
249 | return callback('error');
|
250 | }
|
251 | if (!_page) {
|
252 | return callback('notfound');
|
253 | }
|
254 | page = _page;
|
255 | return callback(null);
|
256 | });
|
257 | },
|
258 | update: function(callback) {
|
259 | if (!page.blockGroups) {
|
260 | return callback('notfound');
|
261 | }
|
262 | if (!page.blockGroups[group]) {
|
263 | return callback('notfound');
|
264 | }
|
265 | page.blockGroups[group].blocks = self._apos.orderById(ids, page.blockGroups[group].blocks, 'id');
|
266 | return self._apos.putPage(req, slug, page, callback);
|
267 | }
|
268 | }, function(err) {
|
269 | if (err) {
|
270 | return res.send({ status: err });
|
271 | }
|
272 | return res.send({ status: 'ok' });
|
273 | });
|
274 | });
|
275 |
|
276 |
|
277 |
|
278 | self._apos.on('diff', function(page, lines) {
|
279 | _.each(page.blockGroups || {}, function(value, group) {
|
280 | var prefix = group + ' block: ';
|
281 | _.each(value.blocks, function(block) {
|
282 | lines.push(prefix + block.type);
|
283 | });
|
284 | });
|
285 | });
|
286 |
|
287 | return process.nextTick(function() {
|
288 | return callback(null);
|
289 | });
|
290 | }
|
291 |
|
292 | blocks.Blocks = Blocks;
|