1
|
|
|
import fse from 'fs-extra' |
2
|
|
|
import {Promise} from 'bluebird' |
3
|
|
|
import path from 'path' |
4
|
|
|
import { |
5
|
|
|
config, |
6
|
|
|
Manager, |
7
|
|
|
coreUtils, |
8
|
|
|
cmsData, |
9
|
|
|
abeExtend, |
10
|
|
|
cmsTemplates |
11
|
|
|
} from '../../' |
12
|
|
|
import * as sourceAttr from '../../cms/editor/handlebars/sourceAttr' |
13
|
|
|
|
14
|
|
|
export function getTemplatesAndPartials(templatesPath, partialsPath) { |
15
|
|
|
let allFiles = [] |
16
|
|
|
var p = new Promise(resolve => { |
17
|
|
|
const extension = '.' + config.files.templates.extension |
18
|
|
|
return coreUtils.file |
19
|
|
|
.getFilesAsync(templatesPath, true, extension) |
20
|
|
|
.then(function(files) { |
21
|
|
|
allFiles = allFiles.concat(files) |
22
|
|
|
return coreUtils.file |
23
|
|
|
.getFilesAsync(partialsPath, true, extension) |
24
|
|
|
.then(function(files) { |
25
|
|
|
allFiles = allFiles.concat(files) |
26
|
|
|
return resolve(allFiles) |
27
|
|
|
}) |
28
|
|
|
}) |
29
|
|
|
}) |
30
|
|
|
|
31
|
|
|
return p |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
export function addOrder(text) { |
35
|
|
|
var regAbe = /{{abe[\S\s].*?key=['|"]([\S\s].*?['|"| ]}})/g |
36
|
|
|
var matches = text.match(regAbe) |
37
|
|
|
|
38
|
|
|
if (typeof matches !== 'undefined' && matches !== null) { |
39
|
|
|
var orderTab = [] |
40
|
|
|
var arrayKey = [] |
41
|
|
|
var max = 0 |
42
|
|
|
var negIndex = -1 |
43
|
|
|
|
44
|
|
|
// We create an array of keys/order and put -1 for keys without order |
45
|
|
|
Array.prototype.forEach.call(matches, match => { |
46
|
|
|
if (typeof match !== 'undefined' && match !== null) { |
47
|
|
|
var orderAttr = cmsData.regex.getAttr(match, 'order') |
48
|
|
|
var keyAttr = cmsData.regex.getAttr(match, 'key') |
49
|
|
|
if ( |
50
|
|
|
typeof orderAttr === 'undefined' || |
51
|
|
|
orderAttr === null || |
52
|
|
|
orderAttr === '' |
53
|
|
|
) { |
54
|
|
|
orderTab.push({key: keyAttr, order: negIndex}) |
55
|
|
|
negIndex = negIndex - 1 |
56
|
|
|
} else { |
57
|
|
|
max = Math.max(parseInt(orderAttr), max) |
58
|
|
|
orderTab.push({key: keyAttr, order: orderAttr}) |
59
|
|
|
} |
60
|
|
|
} |
61
|
|
|
}) |
62
|
|
|
|
63
|
|
|
// We sort the array |
64
|
|
|
orderTab.sort(coreUtils.sort.predicatBy('order', -1)) |
65
|
|
|
|
66
|
|
|
// And increment the not ordered ones beginning with the last order found + 1 |
67
|
|
|
Array.prototype.forEach.call(orderTab, obj => { |
68
|
|
|
if (obj.order < 0) { |
69
|
|
|
max = max + 1 |
70
|
|
|
arrayKey[obj.key] = max |
71
|
|
|
} else { |
72
|
|
|
arrayKey[obj.key] = parseInt(obj.order) |
73
|
|
|
} |
74
|
|
|
}) |
75
|
|
|
|
76
|
|
|
// Then we put order attribute to each abe tag not ordered |
77
|
|
|
Array.prototype.forEach.call(matches, match => { |
78
|
|
|
if (typeof match !== 'undefined' && match !== null) { |
79
|
|
|
var orderAttr = cmsData.regex.getAttr(match, 'order') |
80
|
|
|
var keyAttr = cmsData.regex.getAttr(match, 'key') |
81
|
|
|
if ( |
82
|
|
|
typeof orderAttr === 'undefined' || |
83
|
|
|
orderAttr === null || |
84
|
|
|
orderAttr === '' |
85
|
|
View Code Duplication |
) { |
|
|
|
|
86
|
|
|
var matchOrder = match.replace( |
87
|
|
|
/\}\}$/, |
88
|
|
|
` order='${arrayKey[keyAttr]}'}}` |
89
|
|
|
) |
90
|
|
|
text = text.replace(match, matchOrder) |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
}) |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
return text |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
export function getAbeImport(text) { |
100
|
|
|
var partials = [] |
101
|
|
|
let listReg = /({{abe.*type=[\'|\"]import.*}})/g |
102
|
|
|
var match |
103
|
|
|
while ((match = listReg.exec(text))) { |
104
|
|
|
partials.push(match[0]) |
105
|
|
|
} |
106
|
|
View Code Duplication |
|
|
|
|
|
107
|
|
|
return partials |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* it will include recursively each encountered type=import |
112
|
|
|
* and proceed to a foreach when the file={{some[]}} is an array of values |
113
|
|
|
* @param {[type]} text [description] |
114
|
|
|
* @param {[type]} json [description] |
115
|
|
|
* @return {[type]} [description] |
116
|
|
|
*/ |
117
|
|
|
export function includePartials(text, json) { |
118
|
|
|
var abeImports = cmsTemplates.template.getAbeImport(text) |
119
|
|
|
var duplicateImports = duplicateImports || [] |
|
|
|
|
120
|
|
|
|
121
|
|
|
Array.prototype.forEach.call(abeImports, abeImport => { |
122
|
|
|
var obj = cmsData.attributes.getAll(abeImport, {}) |
123
|
|
|
|
124
|
|
|
var file = obj.file |
125
|
|
|
var partial = '' |
126
|
|
|
if (file.charAt(0) == '/') { |
127
|
|
|
file = path.join(config.root, file) |
128
|
|
|
} else { |
129
|
|
|
file = path.join(Manager.instance.pathPartials, file) |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
file = cmsData.attributes.getValueFromAttribute(file, json) |
133
|
|
|
if (Object.prototype.toString.call(file) === '[object Array]') { |
134
|
|
|
Array.prototype.forEach.call(file, f => { |
135
|
|
|
if (coreUtils.file.exist(f)) { |
136
|
|
|
if (duplicateImports[f] != null) { |
137
|
|
|
var tmpFile = fse.readFileSync(f, 'utf8') |
138
|
|
|
var regAbe = /{{abe .*key=[\'|\"](.*?)[\'|\"].*}}/g |
139
|
|
|
var matches = tmpFile.match(regAbe) |
|
|
|
|
140
|
|
|
var match |
141
|
|
|
while ((match = regAbe.exec(tmpFile)) !== null) { |
142
|
|
|
if (match[1] != null) { |
143
|
|
|
tmpFile = tmpFile.replace( |
144
|
|
|
match[0], |
145
|
|
|
match[0].replace( |
146
|
|
|
match[1], |
147
|
|
|
match[1] + '_' + duplicateImports[f] |
148
|
|
|
) |
149
|
|
|
) |
150
|
|
|
tmpFile = tmpFile.replace( |
151
|
|
|
new RegExp(`\{\{${match[1]}`, 'g'), |
152
|
|
|
'{{' + match[1] + '_' + duplicateImports[f] |
153
|
|
|
) |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
duplicateImports[f] += 1 |
157
|
|
|
partial += cmsTemplates.template.includePartials(tmpFile, json) |
158
|
|
|
} else { |
159
|
|
|
duplicateImports[f] = 1 |
160
|
|
|
partial += cmsTemplates.template.includePartials( |
161
|
|
|
fse.readFileSync(f, 'utf8'), |
162
|
|
|
json |
163
|
|
|
) |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
}) |
167
|
|
|
} else { |
168
|
|
|
if (coreUtils.file.exist(file)) { |
169
|
|
|
if (duplicateImports[file] != null) { |
170
|
|
|
var tmpFile = fse.readFileSync(file, 'utf8') |
171
|
|
|
var regAbe = /{{abe .*key=[\'|\"](.*?)[\'|\"].*}}/g |
172
|
|
|
var match |
173
|
|
|
while ((match = regAbe.exec(tmpFile)) !== null) { |
174
|
|
|
if (match[1] != null) { |
175
|
|
|
tmpFile = tmpFile.replace( |
176
|
|
|
match[0], |
177
|
|
|
match[0].replace( |
178
|
|
|
match[1], |
179
|
|
|
match[1] + '_' + duplicateImports[file] |
180
|
|
|
) |
181
|
|
|
) |
182
|
|
|
tmpFile = tmpFile.replace( |
183
|
|
|
new RegExp(`\{\{${match[1]}`, 'g'), |
184
|
|
|
'{{' + match[1] + '_' + duplicateImports[file] |
185
|
|
|
) |
186
|
|
|
} |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
duplicateImports[file] += 1 |
190
|
|
|
partial = cmsTemplates.template.includePartials(tmpFile, json) |
191
|
|
|
} else { |
192
|
|
|
duplicateImports[file] = 1 |
193
|
|
|
partial = cmsTemplates.template.includePartials( |
194
|
|
|
fse.readFileSync(file, 'utf8'), |
195
|
|
|
json |
196
|
|
|
) |
197
|
|
|
} |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
text = text.replace(cmsData.regex.escapeTextToRegex(abeImport), partial) |
201
|
|
|
}) |
202
|
|
|
|
203
|
|
|
return text |
204
|
|
|
} |
205
|
|
|
|
206
|
|
|
export function translate(text) { |
207
|
|
|
var importReg = /({{abe.*type=[\'|\"]translate.*}})/g |
208
|
|
|
|
209
|
|
|
var matches = text.match(importReg) |
210
|
|
|
|
211
|
|
|
if (typeof matches !== 'undefined' && matches !== null) { |
212
|
|
|
Array.prototype.forEach.call(matches, match => { |
213
|
|
|
var splitedMatches = match.split('{{abe ') |
214
|
|
|
|
215
|
|
|
Array.prototype.forEach.call(splitedMatches, splitedMatch => { |
216
|
|
|
var currentMatch = `{{abe ${splitedMatch}` |
217
|
|
|
if (/({{abe.*type=[\'|\"]translate.*}})/.test(currentMatch)) { |
218
|
|
|
var locale = cmsData.regex.getAttr(currentMatch, 'locale') |
219
|
|
|
var source = cmsData.regex.getAttr(currentMatch, 'source') |
220
|
|
|
|
221
|
|
|
var replace = `{{{i18nAbe "${locale}" "${source}" this}}}` |
222
|
|
|
|
223
|
|
|
text = text.replace( |
224
|
|
|
cmsData.regex.escapeTextToRegex(currentMatch, 'g'), |
225
|
|
|
replace |
226
|
|
|
) |
227
|
|
|
} |
228
|
|
|
}) |
229
|
|
|
}) |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
return text |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
export function getTemplate(file, json = {}) { |
236
|
|
|
var text = '' |
237
|
|
|
|
238
|
|
|
// HOOKS beforeGetTemplate |
239
|
|
|
file = abeExtend.hooks.instance.trigger('beforeGetTemplate', file) |
240
|
|
|
|
241
|
|
|
file = file.replace(Manager.instance.pathTemplates, '') |
242
|
|
|
file = file.replace(config.root, '') |
243
|
|
|
if (file.indexOf('.') > -1) { |
244
|
|
|
file = file.replace(/\..+$/, '') |
245
|
|
|
} |
246
|
|
|
file = path.join( |
247
|
|
|
Manager.instance.pathTemplates, |
248
|
|
|
file + '.' + config.files.templates.extension |
249
|
|
|
) |
250
|
|
|
if (coreUtils.file.exist(file)) { |
251
|
|
|
text = fse.readFileSync(file, 'utf8') |
252
|
|
|
text = cmsTemplates.template.includePartials(text, json) |
253
|
|
|
text = cmsTemplates.template.translate(text) |
254
|
|
|
text = cmsTemplates.template.addOrder(text) |
255
|
|
|
} else { |
256
|
|
|
text = `[ ERROR ] template ${file} doesn't exist anymore` |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
// HOOKS afterGetTemplate |
260
|
|
|
text = abeExtend.hooks.instance.trigger('afterGetTemplate', text) |
261
|
|
|
|
262
|
|
|
return text |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
export function getVariablesInWhere(where) { |
266
|
|
|
var ar = [] |
267
|
|
|
|
268
|
|
|
if (where.left.column.indexOf('{{') > -1) { |
269
|
|
|
ar.push(where.left.column.replace(/\{\{(.*?)\}\}/, '$1')) |
270
|
|
|
} else { |
271
|
|
|
ar.push(where.left.column) |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
if (where.right.value) { |
275
|
|
|
if (typeof where.right.value === 'string') { |
276
|
|
|
if (where.right.value && where.right.value.indexOf('{{') > -1) { |
277
|
|
|
ar.push(where.right.value.replace(/\{\{(.*?)\}\}/, '$1')) |
278
|
|
|
} |
279
|
|
|
} else { |
280
|
|
|
where.right.value.forEach(function(value) { |
281
|
|
|
if (value.column.indexOf('{{') > -1) { |
282
|
|
|
ar.push(value.column.replace(/\{\{(.*?)\}\}/, '$1')) |
283
|
|
|
} |
284
|
|
|
}) |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
if (where.right.column && where.right.column.indexOf('{{') > -1) { |
289
|
|
|
ar.push(where.right.column.replace(/\{\{(.*?)\}\}/, '$1')) |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
return ar |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* Get columns and where.left ids of a select statement |
297
|
|
|
* |
298
|
|
|
* select title, image from ../ where template="" |
299
|
|
|
* |
300
|
|
|
* return [title, image, template] |
301
|
|
|
* |
302
|
|
|
* @param {Array} templatesList ["article.html", "other.html"] |
|
|
|
|
303
|
|
|
* @return {Promise} |
304
|
|
|
*/ |
305
|
|
|
export function recurseWhereVariables(where) { |
306
|
|
|
var ar = [] |
|
|
|
|
307
|
|
|
var arLeft |
308
|
|
|
var arRight |
309
|
|
|
switch (where.operator) { |
310
|
|
|
case 'AND': |
311
|
|
|
arLeft = cmsTemplates.template.recurseWhereVariables(where.left) |
312
|
|
|
arRight = cmsTemplates.template.recurseWhereVariables(where.right) |
313
|
|
|
return arLeft.concat(arRight) |
314
|
|
|
break |
|
|
|
|
315
|
|
|
case 'OR': |
316
|
|
|
arLeft = cmsTemplates.template.recurseWhereVariables(where.left) |
317
|
|
|
arRight = cmsTemplates.template.recurseWhereVariables(where.right) |
318
|
|
|
return arLeft.concat(arRight) |
319
|
|
|
break |
|
|
|
|
320
|
|
|
default: |
321
|
|
|
ar = getVariablesInWhere(where) |
322
|
|
|
break |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
return ar |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
export function getTemplatesTexts(templatesList, json) { |
329
|
|
|
var templates = [] |
330
|
|
|
var p = new Promise(resolve => { |
331
|
|
|
Array.prototype.forEach.call(templatesList, file => { |
332
|
|
|
var template = fse.readFileSync(file, 'utf8') |
333
|
|
|
template = cmsTemplates.template.includePartials(template, json) |
334
|
|
|
var name = file |
335
|
|
|
.replace(path.join(Manager.instance.pathTemplates, path.sep), '') |
336
|
|
|
.replace(`.${config.files.templates.extension}`, '') |
337
|
|
|
templates.push({ |
338
|
|
|
name: name, |
339
|
|
|
path: file, |
340
|
|
|
template: template |
341
|
|
|
}) |
342
|
|
|
}) |
343
|
|
|
resolve(templates) |
344
|
|
|
}) |
345
|
|
|
|
346
|
|
|
return p |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
export function execRequestColumns(tpl) { |
350
|
|
|
var ar = [] |
351
|
|
|
var matches = cmsData.regex.getTagAbeTypeRequest(tpl) |
352
|
|
|
Array.prototype.forEach.call(matches, match => { |
353
|
|
|
var obj = cmsData.attributes.getAll(match[0], {}) |
354
|
|
|
var type = cmsData.sql.getSourceType(obj.sourceString) |
355
|
|
|
switch (type) { |
|
|
|
|
356
|
|
|
case 'request': |
357
|
|
|
var request = cmsData.sql.handleSqlRequest(obj.sourceString, {}) |
358
|
|
|
if ( |
359
|
|
|
typeof request.columns !== 'undefined' && |
360
|
|
|
request.columns !== null |
361
|
|
|
) { |
362
|
|
|
Array.prototype.forEach.call(request.columns, column => { |
363
|
|
|
ar.push(column) |
364
|
|
|
}) |
365
|
|
|
} |
366
|
|
|
if (typeof request.where !== 'undefined' && request.where !== null) { |
367
|
|
|
ar = ar.concat( |
368
|
|
|
cmsTemplates.template.recurseWhereVariables(request.where) |
369
|
|
|
) |
370
|
|
|
} |
371
|
|
|
} |
372
|
|
|
}) |
373
|
|
|
|
374
|
|
|
return ar |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
export function getAbeRequestWhereKeysFromTemplates(templatesList) { |
378
|
|
|
var whereKeys = [] |
379
|
|
|
var p = new Promise(resolve => { |
380
|
|
|
Array.prototype.forEach.call(templatesList, file => { |
381
|
|
|
whereKeys = whereKeys.concat( |
382
|
|
|
cmsTemplates.template.execRequestColumns(file.template) |
383
|
|
|
) |
384
|
|
|
}) |
385
|
|
|
whereKeys = whereKeys.filter(function(item, pos) { |
386
|
|
|
item = item.split('.')[0].split('[')[0] |
387
|
|
|
return whereKeys.indexOf(item) == pos |
388
|
|
|
}) |
389
|
|
|
resolve(whereKeys) |
390
|
|
|
}) |
391
|
|
|
|
392
|
|
|
return p |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
export function setAbeSlugDefaultValueIfDoesntExist(templateText) { |
396
|
|
|
var matches = cmsData.regex.getTagAbeWithType(templateText, 'slug') |
397
|
|
|
if (matches == null || matches[0] == null) { |
398
|
|
|
templateText = `{{abe type="slug" source="{{name}}"}}\n${templateText}` |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
return templateText |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
export function getAbeSlugFromTemplates(templatesList) { |
405
|
|
|
var slugs = {} |
406
|
|
|
Array.prototype.forEach.call(templatesList, file => { |
407
|
|
|
var templateText = cmsTemplates.template.setAbeSlugDefaultValueIfDoesntExist( |
408
|
|
|
file.template |
409
|
|
|
) |
410
|
|
|
var matchesSlug = cmsData.regex.getTagAbeWithType(templateText, 'slug') |
411
|
|
|
var obj = cmsData.attributes.getAll(matchesSlug[0], {}) |
412
|
|
|
slugs[file.name] = obj.sourceString |
413
|
|
|
}) |
414
|
|
|
return slugs |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* if there is no abe tab='slug' in the template, add a default abe tag |
419
|
|
|
* @param {[type]} templateText [description] |
420
|
|
|
*/ |
421
|
|
|
export function setAbePrecontribDefaultValueIfDoesntExist(templateText) { |
422
|
|
|
var matches = cmsData.regex.getTagAbeWithTab(templateText, 'slug') |
423
|
|
|
if (matches == null || matches[0] == null) { |
424
|
|
|
templateText = `{{abe type='text' key='name' desc='Name' required="true" tab="slug" visible="false"}}\n${templateText}` |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
return templateText |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
/** |
431
|
|
|
* Lists all templates, in each template: |
432
|
|
|
* if no tab='slug' replaces the template with default tag {{abe type='text' key='name'...}} |
433
|
|
|
* then removes all abe tags (but the tab='slug' ones) |
434
|
|
|
* then adds 'precontribTemplate' with the template name as an attribute to tab='slug' tags |
435
|
|
|
* @param {Array} templatesList [description] |
436
|
|
|
* @return {Array} [description] |
437
|
|
|
*/ |
438
|
|
|
export function getAbePrecontribFromTemplates(templatesList) { |
439
|
|
|
var precontributionTemplate = [] |
440
|
|
|
|
441
|
|
|
Array.prototype.forEach.call(templatesList, file => { |
442
|
|
|
var templateText = cmsTemplates.template.setAbePrecontribDefaultValueIfDoesntExist( |
443
|
|
|
file.template |
444
|
|
|
) |
445
|
|
|
templateText = templateText.replace( |
446
|
|
|
/(?!.*?tab=['|"]slug)(\{\{abe.+.*\}\})/g, |
447
|
|
|
'' |
448
|
|
|
) |
449
|
|
|
templateText = templateText.replace( |
450
|
|
|
/(\{\{abe.+)(\}\})/g, |
451
|
|
|
`$1 precontribTemplate="${file.name}"$2` |
452
|
|
|
) |
453
|
|
|
precontributionTemplate.push(templateText) |
454
|
|
|
}) |
455
|
|
|
|
456
|
|
|
return precontributionTemplate |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
export function getStructureAndTemplates() { |
460
|
|
|
const extension = '.' + config.files.templates.extension |
461
|
|
|
let result = {structure: [], templates: []} |
462
|
|
|
|
463
|
|
|
result.structure = coreUtils.file.getFoldersSync( |
464
|
|
|
Manager.instance.pathStructure, |
465
|
|
|
true |
466
|
|
|
) |
467
|
|
|
let templatePaths = coreUtils.file.getFilesSync( |
468
|
|
|
Manager.instance.pathTemplates, |
469
|
|
|
true, |
470
|
|
|
extension |
471
|
|
|
) |
472
|
|
|
Array.prototype.forEach.call(templatePaths, templatePath => { |
473
|
|
|
let additionalPath = path |
474
|
|
|
.dirname(templatePath) |
475
|
|
|
.replace(Manager.instance.pathTemplates, '') |
476
|
|
|
if (additionalPath !== '') additionalPath = additionalPath.substring(1) |
|
|
|
|
477
|
|
|
let name = path.join(additionalPath, path.basename(templatePath, extension)) |
478
|
|
|
let template = {path: templatePath, name: name} |
479
|
|
|
result.templates.push(template) |
480
|
|
|
}) |
481
|
|
|
|
482
|
|
|
return result |
483
|
|
|
} |
484
|
|
|
|