@reldens/cms 0.52.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/architecture-guide.md +450 -0
- package/.claude/security-guide.md +102 -0
- package/.claude/seo-guide.md +167 -0
- package/.claude/templating-system-guide.md +29 -0
- package/CLAUDE.md +93 -550
- package/bin/reldens-cms-generate-entities.js +0 -1
- package/install/index.html +4 -0
- package/lib/admin-manager/router-contents.js +1 -0
- package/lib/frontend/content-renderer.js +1 -0
- package/lib/frontend/template-cache.js +1 -1
- package/lib/frontend/template-resolver.js +7 -2
- package/lib/frontend.js +38 -6
- package/lib/manager.js +11 -1
- package/lib/mysql-installer.js +2 -1
- package/lib/sitemap-loader.js +101 -0
- package/lib/template-engine/collections-transformer.js +43 -6
- package/lib/template-engine.js +1 -5
- package/migrations/default-blocks.sql +1 -1
- package/migrations/default-entity-access.sql +1 -1
- package/migrations/default-forms.sql +0 -1
- package/migrations/default-homepage.sql +7 -7
- package/migrations/default-sitemaps-and-robots.sql +44 -0
- package/migrations/default-user.sql +1 -1
- package/migrations/users-authentication.sql +1 -1
- package/package.json +3 -4
- package/templates/layouts/raw.html +1 -0
- package/templates/raw.html +1 -0
- package/templates/robots.txt +3 -0
- package/templates/sitemap.xml +9 -0
- package/.claude/sitemap-generator-guide.md +0 -511
- package/bin/reldens-cms-generate-sitemap.js +0 -149
- package/lib/sitemap-generator.js +0 -181
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
const { Manager } = require('../index');
|
|
10
10
|
const { PrismaClientLoader } = require('@reldens/storage');
|
|
11
11
|
const { Logger, sc } = require('@reldens/utils');
|
|
12
|
-
const { FileHandler } = require('@reldens/server-utils');
|
|
13
12
|
const readline = require('readline');
|
|
14
13
|
|
|
15
14
|
class CmsEntitiesGenerator
|
package/install/index.html
CHANGED
|
@@ -109,6 +109,10 @@
|
|
|
109
109
|
<input type="checkbox" name="install-dynamic-forms" id="install-dynamic-forms" checked/>
|
|
110
110
|
<label for="install-dynamic-forms">Install dynamic forms system</label>
|
|
111
111
|
</div>
|
|
112
|
+
<div class="input-box input-checkbox install-seo-files">
|
|
113
|
+
<input type="checkbox" name="install-seo-files" id="install-seo-files" checked/>
|
|
114
|
+
<label for="install-seo-files">Install default robots.txt and sitemap.xml</label>
|
|
115
|
+
</div>
|
|
112
116
|
<div class="input-box submit-container">
|
|
113
117
|
<input id="install-submit-button" type="submit" value="Install"/>
|
|
114
118
|
<img class="install-loading hidden" src="/install-assets/img/loading.gif"/>
|
|
@@ -248,6 +248,7 @@ class RouterContents
|
|
|
248
248
|
let loadedEntities = await entityRepository.load(idsFilter);
|
|
249
249
|
await this.deleteEntitiesRelatedFiles(driverResource, loadedEntities);
|
|
250
250
|
let deleteResult = await entityRepository.delete(idsFilter);
|
|
251
|
+
await this.emitEvent('reldens.adminAfterEntityDelete', {driverResource, idProperty, ids});
|
|
251
252
|
return redirectPath + (deleteResult ? 'success' : 'errorStorageFailure');
|
|
252
253
|
} catch (error) {
|
|
253
254
|
return redirectPath + 'errorDeleteFailure';
|
|
@@ -119,6 +119,7 @@ class ContentRenderer
|
|
|
119
119
|
);
|
|
120
120
|
let templatePath = this.templateResolver.findTemplatePath(templateName, domain);
|
|
121
121
|
if(!templatePath){
|
|
122
|
+
Logger.warning('Template not found: "'+templateName+'" for domain: "'+domain+'"');
|
|
122
123
|
return layoutContent;
|
|
123
124
|
}
|
|
124
125
|
let routerKey = route?.router;
|
|
@@ -13,7 +13,7 @@ class TemplateCache
|
|
|
13
13
|
constructor(props)
|
|
14
14
|
{
|
|
15
15
|
this.templatesPath = sc.get(props, 'templatesPath', '');
|
|
16
|
-
this.templateExtensions = sc.get(props, 'templateExtensions', ['.html', '.mustache', '.template']);
|
|
16
|
+
this.templateExtensions = sc.get(props, 'templateExtensions', ['.html', '.mustache', '.template', '.txt', '.xml', '.json']);
|
|
17
17
|
this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
|
|
18
18
|
this.partialsCache = {};
|
|
19
19
|
this.domainPartialsCache = new Map();
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const { FileHandler } = require('@reldens/server-utils');
|
|
8
|
-
const { sc } = require('@reldens/utils');
|
|
8
|
+
const { Logger, sc } = require('@reldens/utils');
|
|
9
9
|
|
|
10
10
|
class TemplateResolver
|
|
11
11
|
{
|
|
@@ -13,7 +13,11 @@ class TemplateResolver
|
|
|
13
13
|
constructor(props)
|
|
14
14
|
{
|
|
15
15
|
this.templatesPath = sc.get(props, 'templatesPath', '');
|
|
16
|
-
this.templateExtensions = sc.get(
|
|
16
|
+
this.templateExtensions = sc.get(
|
|
17
|
+
props,
|
|
18
|
+
'templateExtensions',
|
|
19
|
+
['.html', '.mustache', '.template', '.txt', '.xml', '.json']
|
|
20
|
+
);
|
|
17
21
|
this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
|
|
18
22
|
this.domainMapping = sc.get(props, 'domainMapping', {});
|
|
19
23
|
this.siteKeyMapping = sc.get(props, 'siteKeyMapping', {});
|
|
@@ -75,6 +79,7 @@ class TemplateResolver
|
|
|
75
79
|
return templatePath;
|
|
76
80
|
}
|
|
77
81
|
}
|
|
82
|
+
Logger.debug('Template file not found: "'+templateName+'" in path: "'+basePath+'"');
|
|
78
83
|
return false;
|
|
79
84
|
}
|
|
80
85
|
|
package/lib/frontend.js
CHANGED
|
@@ -33,7 +33,11 @@ class Frontend
|
|
|
33
33
|
this.projectRoot = sc.get(props, 'projectRoot', './');
|
|
34
34
|
this.templatesPath = FileHandler.joinPaths(this.projectRoot, 'templates');
|
|
35
35
|
this.publicPath = FileHandler.joinPaths(this.projectRoot, 'public');
|
|
36
|
-
this.templateExtensions = sc.get(
|
|
36
|
+
this.templateExtensions = sc.get(
|
|
37
|
+
props,
|
|
38
|
+
'templateExtensions',
|
|
39
|
+
['.html', '.mustache', '.template', '.txt', '.xml', '.json']
|
|
40
|
+
);
|
|
37
41
|
this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
|
|
38
42
|
this.domainMapping = sc.get(props, 'domainMapping', {});
|
|
39
43
|
this.siteKeyMapping = sc.get(props, 'siteKeyMapping', {});
|
|
@@ -95,6 +99,12 @@ class Frontend
|
|
|
95
99
|
enableJsonResponse: sc.get(props, 'enableJsonResponse', false),
|
|
96
100
|
events: this.events
|
|
97
101
|
});
|
|
102
|
+
this.contentTypeMap = sc.get(props, 'contentTypeMap', {
|
|
103
|
+
'.txt': 'text/plain',
|
|
104
|
+
'.xml': 'application/xml',
|
|
105
|
+
'.json': 'application/json',
|
|
106
|
+
'.html': 'text/html'
|
|
107
|
+
});
|
|
98
108
|
}
|
|
99
109
|
|
|
100
110
|
async initialize()
|
|
@@ -153,6 +163,16 @@ class Frontend
|
|
|
153
163
|
return true;
|
|
154
164
|
}
|
|
155
165
|
|
|
166
|
+
getContentTypeFromPath(path)
|
|
167
|
+
{
|
|
168
|
+
let lastDotIndex = path.lastIndexOf('.');
|
|
169
|
+
if(-1 === lastDotIndex){
|
|
170
|
+
return 'text/html';
|
|
171
|
+
}
|
|
172
|
+
let extension = path.substring(lastDotIndex);
|
|
173
|
+
return sc.get(this.contentTypeMap, extension, 'text/html');
|
|
174
|
+
}
|
|
175
|
+
|
|
156
176
|
async handleRequest(req, res)
|
|
157
177
|
{
|
|
158
178
|
try {
|
|
@@ -178,10 +198,14 @@ class Frontend
|
|
|
178
198
|
if(!originalPath.endsWith('/') && routeFoundWithSlash){
|
|
179
199
|
return res.redirect(301, originalPath + '/');
|
|
180
200
|
}
|
|
201
|
+
let contentType = this.getContentTypeFromPath(originalPath);
|
|
181
202
|
return await this.responseManager.renderWithCacheHandler(
|
|
182
203
|
async () => await this.contentRenderer.generateRouteContent(route, domain, req),
|
|
183
204
|
async () => await this.responseManager.renderNotFound(domain, res, req),
|
|
184
|
-
async (content) =>
|
|
205
|
+
async (content) => {
|
|
206
|
+
res.setHeader('Content-Type', contentType);
|
|
207
|
+
return res.send(content);
|
|
208
|
+
},
|
|
185
209
|
domain,
|
|
186
210
|
res,
|
|
187
211
|
originalPath,
|
|
@@ -200,6 +224,7 @@ class Frontend
|
|
|
200
224
|
}
|
|
201
225
|
let entityResult = await this.entityAccessManager.findEntityByPath(originalPath);
|
|
202
226
|
if(entityResult){
|
|
227
|
+
let contentType = this.getContentTypeFromPath(originalPath);
|
|
203
228
|
return await this.responseManager.renderWithCacheHandler(
|
|
204
229
|
async () => await this.contentRenderer.renderWithTemplateContent(
|
|
205
230
|
entityResult.entity,
|
|
@@ -209,7 +234,10 @@ class Frontend
|
|
|
209
234
|
null
|
|
210
235
|
),
|
|
211
236
|
async () => await this.responseManager.renderNotFound(domain, res, req),
|
|
212
|
-
async (content) =>
|
|
237
|
+
async (content) => {
|
|
238
|
+
res.setHeader('Content-Type', contentType);
|
|
239
|
+
return res.send(content);
|
|
240
|
+
},
|
|
213
241
|
domain,
|
|
214
242
|
res,
|
|
215
243
|
originalPath,
|
|
@@ -218,12 +246,16 @@ class Frontend
|
|
|
218
246
|
}
|
|
219
247
|
let templatePath = this.templateResolver.findTemplateByPath(originalPath, domain);
|
|
220
248
|
if(templatePath){
|
|
249
|
+
let contentType = this.getContentTypeFromPath(originalPath);
|
|
221
250
|
return await this.responseManager.renderWithCacheHandler(
|
|
222
251
|
async () => await this.contentRenderer.generateTemplateContent(templatePath, domain, req),
|
|
223
252
|
async () => res.status(500).send('Template error: '+templatePath),
|
|
224
|
-
async (content) =>
|
|
225
|
-
|
|
226
|
-
|
|
253
|
+
async (content) => {
|
|
254
|
+
res.setHeader('Content-Type', contentType);
|
|
255
|
+
return res.send(
|
|
256
|
+
await this.contentRenderer.renderWithTemplateContent({content}, {}, domain, req, null)
|
|
257
|
+
);
|
|
258
|
+
},
|
|
227
259
|
domain,
|
|
228
260
|
res,
|
|
229
261
|
originalPath,
|
package/lib/manager.js
CHANGED
|
@@ -21,6 +21,7 @@ const { Frontend } = require('./frontend');
|
|
|
21
21
|
const { CacheManager } = require('./cache/cache-manager');
|
|
22
22
|
const { TemplateReloader } = require('./template-reloader');
|
|
23
23
|
const { PasswordEncryptionHandler } = require('./password-encryption-handler');
|
|
24
|
+
const { SitemapLoader } = require('./sitemap-loader');
|
|
24
25
|
const { EventsManagerSingleton, Logger, sc } = require('@reldens/utils');
|
|
25
26
|
const { DriversMap } = require('@reldens/storage');
|
|
26
27
|
const { AppServerFactory, FileHandler, Encryptor } = require('@reldens/server-utils');
|
|
@@ -74,7 +75,11 @@ class Manager
|
|
|
74
75
|
'domainCdnMapping',
|
|
75
76
|
sc.toJson(process.env.RELDENS_DOMAIN_CDN_MAPPING, {})
|
|
76
77
|
);
|
|
77
|
-
this.templateExtensions = sc.get(
|
|
78
|
+
this.templateExtensions = sc.get(
|
|
79
|
+
props,
|
|
80
|
+
'templateExtensions',
|
|
81
|
+
['.html', '.mustache', '.template', '.txt', '.xml', '.json']
|
|
82
|
+
);
|
|
78
83
|
this.cache = sc.get(props, 'cache', false);
|
|
79
84
|
this.reloadTime = sc.get(props, 'reloadTime', 0);
|
|
80
85
|
this.app = sc.get(props, 'app', false);
|
|
@@ -416,6 +421,11 @@ class Manager
|
|
|
416
421
|
return false;
|
|
417
422
|
}
|
|
418
423
|
}
|
|
424
|
+
this.sitemapLoader = new SitemapLoader({
|
|
425
|
+
dataServer: this.dataServer,
|
|
426
|
+
events: this.events,
|
|
427
|
+
domainMapping: this.domainMapping
|
|
428
|
+
});
|
|
419
429
|
if(!this.useProvidedServer){
|
|
420
430
|
await this.appServer.listen(this.config.port);
|
|
421
431
|
}
|
package/lib/mysql-installer.js
CHANGED
|
@@ -20,7 +20,8 @@ class MySQLInstaller
|
|
|
20
20
|
'install-default-homepage': 'default-homepage.sql',
|
|
21
21
|
'install-default-blocks': 'default-blocks.sql',
|
|
22
22
|
'install-entity-access': 'default-entity-access.sql',
|
|
23
|
-
'install-dynamic-forms': 'default-forms.sql'
|
|
23
|
+
'install-dynamic-forms': 'default-forms.sql',
|
|
24
|
+
'install-seo-files': 'default-sitemaps-and-robots.sql'
|
|
24
25
|
};
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Reldens - CMS - SitemapLoader
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { Logger, sc } = require('@reldens/utils');
|
|
8
|
+
|
|
9
|
+
class SitemapLoader
|
|
10
|
+
{
|
|
11
|
+
|
|
12
|
+
constructor(props)
|
|
13
|
+
{
|
|
14
|
+
this.dataServer = sc.get(props, 'dataServer', false);
|
|
15
|
+
this.routesRepository = this.dataServer?.getEntity('routes');
|
|
16
|
+
this.events = sc.get(props, 'events', false);
|
|
17
|
+
this.domainMapping = sc.get(props, 'domainMapping', {});
|
|
18
|
+
this.listenEvents();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
listenEvents()
|
|
22
|
+
{
|
|
23
|
+
if(!this.events){
|
|
24
|
+
Logger.error('EventsManager not provided for SitemapLoader.');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
this.events.on('reldens.afterVariablesCreated', this.loadSitemapData.bind(this));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async loadSitemapData(eventData)
|
|
31
|
+
{
|
|
32
|
+
if(!this.dataServer){
|
|
33
|
+
Logger.error('DataServer not provided for SitemapLoader.');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if(!this.routesRepository){
|
|
37
|
+
Logger.error('Routes repository not found for SitemapLoader.');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
let req = eventData.renderContext.req;
|
|
41
|
+
if(!req){
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if(!req.path){
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if('/sitemap.xml' !== req.path){
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if(req.sitemapPages){
|
|
51
|
+
eventData.variables.sitemapPages = req.sitemapPages;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
let currentDomain = eventData.renderContext.domain;
|
|
55
|
+
let mappedDomain = this.resolveMappedDomain(currentDomain);
|
|
56
|
+
let filters = {
|
|
57
|
+
enabled: 1,
|
|
58
|
+
redirect_url: null,
|
|
59
|
+
redirect_type: null,
|
|
60
|
+
OR: [
|
|
61
|
+
{domain: null},
|
|
62
|
+
{domain: mappedDomain}
|
|
63
|
+
]
|
|
64
|
+
};
|
|
65
|
+
try {
|
|
66
|
+
let routesWithPages = await this.routesRepository.loadWithRelations(filters, 'cms_pages');
|
|
67
|
+
let sitemapPages = routesWithPages.filter(route => {
|
|
68
|
+
if(!route.cms_pages || 0 === route.cms_pages.length){
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
let page = route.cms_pages[0];
|
|
72
|
+
if('noindex,nofollow' === page.meta_robots){
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
req.sitemapPages = sitemapPages;
|
|
78
|
+
eventData.variables.sitemapPages = sitemapPages;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
Logger.error('Error loading sitemap data: '+error.message);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
resolveMappedDomain(currentDomain)
|
|
85
|
+
{
|
|
86
|
+
if(!this.domainMapping){
|
|
87
|
+
return currentDomain;
|
|
88
|
+
}
|
|
89
|
+
if(!sc.isObject(this.domainMapping)){
|
|
90
|
+
return currentDomain;
|
|
91
|
+
}
|
|
92
|
+
let mappedValue = sc.get(this.domainMapping, currentDomain, false);
|
|
93
|
+
if(!mappedValue){
|
|
94
|
+
return currentDomain;
|
|
95
|
+
}
|
|
96
|
+
return mappedValue;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports.SitemapLoader = SitemapLoader;
|
|
@@ -234,7 +234,14 @@ class CollectionsTransformer extends CollectionsTransformerBase
|
|
|
234
234
|
this.jsonFieldsParser.getJsonFieldsForEntity(tableName)
|
|
235
235
|
);
|
|
236
236
|
}
|
|
237
|
-
let collectionContent = await this.renderCollectionLoop(
|
|
237
|
+
let collectionContent = await this.renderCollectionLoop(
|
|
238
|
+
loopContent,
|
|
239
|
+
collectionData,
|
|
240
|
+
domain,
|
|
241
|
+
req,
|
|
242
|
+
systemVariables,
|
|
243
|
+
enhancedData
|
|
244
|
+
);
|
|
238
245
|
finalContent = this.renderEngine.render(
|
|
239
246
|
1 < paginationData.totalPages
|
|
240
247
|
? this.loadPaginationTemplate(paginationOptions.containerName, domain)
|
|
@@ -259,7 +266,14 @@ class CollectionsTransformer extends CollectionsTransformerBase
|
|
|
259
266
|
queryOptionsJson,
|
|
260
267
|
relationsString
|
|
261
268
|
);
|
|
262
|
-
finalContent = await this.renderCollectionLoop(
|
|
269
|
+
finalContent = await this.renderCollectionLoop(
|
|
270
|
+
loopContent,
|
|
271
|
+
collectionData,
|
|
272
|
+
domain,
|
|
273
|
+
req,
|
|
274
|
+
systemVariables,
|
|
275
|
+
enhancedData
|
|
276
|
+
);
|
|
263
277
|
}
|
|
264
278
|
return template.substring(0, startPos) + finalContent + template.substring(endPos + endMatch[0].length);
|
|
265
279
|
}
|
|
@@ -312,7 +326,14 @@ class CollectionsTransformer extends CollectionsTransformerBase
|
|
|
312
326
|
}
|
|
313
327
|
let renderedContent = '';
|
|
314
328
|
for(let row of collectionData){
|
|
315
|
-
renderedContent += await this.processPartialsInLoop(
|
|
329
|
+
renderedContent += await this.processPartialsInLoop(
|
|
330
|
+
loopContent,
|
|
331
|
+
row,
|
|
332
|
+
domain,
|
|
333
|
+
req,
|
|
334
|
+
systemVariables,
|
|
335
|
+
enhancedData
|
|
336
|
+
);
|
|
316
337
|
}
|
|
317
338
|
return renderedContent;
|
|
318
339
|
}
|
|
@@ -351,7 +372,13 @@ class CollectionsTransformer extends CollectionsTransformerBase
|
|
|
351
372
|
continue;
|
|
352
373
|
}
|
|
353
374
|
if(this.processAllTemplateFunctions){
|
|
354
|
-
partialContent = await this.processAllTemplateFunctions(
|
|
375
|
+
partialContent = await this.processAllTemplateFunctions(
|
|
376
|
+
partialContent,
|
|
377
|
+
domain,
|
|
378
|
+
req,
|
|
379
|
+
systemVariables,
|
|
380
|
+
enhancedData
|
|
381
|
+
);
|
|
355
382
|
}
|
|
356
383
|
let renderData = Object.assign({}, enhancedData);
|
|
357
384
|
if(sc.hasOwn(tag.attributes, 'row')){
|
|
@@ -367,9 +394,19 @@ class CollectionsTransformer extends CollectionsTransformerBase
|
|
|
367
394
|
+processedContent.substring(tag.end);
|
|
368
395
|
}
|
|
369
396
|
if(this.processAllTemplateFunctions){
|
|
370
|
-
processedContent = await this.processAllTemplateFunctions(
|
|
397
|
+
processedContent = await this.processAllTemplateFunctions(
|
|
398
|
+
processedContent,
|
|
399
|
+
domain,
|
|
400
|
+
req,
|
|
401
|
+
systemVariables,
|
|
402
|
+
enhancedData
|
|
403
|
+
);
|
|
371
404
|
}
|
|
372
|
-
return this.renderEngine.render(
|
|
405
|
+
return this.renderEngine.render(
|
|
406
|
+
processedContent,
|
|
407
|
+
Object.assign({}, enhancedData, {row: rowData}),
|
|
408
|
+
this.getPartials(domain)
|
|
409
|
+
);
|
|
373
410
|
}
|
|
374
411
|
|
|
375
412
|
getCurrentUrl(req)
|
package/lib/template-engine.js
CHANGED
|
@@ -195,11 +195,7 @@ class TemplateEngine
|
|
|
195
195
|
|
|
196
196
|
buildEnhancedRenderData(originalData, systemVariables, currentEntityData)
|
|
197
197
|
{
|
|
198
|
-
let enhancedData = Object.assign({}, originalData);
|
|
199
|
-
enhancedData.currentRequest = systemVariables.currentRequest;
|
|
200
|
-
enhancedData.currentRoute = systemVariables.currentRoute;
|
|
201
|
-
enhancedData.currentDomain = systemVariables.currentDomain;
|
|
202
|
-
enhancedData.systemInfo = systemVariables.systemInfo;
|
|
198
|
+
let enhancedData = Object.assign({}, originalData, systemVariables);
|
|
203
199
|
if(currentEntityData){
|
|
204
200
|
enhancedData.currentEntity = currentEntityData;
|
|
205
201
|
}
|
|
@@ -12,7 +12,6 @@ CREATE TABLE `cms_forms` (
|
|
|
12
12
|
UNIQUE INDEX `form_key` (`form_key`) USING BTREE
|
|
13
13
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
14
14
|
|
|
15
|
-
|
|
16
15
|
CREATE TABLE `cms_forms_submitted` (
|
|
17
16
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
18
17
|
`form_id` INT UNSIGNED NOT NULL,
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
-- Default homepage:
|
|
2
1
|
|
|
3
|
-
--
|
|
4
|
-
REPLACE INTO `routes` (`id`, `path`, `router`, `cache_ttl_seconds`, `enabled`, `created_at`) VALUES (1, '/', 'cmsPages', 3600, 1, NOW());
|
|
2
|
+
-- Default homepage
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
INSERT INTO `routes` (`id`, `path`, `router`, `cache_ttl_seconds`, `enabled`, `created_at`) VALUES (NULL, '/', 'cmsPages', 3600, 1, NOW());
|
|
5
|
+
SET @route_id = LAST_INSERT_ID();
|
|
6
|
+
|
|
7
|
+
INSERT INTO `cms_pages` (
|
|
8
8
|
`id`, `title`, `content`, `template`, `route_id`, `meta_title`, `meta_description`,
|
|
9
9
|
`canonical_url`, `meta_robots`, `meta_og_title`, `meta_og_description`,
|
|
10
10
|
`meta_og_image`, `meta_twitter_card_type`, `status`, `locale`, `publish_date`, `expire_date`, `created_at`
|
|
11
11
|
) VALUES (
|
|
12
|
-
|
|
12
|
+
NULL,
|
|
13
13
|
'Home',
|
|
14
14
|
'<h1>Welcome to Reldens CMS</h1><p>This is your homepage. Edit this content in the admin panel.</p>',
|
|
15
15
|
NULL,
|
|
16
|
-
|
|
16
|
+
@route_id,
|
|
17
17
|
'Home - Reldens CMS',
|
|
18
18
|
'Welcome to Reldens CMS',
|
|
19
19
|
NULL,
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
-- Default robots.txt and sitemap.xml
|
|
3
|
+
|
|
4
|
+
INSERT INTO `routes` (`id`, `path`, `router`, `cache_ttl_seconds`, `enabled`, `created_at`) VALUES
|
|
5
|
+
(NULL, '/robots.txt', 'cmsPages', 3600, 1, NOW());
|
|
6
|
+
SET @route_id_robots = LAST_INSERT_ID();
|
|
7
|
+
|
|
8
|
+
INSERT INTO `cms_pages` (
|
|
9
|
+
`id`, `title`, `content`, `template`, `layout`, `route_id`, `meta_robots`,
|
|
10
|
+
`status`, `locale`, `publish_date`, `created_at`
|
|
11
|
+
) VALUES (
|
|
12
|
+
NULL,
|
|
13
|
+
'Robots.txt',
|
|
14
|
+
NULL,
|
|
15
|
+
'robots',
|
|
16
|
+
'raw',
|
|
17
|
+
@route_id_robots,
|
|
18
|
+
'noindex,nofollow',
|
|
19
|
+
NULL,
|
|
20
|
+
NULL,
|
|
21
|
+
NOW(),
|
|
22
|
+
NOW()
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
INSERT INTO `routes` (`id`, `path`, `router`, `cache_ttl_seconds`, `enabled`, `domain`, `created_at`) VALUES
|
|
26
|
+
(NULL, '/sitemap.xml', 'cmsPages', 3600, 1, NULL, NOW());
|
|
27
|
+
SET @route_id_sitemap = LAST_INSERT_ID();
|
|
28
|
+
|
|
29
|
+
INSERT INTO `cms_pages` (
|
|
30
|
+
`id`, `title`, `content`, `template`, `layout`, `route_id`, `meta_robots`,
|
|
31
|
+
`status`, `locale`, `publish_date`, `created_at`
|
|
32
|
+
) VALUES (
|
|
33
|
+
NULL,
|
|
34
|
+
'Sitemap XML',
|
|
35
|
+
NULL,
|
|
36
|
+
'sitemap',
|
|
37
|
+
'raw',
|
|
38
|
+
@route_id_sitemap,
|
|
39
|
+
'noindex,nofollow',
|
|
40
|
+
NULL,
|
|
41
|
+
NULL,
|
|
42
|
+
NOW(),
|
|
43
|
+
NOW()
|
|
44
|
+
);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reldens/cms",
|
|
3
3
|
"scope": "@reldens",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.53.0",
|
|
5
5
|
"description": "Reldens - CMS",
|
|
6
6
|
"author": "Damian A. Pastorini",
|
|
7
7
|
"license": "MIT",
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
"bin": {
|
|
14
14
|
"reldens-cms": "bin/reldens-cms.js",
|
|
15
15
|
"reldens-cms-generate-entities": "bin/reldens-cms-generate-entities.js",
|
|
16
|
-
"reldens-cms-update-password": "bin/reldens-cms-update-password.js"
|
|
17
|
-
"reldens-cms-generate-sitemap": "bin/reldens-cms-generate-sitemap.js"
|
|
16
|
+
"reldens-cms-update-password": "bin/reldens-cms-update-password.js"
|
|
18
17
|
},
|
|
19
18
|
"repository": {
|
|
20
19
|
"type": "git",
|
|
@@ -36,7 +35,7 @@
|
|
|
36
35
|
},
|
|
37
36
|
"dependencies": {
|
|
38
37
|
"@reldens/server-utils": "^0.44.0",
|
|
39
|
-
"@reldens/storage": "^0.
|
|
38
|
+
"@reldens/storage": "^0.88.0",
|
|
40
39
|
"@reldens/utils": "^0.54.0",
|
|
41
40
|
"dotenv": "17.2.3",
|
|
42
41
|
"mustache": "4.2.0"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{&content}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{&content}}
|