@reldens/cms 0.20.0 → 0.21.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.
Files changed (50) hide show
  1. package/README.md +236 -11
  2. package/admin/reldens-admin-client.css +75 -21
  3. package/admin/reldens-admin-client.js +108 -133
  4. package/admin/templates/clear-all-cache-button.html +7 -7
  5. package/admin/templates/edit.html +7 -0
  6. package/admin/templates/layout.html +15 -9
  7. package/admin/templates/list-content.html +4 -2
  8. package/admin/templates/list.html +24 -8
  9. package/admin/templates/view.html +21 -0
  10. package/lib/admin-manager/admin-filters-manager.js +177 -0
  11. package/lib/admin-manager/contents-builder.js +1 -0
  12. package/lib/admin-manager/default-translations.js +38 -0
  13. package/lib/admin-manager/router-contents.js +50 -45
  14. package/lib/admin-manager/router.js +19 -0
  15. package/lib/frontend/content-renderer.js +178 -0
  16. package/lib/frontend/entity-access-manager.js +63 -0
  17. package/lib/frontend/request-processor.js +128 -0
  18. package/lib/frontend/response-manager.js +54 -0
  19. package/lib/frontend/template-cache.js +102 -0
  20. package/lib/frontend/template-resolver.js +111 -0
  21. package/lib/frontend.js +89 -630
  22. package/lib/manager.js +25 -12
  23. package/lib/search-renderer.js +15 -7
  24. package/lib/search-request-handler.js +67 -0
  25. package/lib/search.js +13 -1
  26. package/lib/template-engine/collections-single-transformer.js +11 -5
  27. package/lib/template-engine/collections-transformer.js +47 -34
  28. package/lib/template-engine/entities-transformer.js +3 -2
  29. package/lib/template-engine/partials-transformer.js +5 -6
  30. package/lib/template-engine/system-variables-provider.js +4 -1
  31. package/lib/template-engine.js +11 -5
  32. package/lib/template-reloader.js +307 -0
  33. package/package.json +4 -4
  34. package/templates/{browserconfig.xml → assets/favicons/default/browserconfig.xml} +1 -1
  35. package/templates/assets/favicons/default/favicon.ico +0 -0
  36. package/templates/{site.webmanifest → assets/favicons/default/site.webmanifest} +3 -3
  37. package/templates/js/functions.js +144 -0
  38. package/templates/js/scripts.js +5 -0
  39. package/templates/page.html +11 -5
  40. package/templates/partials/pagedCollection.html +1 -1
  41. package/lib/admin-translations.js +0 -56
  42. package/templates/favicon.ico +0 -0
  43. /package/templates/assets/favicons/{android-icon-144x144.png → default/android-icon-144x144.png} +0 -0
  44. /package/templates/assets/favicons/{android-icon-192x192.png → default/android-icon-192x192.png} +0 -0
  45. /package/templates/assets/favicons/{android-icon-512x512.png → default/android-icon-512x512.png} +0 -0
  46. /package/templates/assets/favicons/{apple-touch-icon.png → default/apple-touch-icon.png} +0 -0
  47. /package/templates/assets/favicons/{favicon-16x16.png → default/favicon-16x16.png} +0 -0
  48. /package/templates/assets/favicons/{favicon-32x32.png → default/favicon-32x32.png} +0 -0
  49. /package/templates/assets/favicons/{mstile-150x150.png → default/mstile-150x150.png} +0 -0
  50. /package/templates/assets/favicons/{safari-pinned-tab.svg → default/safari-pinned-tab.svg} +0 -0
