@reldens/cms 0.19.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 (55) hide show
  1. package/README.md +399 -17
  2. package/admin/reldens-admin-client.css +156 -99
  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 +111 -538
  22. package/lib/manager.js +26 -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/asset-transformer.js +41 -0
  27. package/lib/template-engine/collections-single-transformer.js +28 -5
  28. package/lib/template-engine/collections-transformer.js +66 -32
  29. package/lib/template-engine/date-transformer.js +53 -0
  30. package/lib/template-engine/entities-transformer.js +5 -2
  31. package/lib/template-engine/partials-transformer.js +8 -5
  32. package/lib/template-engine/system-variables-provider.js +108 -0
  33. package/lib/template-engine/translate-transformer.js +98 -0
  34. package/lib/template-engine/translation-service.js +104 -0
  35. package/lib/template-engine/url-transformer.js +41 -0
  36. package/lib/template-engine.js +99 -12
  37. package/lib/template-reloader.js +307 -0
  38. package/package.json +4 -4
  39. package/templates/{browserconfig.xml → assets/favicons/default/browserconfig.xml} +1 -1
  40. package/templates/assets/favicons/default/favicon.ico +0 -0
  41. package/templates/{site.webmanifest → assets/favicons/default/site.webmanifest} +3 -3
  42. package/templates/js/functions.js +144 -0
  43. package/templates/js/scripts.js +5 -0
  44. package/templates/page.html +11 -5
  45. package/templates/partials/pagedCollection.html +1 -1
  46. package/lib/admin-translations.js +0 -56
  47. package/templates/favicon.ico +0 -0
  48. /package/templates/assets/favicons/{android-icon-144x144.png → default/android-icon-144x144.png} +0 -0
  49. /package/templates/assets/favicons/{android-icon-192x192.png → default/android-icon-192x192.png} +0 -0
  50. /package/templates/assets/favicons/{android-icon-512x512.png → default/android-icon-512x512.png} +0 -0
  51. /package/templates/assets/favicons/{apple-touch-icon.png → default/apple-touch-icon.png} +0 -0
  52. /package/templates/assets/favicons/{favicon-16x16.png → default/favicon-16x16.png} +0 -0
  53. /package/templates/assets/favicons/{favicon-32x32.png → default/favicon-32x32.png} +0 -0
  54. /package/templates/assets/favicons/{mstile-150x150.png → default/mstile-150x150.png} +0 -0
  55. /package/templates/assets/favicons/{safari-pinned-tab.svg → default/safari-pinned-tab.svg} +0 -0
@@ -13,9 +13,10 @@ class PartialsTransformer
13
13
  {
14
14
  this.renderEngine = sc.get(props, 'renderEngine', false);
15
15
  this.getPartials = sc.get(props, 'getPartials', false);
16
+ this.processAllTemplateFunctions = sc.get(props, 'processAllTemplateFunctions', false);
16
17
  }
17
18
 
18
- async transform(template, domain)
19
+ async transform(template, domain, req, systemVariables, enhancedData = {})
19
20
  {
20
21
  let processedTemplate = template;
21
22
  let partialTags = this.findAllPartialTags(template);
@@ -27,11 +28,13 @@ class PartialsTransformer
27
28
  processedTemplate = processedTemplate.substring(0, tag.start)+''+processedTemplate.substring(tag.end);
28
29
  continue;
29
30
  }
30
- let wrapperTemplate = '{{#vars}}{{> ' + tag.name + '}}{{/vars}}';
31
- let renderData = { vars: tag.attributes };
32
- let partials = {[tag.name]: partialContent};
31
+ if(this.processAllTemplateFunctions){
32
+ partialContent = await this.processAllTemplateFunctions(partialContent, domain, req, systemVariables, enhancedData);
33
+ }
34
+ let partialData = Object.assign({}, enhancedData, tag.attributes);
35
+ let renderedPartial = this.renderEngine.render(partialContent, partialData, {});
33
36
  processedTemplate = processedTemplate.substring(0, tag.start) +
34
- this.renderEngine.render(wrapperTemplate, renderData, partials) +
37
+ renderedPartial +
35
38
  processedTemplate.substring(tag.end);
36
39
  }
37
40
  return processedTemplate;
@@ -0,0 +1,108 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS - SystemVariablesProvider
4
+ *
5
+ */
6
+
7
+ const { sc } = require('@reldens/utils');
8
+
9
+ class SystemVariablesProvider
10
+ {
11
+
12
+ constructor(props)
13
+ {
14
+ this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
15
+ this.projectRoot = sc.get(props, 'projectRoot', './');
16
+ this.publicPath = sc.get(props, 'publicPath', './public');
17
+ }
18
+
19
+ buildSystemVariables(req, route, domain)
20
+ {
21
+ let currentRequest = this.buildCurrentRequestData(req, domain);
22
+ let currentRoute = this.buildCurrentRouteData(route);
23
+ let currentDomain = this.buildCurrentDomainData(domain);
24
+ let systemInfo = this.buildSystemInfo();
25
+ return {
26
+ currentRequest,
27
+ currentRoute,
28
+ currentDomain,
29
+ systemInfo
30
+ };
31
+ }
32
+
33
+ buildCurrentRequestData(req, domain)
34
+ {
35
+ if(!req){
36
+ return {};
37
+ }
38
+ let protocol = sc.get(req, 'protocol', 'http');
39
+ let host = req.get('host') || 'localhost';
40
+ let originalUrl = sc.get(req, 'originalUrl', sc.get(req, 'path', '/'));
41
+ let fullUrl = protocol+'://'+host+originalUrl;
42
+ return {
43
+ method: sc.get(req, 'method', 'GET'),
44
+ path: sc.get(req, 'path', '/'),
45
+ originalUrl,
46
+ fullUrl,
47
+ protocol,
48
+ host,
49
+ domain: domain || host.split(':')[0],
50
+ query: sc.get(req, 'query', {}),
51
+ params: sc.get(req, 'params', {}),
52
+ headers: sc.get(req, 'headers', {}),
53
+ userAgent: req.get('user-agent') || '',
54
+ ip: sc.get(req, 'ip', ''),
55
+ baseUrl: protocol+'://'+host,
56
+ timestamp: sc.getCurrentDate(),
57
+ isSecure: 'https' === protocol
58
+ };
59
+ }
60
+
61
+ buildCurrentRouteData(route)
62
+ {
63
+ if(!route){
64
+ return null;
65
+ }
66
+ return {
67
+ id: sc.get(route, 'id', null),
68
+ path: sc.get(route, 'path', ''),
69
+ router: sc.get(route, 'router', ''),
70
+ domain: sc.get(route, 'domain', null),
71
+ enabled: sc.get(route, 'enabled', false),
72
+ title: sc.get(route, 'title', ''),
73
+ template: sc.get(route, 'template', ''),
74
+ layout: sc.get(route, 'layout', ''),
75
+ meta_title: sc.get(route, 'meta_title', ''),
76
+ meta_description: sc.get(route, 'meta_description', ''),
77
+ sort_order: sc.get(route, 'sort_order', 0)
78
+ };
79
+ }
80
+
81
+ buildCurrentDomainData(domain)
82
+ {
83
+ return {
84
+ current: domain || this.defaultDomain,
85
+ default: this.defaultDomain,
86
+ resolved: domain || this.defaultDomain
87
+ };
88
+ }
89
+
90
+ buildSystemInfo()
91
+ {
92
+ let date = new Date();
93
+ return {
94
+ projectRoot: this.projectRoot,
95
+ publicPath: this.publicPath,
96
+ nodeVersion: process.version,
97
+ platform: process.platform,
98
+ environment: process.env.NODE_ENV || 'development',
99
+ timestamp: sc.getCurrentDate(),
100
+ uptime: process.uptime(),
101
+ currentDate: sc.formatDate(date),
102
+ currentYear: sc.formatDate(date, 'Y')
103
+ };
104
+ }
105
+
106
+ }
107
+
108
+ module.exports.SystemVariablesProvider = SystemVariablesProvider;
@@ -0,0 +1,98 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS - TranslateTransformer
4
+ *
5
+ */
6
+
7
+ const { TranslationService } = require('./translation-service');
8
+ const { FileHandler } = require('@reldens/server-utils');
9
+ const { sc } = require('@reldens/utils');
10
+
11
+ class TranslateTransformer
12
+ {
13
+
14
+ constructor(props)
15
+ {
16
+ let projectRoot = sc.get(props, 'projectRoot', './');
17
+ let translationsPath = FileHandler.joinPaths(projectRoot, 'translations');
18
+ this.translationService = new TranslationService({
19
+ translationsPath,
20
+ defaultLocale: sc.get(props, 'defaultLocale', 'en'),
21
+ fallbackLocale: sc.get(props, 'fallbackLocale', 'en')
22
+ });
23
+ }
24
+
25
+ async transform(template, domain, req, systemVariables)
26
+ {
27
+ if(!template){
28
+ return template;
29
+ }
30
+ let currentLocale = this.extractLocaleFromSystemVariables(systemVariables);
31
+ let translatePattern = /\[(?:translate|t)\(([^)]+)\)\]/g;
32
+ let matches = [...template.matchAll(translatePattern)];
33
+ for(let i = matches.length - 1; i >= 0; i--){
34
+ let match = matches[i];
35
+ let args = this.parseTranslateArgs(match[1]);
36
+ let translatedText = await this.translationService.translate(
37
+ args.key,
38
+ currentLocale,
39
+ args.defaultValue,
40
+ args.interpolations
41
+ );
42
+ template = template.substring(0, match.index) +
43
+ translatedText +
44
+ template.substring(match.index + match[0].length);
45
+ }
46
+ return template;
47
+ }
48
+
49
+ parseTranslateArgs(argsString)
50
+ {
51
+ let args = argsString.split(',').map(arg => arg.trim().replace(/['"]/g, ''));
52
+ return {
53
+ key: args[0] || '',
54
+ defaultValue: args[1] || '',
55
+ interpolations: this.parseInterpolations(args[2])
56
+ };
57
+ }
58
+
59
+ parseInterpolations(interpolationsStr)
60
+ {
61
+ if(!interpolationsStr){
62
+ return {};
63
+ }
64
+ let interpolations = {};
65
+ let pairs = interpolationsStr.replace(/[{}]/g, '').split(',');
66
+ for(let pair of pairs){
67
+ let keyValue = pair.split(':');
68
+ if(2 === keyValue.length){
69
+ interpolations[keyValue[0].trim()] = keyValue[1].trim();
70
+ }
71
+ }
72
+ return interpolations;
73
+ }
74
+
75
+ extractLocaleFromSystemVariables(systemVariables)
76
+ {
77
+ let currentRequest = sc.get(systemVariables, 'currentRequest', {});
78
+ let headers = sc.get(currentRequest, 'headers', {});
79
+ let acceptLanguage = sc.get(headers, 'accept-language', '');
80
+ if(acceptLanguage){
81
+ let primaryLanguage = acceptLanguage.split(',')[0];
82
+ if(primaryLanguage && primaryLanguage.includes('-')){
83
+ return primaryLanguage.split('-')[0];
84
+ }
85
+ if(primaryLanguage){
86
+ return primaryLanguage;
87
+ }
88
+ }
89
+ let locale = sc.get(currentRequest, 'query', {}).locale;
90
+ if(locale){
91
+ return locale;
92
+ }
93
+ return this.translationService.defaultLocale;
94
+ }
95
+
96
+ }
97
+
98
+ module.exports.TranslateTransformer = TranslateTransformer;
@@ -0,0 +1,104 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS - TranslationService
4
+ *
5
+ */
6
+
7
+ const { FileHandler } = require('@reldens/server-utils');
8
+ const { Logger, sc } = require('@reldens/utils');
9
+
10
+ class TranslationService
11
+ {
12
+
13
+ constructor(props)
14
+ {
15
+ this.translationsPath = sc.get(props, 'translationsPath', './translations');
16
+ this.defaultLocale = sc.get(props, 'defaultLocale', 'en');
17
+ this.fallbackLocale = sc.get(props, 'fallbackLocale', 'en');
18
+ this.translations = new Map();
19
+ this.loadedLocales = new Set();
20
+ }
21
+
22
+ async loadTranslations(locale)
23
+ {
24
+ if(this.loadedLocales.has(locale)){
25
+ return true;
26
+ }
27
+ let translationFile = FileHandler.joinPaths(this.translationsPath, locale + '.json');
28
+ if(!FileHandler.exists(translationFile)){
29
+ if(locale !== this.fallbackLocale){
30
+ Logger.warning('Translation file not found for locale: '+locale+', loading fallback');
31
+ return await this.loadTranslations(this.fallbackLocale);
32
+ }
33
+ Logger.warning('Translation file not found: '+translationFile);
34
+ return false;
35
+ }
36
+ let translationContent = FileHandler.readFile(translationFile);
37
+ if(!translationContent){
38
+ Logger.error('Failed to read translation file: '+translationFile);
39
+ return false;
40
+ }
41
+ let translationData = sc.toJson(translationContent, {});
42
+ if(!translationData){
43
+ Logger.error('Invalid JSON in translation file: '+translationFile);
44
+ return false;
45
+ }
46
+ this.translations.set(locale, translationData);
47
+ this.loadedLocales.add(locale);
48
+ return true;
49
+ }
50
+
51
+ async translate(key, locale, defaultValue, interpolations)
52
+ {
53
+ let targetLocale = locale || this.defaultLocale;
54
+ if(!this.loadedLocales.has(targetLocale)){
55
+ await this.loadTranslations(targetLocale);
56
+ }
57
+ let translations = this.translations.get(targetLocale);
58
+ let translatedText = this.getNestedTranslation(translations, key);
59
+ if(!translatedText && targetLocale !== this.fallbackLocale){
60
+ if(!this.loadedLocales.has(this.fallbackLocale)){
61
+ await this.loadTranslations(this.fallbackLocale);
62
+ }
63
+ let fallbackTranslations = this.translations.get(this.fallbackLocale);
64
+ translatedText = this.getNestedTranslation(fallbackTranslations, key);
65
+ }
66
+ if(!translatedText){
67
+ translatedText = defaultValue || key;
68
+ }
69
+ if(interpolations && sc.isObject(interpolations)){
70
+ translatedText = this.interpolateString(translatedText, interpolations);
71
+ }
72
+ return translatedText;
73
+ }
74
+
75
+ getNestedTranslation(translations, key)
76
+ {
77
+ if(!translations || !key){
78
+ return null;
79
+ }
80
+ let keys = key.split('.');
81
+ let current = translations;
82
+ for(let keyPart of keys){
83
+ if(!sc.hasOwn(current, keyPart)){
84
+ return null;
85
+ }
86
+ current = current[keyPart];
87
+ }
88
+ return sc.isString(current) ? current : null;
89
+ }
90
+
91
+ interpolateString(text, interpolations)
92
+ {
93
+ let result = text;
94
+ for(let key of Object.keys(interpolations)){
95
+ let placeholder = '{' + key + '}';
96
+ let value = interpolations[key];
97
+ result = result.replace(new RegExp(sc.sanitize(placeholder), 'g'), value);
98
+ }
99
+ return result;
100
+ }
101
+
102
+ }
103
+
104
+ module.exports.TranslationService = TranslationService;
@@ -0,0 +1,41 @@
1
+ /**
2
+ *
3
+ * Reldens - CMS - UrlTransformer
4
+ *
5
+ */
6
+
7
+ const { sc } = require('@reldens/utils');
8
+
9
+ class UrlTransformer
10
+ {
11
+
12
+ async transform(template, domain, req, systemVariables)
13
+ {
14
+ if(!template){
15
+ return template;
16
+ }
17
+ let currentRequest = sc.get(systemVariables, 'currentRequest', {});
18
+ let urlPattern = /\[url\(([^)]+)\)\]/g;
19
+ let matches = [...template.matchAll(urlPattern)];
20
+ for(let i = matches.length - 1; i >= 0; i--){
21
+ let match = matches[i];
22
+ let urlPath = match[1].replace(/['"]/g, '');
23
+ let absoluteUrl = this.buildAbsoluteUrl(urlPath, currentRequest);
24
+ template = template.substring(0, match.index) +
25
+ absoluteUrl +
26
+ template.substring(match.index + match[0].length);
27
+ }
28
+ return template;
29
+ }
30
+
31
+ buildAbsoluteUrl(relativePath, currentRequest)
32
+ {
33
+ if(!relativePath || relativePath.startsWith('http')){
34
+ return relativePath;
35
+ }
36
+ return sc.get(currentRequest, 'baseUrl', '') + relativePath;
37
+ }
38
+
39
+ }
40
+
41
+ module.exports.UrlTransformer = UrlTransformer;
@@ -9,6 +9,11 @@ const { EntitiesTransformer } = require('./template-engine/entities-transformer'
9
9
  const { CollectionsTransformer } = require('./template-engine/collections-transformer');
10
10
  const { CollectionsSingleTransformer } = require('./template-engine/collections-single-transformer');
11
11
  const { PartialsTransformer } = require('./template-engine/partials-transformer');
12
+ const { UrlTransformer } = require('./template-engine/url-transformer');
13
+ const { AssetTransformer } = require('./template-engine/asset-transformer');
14
+ const { DateTransformer } = require('./template-engine/date-transformer');
15
+ const { TranslateTransformer } = require('./template-engine/translate-transformer');
16
+ const { SystemVariablesProvider } = require('./template-engine/system-variables-provider');
12
17
  const { Logger, sc } = require('@reldens/utils');
13
18
 
14
19
  class TemplateEngine
@@ -19,7 +24,16 @@ class TemplateEngine
19
24
  this.renderEngine = sc.get(props, 'renderEngine', false);
20
25
  this.dataServer = sc.get(props, 'dataServer', false);
21
26
  this.getPartials = sc.get(props, 'getPartials', false);
27
+ this.events = sc.get(props, 'events', false);
28
+ this.defaultDomain = sc.get(props, 'defaultDomain', 'default');
29
+ this.projectRoot = sc.get(props, 'projectRoot', './');
30
+ this.publicPath = sc.get(props, 'publicPath', './public');
22
31
  this.jsonFieldsParser = new JsonFieldsParser({entitiesConfig: sc.get(props, 'entitiesConfig', {})});
32
+ this.systemVariablesProvider = new SystemVariablesProvider({
33
+ defaultDomain: this.defaultDomain,
34
+ projectRoot: this.projectRoot,
35
+ publicPath: this.publicPath
36
+ });
23
37
  this.entitiesTransformer = new EntitiesTransformer({
24
38
  dataServer: this.dataServer,
25
39
  jsonFieldsParser: this.jsonFieldsParser,
@@ -31,7 +45,8 @@ class TemplateEngine
31
45
  renderEngine: this.renderEngine,
32
46
  getPartials: this.getPartials,
33
47
  findAllPartialTags: this.findAllPartialTags.bind(this),
34
- loadPartialTemplate: this.loadPartialTemplate.bind(this)
48
+ loadPartialTemplate: this.loadPartialTemplate.bind(this),
49
+ processAllTemplateFunctions: this.processAllTemplateFunctions.bind(this)
35
50
  });
36
51
  this.collectionsTransformer = new CollectionsTransformer({
37
52
  dataServer: this.dataServer,
@@ -39,48 +54,120 @@ class TemplateEngine
39
54
  renderEngine: this.renderEngine,
40
55
  getPartials: this.getPartials,
41
56
  findAllPartialTags: this.findAllPartialTags.bind(this),
42
- loadPartialTemplate: this.loadPartialTemplate.bind(this)
57
+ loadPartialTemplate: this.loadPartialTemplate.bind(this),
58
+ processAllTemplateFunctions: this.processAllTemplateFunctions.bind(this)
43
59
  });
44
60
  this.partialsTransformer = new PartialsTransformer({
45
61
  renderEngine: this.renderEngine,
46
- getPartials: this.getPartials
62
+ getPartials: this.getPartials,
63
+ processAllTemplateFunctions: this.processAllTemplateFunctions.bind(this)
64
+ });
65
+ this.urlTransformer = new UrlTransformer();
66
+ this.assetTransformer = new AssetTransformer();
67
+ this.dateTransformer = new DateTransformer({
68
+ defaultFormat: sc.get(props, 'defaultDateFormat', 'Y-m-d H:i:s')
69
+ });
70
+ this.translateTransformer = new TranslateTransformer({
71
+ projectRoot: this.projectRoot,
72
+ defaultLocale: sc.get(props, 'defaultLocale', 'en'),
73
+ fallbackLocale: sc.get(props, 'fallbackLocale', 'en')
47
74
  });
48
75
  this.transformers = [
49
76
  this.entitiesTransformer,
50
77
  this.collectionsSingleTransformer,
51
78
  this.collectionsTransformer,
52
- this.partialsTransformer
79
+ this.partialsTransformer,
80
+ this.urlTransformer,
81
+ this.assetTransformer,
82
+ this.dateTransformer,
83
+ this.translateTransformer
53
84
  ];
54
85
  }
55
86
 
56
- async processAllTemplateFunctions(template, domain, req)
87
+ async processAllTemplateFunctions(template, domain, req, systemVariables, enhancedData = {})
57
88
  {
58
89
  let processedTemplate = template;
59
90
  for(let transformer of this.transformers){
60
- if(sc.isFunction(transformer.transform)){
61
- processedTemplate = await transformer.transform(processedTemplate, domain, req);
91
+ if(!transformer){
92
+ continue;
62
93
  }
94
+ if(!sc.isFunction(transformer.transform)){
95
+ continue;
96
+ }
97
+ processedTemplate = await transformer.transform(processedTemplate, domain, req, systemVariables, enhancedData);
63
98
  }
64
99
  return processedTemplate;
65
100
  }
66
101
 
67
- async render(template, data, partials, domain, req)
102
+ async render(template, data, partials, domain, req, route, currentEntityData)
68
103
  {
69
104
  if(!this.renderEngine){
70
- Logger.error('Render engine not provided');
105
+ Logger.critical('Render engine not provided');
71
106
  return '';
72
107
  }
73
108
  if(!sc.isFunction(this.renderEngine.render)){
74
- Logger.error('Render engine does not contain a render method');
109
+ Logger.critical('Render engine does not contain a render method');
75
110
  return '';
76
111
  }
77
- return this.renderEngine.render(
78
- this.unescapeHtml(await this.processAllTemplateFunctions(template, domain, req)),
112
+ if(!this.events){
113
+ Logger.critical('Events manager not provided');
114
+ return '';
115
+ }
116
+ let systemVariables = this.systemVariablesProvider.buildSystemVariables(req, route, domain);
117
+ let renderContext = {
118
+ template,
79
119
  data,
120
+ partials,
121
+ domain,
122
+ req,
123
+ route,
124
+ currentEntityData
125
+ };
126
+ let eventData = {
127
+ variables: systemVariables,
128
+ renderContext
129
+ };
130
+ await this.events.emit('reldens.afterVariablesCreated', eventData);
131
+ let enhancedData = this.buildEnhancedRenderData(data, eventData.variables, currentEntityData);
132
+ let beforeProcessData = {
133
+ content: template,
134
+ variables: enhancedData,
135
+ renderContext
136
+ };
137
+ await this.events.emit('reldens.beforeContentProcess', beforeProcessData);
138
+ let processedTemplate = await this.processAllTemplateFunctions(
139
+ beforeProcessData.content,
140
+ domain,
141
+ req,
142
+ eventData.variables,
143
+ enhancedData
144
+ );
145
+ let afterProcessData = {
146
+ processedContent: processedTemplate,
147
+ variables: enhancedData,
148
+ renderContext
149
+ };
150
+ await this.events.emit('reldens.afterContentProcess', afterProcessData);
151
+ return this.renderEngine.render(
152
+ this.unescapeHtml(afterProcessData.processedContent),
153
+ enhancedData,
80
154
  partials
81
155
  );
82
156
  }
83
157
 
158
+ buildEnhancedRenderData(originalData, systemVariables, currentEntityData)
159
+ {
160
+ let enhancedData = Object.assign({}, originalData);
161
+ enhancedData.currentRequest = systemVariables.currentRequest;
162
+ enhancedData.currentRoute = systemVariables.currentRoute;
163
+ enhancedData.currentDomain = systemVariables.currentDomain;
164
+ enhancedData.systemInfo = systemVariables.systemInfo;
165
+ if(currentEntityData){
166
+ enhancedData.currentEntity = currentEntityData;
167
+ }
168
+ return enhancedData;
169
+ }
170
+
84
171
  unescapeHtml(text)
85
172
  {
86
173
  return text