@@ -0,0 +1,54 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS - Frontend - ResponseManager
4
+ *
5
+ */
6
+
7
+ const { sc } = require('@reldens/utils');
8
+
9
+ class ResponseManager
10
+ {
11
+
12
+ constructor(props)
13
+ {
14
+ this.cacheManager = sc.get(props, 'cacheManager', false);
15
+ this.contentRenderer = sc.get(props, 'contentRenderer', false);
16
+ this.templateResolver = sc.get(props, 'templateResolver', false);
17
+ this.requestProcessor = sc.get(props, 'requestProcessor', false);
18
+ }
19
+
20
+ async renderWithCacheHandler(contentGenerator, errorHandler, responseHandler, domain, res, path, req)
21
+ {
22
+ let renderedContent = await contentGenerator();
23
+ if(!renderedContent){
24
+ return await errorHandler();
25
+ }
26
+ if(this.cacheManager && this.cacheManager.isEnabled()){
27
+ let cacheKey = this.requestProcessor.buildCacheKey(path, req);
28
+ await this.cacheManager.set(domain, cacheKey, renderedContent);
29
+ }
30
+ return await responseHandler(renderedContent);
31
+ }
32
+
33
+ async renderNotFound(domain, res, req)
34
+ {
35
+ let notFoundPath = this.templateResolver.findTemplatePath('404', domain);
36
+ if(notFoundPath){
37
+ let content = await this.contentRenderer.generateTemplateContent(notFoundPath, domain, req, {});
38
+ if(content){
39
+ res.status(404);
40
+ return res.send(await this.contentRenderer.renderWithTemplateContent(
41
+ {content},
42
+ {meta_title: 'Page not found'},
43
+ domain,
44
+ req,
45
+ null
46
+ ));
47
+ }
48
+ }
49
+ return res.status(404).send('Page not found');
50
+ }
51
+
52
+ }
53
+
54
+ module.exports.ResponseManager = ResponseManager;
@@ -0,0 +1,102 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS - Frontend - TemplateCache
4
+ *
5
+ */
6
+
7
+ const { FileHandler } = require('@reldens/server-utils');
8
+ const { Logger, sc } = require('@reldens/utils');
9
+
10
+ class TemplateCache
11
+ {
12
+
13
+ constructor(props)
14
+ {
15
+ this.templatesPath = sc.get(props, 'templatesPath', '');
16
+ this.templateExtensions = sc.get(props, 'templateExtensions', ['.html', '.mustache', '.template']);
17
+ this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
18
+ this.partialsCache = {};
19
+ this.domainPartialsCache = new Map();
20
+ this.domainTemplatesMap = new Map();
21
+ this.templateResolver = sc.get(props, 'templateResolver', false);
22
+ }
23
+
24
+ async loadPartials()
25
+ {
26
+ let partialsPath = FileHandler.joinPaths(this.templatesPath, 'partials');
27
+ FileHandler.createFolder(partialsPath);
28
+ let partialFiles = FileHandler.getFilesInFolder(partialsPath, this.templateExtensions);
29
+ for(let file of partialFiles){
30
+ let partialName = this.templateResolver.extractTemplateName(file);
31
+ if(!partialName){
32
+ continue;
33
+ }
34
+ let partialPath = FileHandler.joinPaths(partialsPath, file);
35
+ let partialContent = FileHandler.readFile(partialPath);
36
+ if(!partialContent){
37
+ Logger.error('Failed to read partial: '+partialPath);
38
+ continue;
39
+ }
40
+ this.partialsCache[partialName] = partialContent;
41
+ }
42
+ }
43
+
44
+ async loadDomainPartials(domain, domainPath)
45
+ {
46
+ let domainPartialsPath = FileHandler.joinPaths(domainPath, 'partials');
47
+ if(!FileHandler.exists(domainPartialsPath)){
48
+ return;
49
+ }
50
+ let domainPartials = {};
51
+ let partialFiles = FileHandler.getFilesInFolder(domainPartialsPath, this.templateExtensions);
52
+ for(let file of partialFiles){
53
+ let partialName = this.templateResolver.extractTemplateName(file);
54
+ if(!partialName){
55
+ continue;
56
+ }
57
+ let partialPath = FileHandler.joinPaths(domainPartialsPath, file);
58
+ let partialContent = FileHandler.readFile(partialPath);
59
+ if(!partialContent){
60
+ Logger.error('Failed to read domain partial: '+partialPath);
61
+ continue;
62
+ }
63
+ domainPartials[partialName] = partialContent;
64
+ }
65
+ this.domainPartialsCache.set(domain, domainPartials);
66
+ }
67
+
68
+ async setupDomainTemplates()
69
+ {
70
+ let domainsPath = FileHandler.joinPaths(this.templatesPath, 'domains');
71
+ if(!FileHandler.exists(domainsPath)){
72
+ return;
73
+ }
74
+ let domainFolders = FileHandler.fetchSubFoldersList(domainsPath);
75
+ for(let domain of domainFolders){
76
+ let domainPath = FileHandler.joinPaths(domainsPath, domain);
77
+ this.domainTemplatesMap.set(domain, domainPath);
78
+ await this.loadDomainPartials(domain, domainPath);
79
+ }
80
+ }
81
+
82
+ getPartialsForDomain(domain)
83
+ {
84
+ let resolvedDomain = this.templateResolver.resolveDomainToFolder(domain);
85
+ let domainPartials = this.domainPartialsCache.get(resolvedDomain);
86
+ if(!domainPartials && this.defaultDomain && resolvedDomain !== this.defaultDomain){
87
+ domainPartials = this.domainPartialsCache.get(this.defaultDomain);
88
+ }
89
+ if(!domainPartials){
90
+ return this.partialsCache;
91
+ }
92
+ return Object.assign({}, this.partialsCache, domainPartials);
93
+ }
94
+
95
+ getDomainTemplatesMap()
96
+ {
97
+ return this.domainTemplatesMap;
98
+ }
99
+
100
+ }
101
+
102
+ module.exports.TemplateCache = TemplateCache;
@@ -0,0 +1,111 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS - Frontend - TemplateResolver
4
+ *
5
+ */
6
+
7
+ const { FileHandler } = require('@reldens/server-utils');
8
+ const { sc } = require('@reldens/utils');
9
+
10
+ class TemplateResolver
11
+ {
12
+
13
+ constructor(props)
14
+ {
15
+ this.templatesPath = sc.get(props, 'templatesPath', '');
16
+ this.templateExtensions = sc.get(props, 'templateExtensions', ['.html', '.mustache', '.template']);
17
+ this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
18
+ this.domainMapping = sc.get(props, 'domainMapping', {});
19
+ this.siteKeyMapping = sc.get(props, 'siteKeyMapping', {});
20
+ this.domainTemplatesMap = sc.get(props, 'domainTemplatesMap', new Map());
21
+ }
22
+
23
+ extractTemplateName(filename)
24
+ {
25
+ for(let extension of this.templateExtensions){
26
+ if(filename.endsWith(extension)){
27
+ return filename.replace(extension, '');
28
+ }
29
+ }
30
+ return false;
31
+ }
32
+
33
+ resolveDomainToFolder(domain)
34
+ {
35
+ if(!domain){
36
+ domain = this.defaultDomain;
37
+ }
38
+ return sc.get(this.domainMapping, domain, domain);
39
+ }
40
+
41
+ resolveDomainToSiteKey(domain)
42
+ {
43
+ return sc.get(this.siteKeyMapping, this.resolveDomainToFolder(domain), 'default');
44
+ }
45
+
46
+ findTemplatePath(templateName, domain)
47
+ {
48
+ let resolvedDomain = this.resolveDomainToFolder(domain);
49
+ if(resolvedDomain){
50
+ let domainPath = this.domainTemplatesMap.get(resolvedDomain);
51
+ if(domainPath){
52
+ let domainTemplatePath = this.findTemplateInPath(templateName, domainPath);
53
+ if(domainTemplatePath){
54
+ return domainTemplatePath;
55
+ }
56
+ }
57
+ if(this.defaultDomain && resolvedDomain !== this.defaultDomain){
58
+ let defaultDomainPath = this.domainTemplatesMap.get(this.defaultDomain);
59
+ if(defaultDomainPath){
60
+ let defaultTemplatePath = this.findTemplateInPath(templateName, defaultDomainPath);
61
+ if(defaultTemplatePath){
62
+ return defaultTemplatePath;
63
+ }
64
+ }
65
+ }
66
+ }
67
+ return this.findTemplateInPath(templateName, this.templatesPath);
68
+ }
69
+
70
+ findTemplateInPath(templateName, basePath)
71
+ {
72
+ for(let extension of this.templateExtensions){
73
+ let templatePath = FileHandler.joinPaths(basePath, templateName + extension);
74
+ if(FileHandler.exists(templatePath)){
75
+ return templatePath;
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+
81
+ findLayoutPath(layoutName, domain)
82
+ {
83
+ let resolvedDomain = this.resolveDomainToFolder(domain);
84
+ if(resolvedDomain){
85
+ let domainPath = this.domainTemplatesMap.get(resolvedDomain);
86
+ if(domainPath){
87
+ let domainLayoutPath = this.findTemplateInPath('layouts/' + layoutName, domainPath);
88
+ if(domainLayoutPath){
89
+ return domainLayoutPath;
90
+ }
91
+ }
92
+ }
93
+ return this.findTemplateInPath('layouts/' + layoutName, this.templatesPath);
94
+ }
95
+
96
+ findTemplateByPath(path, domain)
97
+ {
98
+ if('/' === path){
99
+ path = '/index';
100
+ }
101
+ let templatePath = path.endsWith('/') ? path.slice(0, -1) : path;
102
+ templatePath = templatePath.startsWith('/') ? templatePath.substring(1) : templatePath;
103
+ if('page' === templatePath){
104
+ return false;
105
+ }
106
+ return this.findTemplatePath(templatePath, domain);
107
+ }
108
+
109
+ }
110
+
111
+ module.exports.TemplateResolver = TemplateResolver;