@reldens/cms 0.15.0 → 0.18.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 (38) hide show
  1. package/README.md +150 -34
  2. package/admin/reldens-admin-client.css +39 -23
  3. package/admin/reldens-admin-client.js +7 -0
  4. package/admin/templates/cache-clean-button.html +4 -0
  5. package/admin/templates/edit.html +3 -1
  6. package/admin/templates/fields/view/textarea.html +1 -0
  7. package/admin/templates/sections/editForm/cms-pages.html +15 -0
  8. package/admin/templates/sections/viewForm/cms-pages.html +15 -0
  9. package/admin/templates/view.html +1 -0
  10. package/bin/reldens-cms-generate-entities.js +116 -5
  11. package/bin/reldens-cms.js +26 -8
  12. package/install/js/installer.js +5 -0
  13. package/install/success.html +1 -1
  14. package/lib/admin-manager/contents-builder.js +256 -0
  15. package/lib/admin-manager/router-contents.js +576 -0
  16. package/lib/admin-manager/router.js +208 -0
  17. package/lib/admin-manager.js +114 -944
  18. package/lib/cache/add-cache-button-subscriber.js +101 -0
  19. package/lib/cache/cache-manager.js +129 -0
  20. package/lib/cache/cache-routes-handler.js +76 -0
  21. package/lib/cms-pages-route-manager.js +117 -0
  22. package/lib/frontend.js +207 -64
  23. package/lib/installer.js +44 -20
  24. package/lib/json-fields-parser.js +74 -0
  25. package/lib/manager.js +55 -10
  26. package/lib/template-engine.js +361 -41
  27. package/lib/templates-list.js +10 -0
  28. package/migrations/default-blocks.sql +1 -1
  29. package/migrations/default-entity-access.sql +2 -2
  30. package/migrations/default-homepage.sql +27 -7
  31. package/migrations/install.sql +33 -36
  32. package/package.json +3 -3
  33. package/templates/index.js.dist +3 -3
  34. package/templates/js/scripts.js +5 -0
  35. package/templates/layouts/default.html +4 -4
  36. package/templates/page.html +14 -10
  37. package/templates/partials/footer.html +2 -23
  38. package/templates/partials/header.html +2 -35
@@ -5,59 +5,58 @@ CREATE TABLE IF NOT EXISTS `routes` (
5
5
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
6
6
  `path` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
7
7
  `router` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
8
- `content_id` INT UNSIGNED NOT NULL,
9
- `title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
10
- `meta_description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
11
- `canonical_url` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
12
- `meta_robots` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'index,follow',
13
- `og_title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
14
- `og_description` TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
15
- `og_image` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
16
- `twitter_card_type` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'summary',
17
- `status` VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'published',
18
- `publish_at` TIMESTAMP NULL,
19
- `locale` VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'en',
20
8
  `cache_ttl_seconds` INT UNSIGNED NULL DEFAULT 3600,
9
+ `enabled` TINYINT UNSIGNED NOT NULL DEFAULT '1',
10
+ `domain` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
21
11
  `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
22
12
  `updated_at` TIMESTAMP NOT NULL DEFAULT (NOW()) ON UPDATE CURRENT_TIMESTAMP,
23
13
  PRIMARY KEY (`id`) USING BTREE,
24
- UNIQUE KEY `path` (`path`) USING BTREE
14
+ UNIQUE KEY `path_domain` (`path`, `domain`) USING BTREE
25
15
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
26
16
 
27
- CREATE TABLE IF NOT EXISTS `cms_pages_meta` (
17
+ CREATE TABLE IF NOT EXISTS `cms_categories` (
28
18
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
29
- `page_id` INT UNSIGNED NOT NULL,
30
- `publish_date` TIMESTAMP NULL,
31
- `expire_date` TIMESTAMP NULL,
19
+ `name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
20
+ `title` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
21
+ `enabled` TINYINT UNSIGNED NOT NULL DEFAULT '1',
22
+ `parent_id` INT UNSIGNED NULL DEFAULT NULL,
32
23
  `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
33
24
  `updated_at` TIMESTAMP NOT NULL DEFAULT (NOW()) ON UPDATE CURRENT_TIMESTAMP,
34
25
  PRIMARY KEY (`id`) USING BTREE,
35
- KEY `page_id` (`page_id`) USING BTREE
26
+ INDEX `FK_cms_categories_cms_categories` (`parent_id`) USING BTREE,
27
+ CONSTRAINT `FK_cms_categories_cms_categories` FOREIGN KEY (`parent_id`) REFERENCES `cms_categories` (`id`) ON UPDATE CASCADE ON DELETE NO ACTION
36
28
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
37
29
 
38
30
  CREATE TABLE IF NOT EXISTS `cms_pages` (
39
31
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
40
32
  `title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
41
33
  `content` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
42
- `markdown` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
43
34
  `json_data` JSON NULL,
44
35
  `template` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
45
36
  `layout` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'default',
46
- `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
47
- `updated_at` TIMESTAMP NOT NULL DEFAULT (NOW()) ON UPDATE CURRENT_TIMESTAMP,
48
- PRIMARY KEY (`id`) USING BTREE
49
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
50
-
51
- CREATE TABLE IF NOT EXISTS `entities_meta` (
52
- `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
53
- `entity_name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
54
- `entity_id` INT UNSIGNED NOT NULL,
55
- `meta_key` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
56
- `meta_value` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
37
+ `category_id` INT UNSIGNED NULL DEFAULT NULL,
38
+ `route_id` INT UNSIGNED NULL DEFAULT NULL,
39
+ `enabled` TINYINT UNSIGNED NOT NULL DEFAULT '1',
40
+ `meta_title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
41
+ `meta_description` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
42
+ `meta_robots` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'index,follow',
43
+ `meta_theme_color` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
44
+ `meta_og_title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
45
+ `meta_og_description` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
46
+ `meta_og_image` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
47
+ `meta_twitter_card_type` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'summary',
48
+ `canonical_url` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
49
+ `status` VARCHAR(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'published',
50
+ `locale` VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'en',
51
+ `publish_date` TIMESTAMP NULL,
52
+ `expire_date` TIMESTAMP NULL,
57
53
  `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
58
54
  `updated_at` TIMESTAMP NOT NULL DEFAULT (NOW()) ON UPDATE CURRENT_TIMESTAMP,
59
55
  PRIMARY KEY (`id`) USING BTREE,
60
- UNIQUE KEY `entity_meta` (`entity_name`, `entity_id`, `meta_key`) USING BTREE
56
+ INDEX `FK_cms_pages_cms_categories` (`category_id`) USING BTREE,
57
+ INDEX `FK_cms_pages_routes` (`route_id`) USING BTREE,
58
+ CONSTRAINT `FK_cms_pages_cms_categories` FOREIGN KEY (`category_id`) REFERENCES `cms_categories` (`id`) ON UPDATE CASCADE ON DELETE NO ACTION,
59
+ CONSTRAINT `FK_cms_pages_routes` FOREIGN KEY (`route_id`) REFERENCES `routes` (`id`) ON UPDATE CASCADE ON DELETE SET NULL
61
60
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
62
61
 
63
62
  CREATE TABLE IF NOT EXISTS `cms_blocks` (
@@ -65,19 +64,17 @@ CREATE TABLE IF NOT EXISTS `cms_blocks` (
65
64
  `name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
66
65
  `title` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
67
66
  `content` LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
68
- `template_file` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL,
69
- `variables` JSON NULL,
70
- `is_active` BOOLEAN NOT NULL DEFAULT TRUE,
67
+ `enabled` TINYINT UNSIGNED NOT NULL DEFAULT '1',
71
68
  `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
72
69
  `updated_at` TIMESTAMP NOT NULL DEFAULT (NOW()) ON UPDATE CURRENT_TIMESTAMP,
73
70
  PRIMARY KEY (`id`) USING BTREE,
74
71
  UNIQUE KEY `name` (`name`) USING BTREE
75
72
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
76
73
 
77
- CREATE TABLE IF NOT EXISTS `cms_entity_access` (
74
+ CREATE TABLE IF NOT EXISTS `entities_access` (
78
75
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
79
76
  `entity_name` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
80
- `is_public` BOOLEAN NOT NULL DEFAULT FALSE,
77
+ `is_public` TINYINT UNSIGNED NOT NULL DEFAULT '0',
81
78
  `allowed_operations` JSON NULL DEFAULT ('["read"]'),
82
79
  `access_rules` JSON NULL,
83
80
  `created_at` TIMESTAMP NOT NULL DEFAULT (NOW()),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@reldens/cms",
3
3
  "scope": "@reldens",
4
- "version": "0.15.0",
4
+ "version": "0.18.0",
5
5
  "description": "Reldens - CMS",
6
6
  "author": "Damian A. Pastorini",
7
7
  "license": "MIT",
@@ -33,8 +33,8 @@
33
33
  "url": "https://github.com/damian-pastorini/reldens-cms/issues"
34
34
  },
35
35
  "dependencies": {
36
- "@reldens/server-utils": "^0.18.0",
37
- "@reldens/storage": "^0.51.0",
36
+ "@reldens/server-utils": "^0.19.0",
37
+ "@reldens/storage": "^0.59.0",
38
38
  "@reldens/utils": "^0.50.0",
39
39
  "dotenv": "^16.5.0",
40
40
  "mustache": "^4.2.0"
@@ -7,7 +7,7 @@
7
7
  const { Manager } = require('@reldens/cms');
8
8
  const { Logger } = require('@reldens/utils');
9
9
  const { rawRegisteredEntities, entitiesConfig, entitiesTranslations } = require('./generated-entities/models/{{driverKey}}/registered-models-{{driverKey}}');
10
-
10
+ {{prismaClientImports}}
11
11
  let args = process.argv.slice(2);
12
12
  let projectRoot = args[0] || process.cwd();
13
13
 
@@ -15,7 +15,7 @@ let manager = new Manager({
15
15
  projectRoot,
16
16
  rawRegisteredEntities,
17
17
  entitiesConfig,
18
- entitiesTranslations
18
+ entitiesTranslations{{prismaClientParam}}
19
19
  });
20
20
  Logger.debug('Reldens CMS Manager instance created.', {configuration: manager.config});
21
21
 
@@ -27,6 +27,6 @@ manager.start().then((result) => {
27
27
  Logger.info('Reldens CMS started by command.');
28
28
  return true;
29
29
  }).catch((error) => {
30
- Logger.critical('Failed to start CMS: '+error.message);
30
+ Logger.critical('Failed to start CMS: ' + error.message);
31
31
  process.exit();
32
32
  });
@@ -11,4 +11,9 @@ document.addEventListener('DOMContentLoaded', function() {
11
11
  link.classList.add('active');
12
12
  }
13
13
  }
14
+
15
+ let copyRightYear = document.querySelector('.copyright-year');
16
+ if(copyRightYear){
17
+ copyRightYear.innerHTML = String((new Date()).getFullYear());
18
+ }
14
19
  });
@@ -1,16 +1,16 @@
1
- {{ entity('cmsBlocks', 'header-main', 'name') }}
1
+ <entity name="cmsBlocks" field="name" value="header-main"/>
2
2
 
3
3
  <main id="main" class="main-container">
4
4
  <div class="container">
5
5
  <div class="row">
6
6
  <div class="col-md-3">
7
- {{ entity('cmsBlocks', 'sidebar-left', 'name') }}
7
+ <entity name="cmsBlocks" field="name" value="sidebar-left"/>
8
8
  </div>
9
9
  <div class="col-md-9">
10
- {{{content}}}
10
+ {{&content}}
11
11
  </div>
12
12
  </div>
13
13
  </div>
14
14
  </main>
15
15
 
16
- {{ entity('cmsBlocks', 'footer-main', 'name') }}
16
+ <entity name="cmsBlocks" field="name" value="footer-main"/>
@@ -1,20 +1,24 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="{{locale}}">
3
3
  <head>
4
- <title>{{title}}</title>
4
+ <title>{{meta_title}}</title>
5
5
  <meta charset="utf-8"/>
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes, viewport-fit=cover"/>
7
- <meta name="theme-color" content="#000000"/>
8
- <meta name="description" content="{{description}}"/>
9
- <meta property="og:title" content="{{title}}"/>
10
- <meta property="og:description" content="{{description}}"/>
7
+ <meta name="description" content="{{meta_description}}">
8
+ <meta name="robots" content="{{meta_robots}}">
9
+ <meta name="theme-color" content="{{meta_theme_color}}"/>
10
+ <meta property="og:title" content="{{meta_og_title}}"/>
11
+ <meta property="og:description" content="{{meta_og_description}}"/>
12
+ <meta property="og:image" content="{{meta_og_image}}"/>
13
+ <meta name="twitter:card" content="{{meta_twitter_card_type}}"/>
14
+ <meta name="language" content="{{locale}}"/>
15
+ <meta name="publish-date" content="{{publish_date}}"/>
16
+ <meta name="expire-date" content="{{expire_date}}"/>
17
+ <link rel="canonical" href="{{canonical_url}}"/>
11
18
  <link href="/css/styles.css" rel="stylesheet"/>
12
19
  </head>
13
- <body class="{{siteHandle}}{{#elementClassName}} {{elementClassName}}{{/elementClassName}}"{{#backgroundImage}} style="background-image: url('{{backgroundImage}}');"{{/backgroundImage}}>
14
- {{{content}}}
20
+ <body class="{{siteHandle}}">
21
+ {{&content}}
15
22
  <script type="text/javascript" defer src="/js/scripts.js"></script>
16
- <script type="text/javascript">
17
- const currentYear = {{currentYear}};
18
- </script>
19
23
  </body>
20
24
  </html>
@@ -2,34 +2,13 @@
2
2
  <div class="container top-border">
3
3
  <div class="row">
4
4
  <div class="col-lg-4 col-md-6 footer-contact">
5
- <h3>{{site_name}}</h3>
6
- <p><strong>E-mail:</strong> <a href="mailto:{{contact_email}}">{{contact_email}}</a></p>
5
+ <h3>Your Site Name Here</h3>
7
6
  </div>
8
- <div class="col-lg-4 col-md-6 footer-links">
9
- {{#footer_menu}}
10
- <h4>Useful Links</h4>
11
- <ul>
12
- {{#items}}
13
- <li><a href="{{url}}">{{title}}</a></li>
14
- {{/items}}
15
- </ul>
16
- {{/footer_menu}}
17
- </div>
18
- {{#social_links}}
19
- <div class="col-lg-4 col-md-12 footer-links text-right">
20
- <h4>Networks</h4>
21
- <div class="social-links mt-3">
22
- {{#links}}
23
- <a href="{{url}}" target="_blank"><i class="bx {{icon}}"></i></a>
24
- {{/links}}
25
- </div>
26
- </div>
27
- {{/social_links}}
28
7
  </div>
29
8
  </div>
30
9
  </div>
31
10
  <div class="container footer-bottom clearfix">
32
11
  <div class="copyright">
33
- &copy; Copyright {{currentYear}} <strong><a href="https://www.dwdeveloper.com" target="_blank">DwDeveloper</a></strong>. All Rights Reserved
12
+ &copy; Copyright <span class="copyright-year">2025</span> <strong><a href="https://www.dwdeveloper.com" target="_blank">DwDeveloper</a></strong>. All Rights Reserved
34
13
  </div>
35
14
  </div>
@@ -1,36 +1,3 @@
1
- <div class="container d-flex align-items-center">
2
- <div class="logo{{#is_reldens}} reldens-logo{{/is_reldens}}">
3
- {{#logo_image}}
4
- <a href="{{home_url}}">
5
- <img src="{{logo_image}}" alt="{{site_name}}">
6
- </a>
7
- {{/logo_image}}
8
- {{^logo_image}}
9
- <a href="{{home_url}}">{{site_name}}</a>
10
- {{/logo_image}}
11
- </div>
12
- {{#menu_items}}
13
- <nav class="nav-menu d-none d-lg-block">
14
- <ul>
15
- {{#items}}
16
- <li{{#has_children}} class="drop-down"{{/has_children}}>
17
- <a href="{{url}}"{{#is_external}} target="_blank"{{/is_external}}>{{title}}</a>
18
- {{#has_children}}
19
- <ul>
20
- {{#children}}
21
- <li>
22
- <a href="{{url}}"{{#is_external}} target="_blank"{{/is_external}}>{{title}}</a>
23
- </li>
24
- {{/children}}
25
- </ul>
26
- {{/has_children}}
27
- </li>
28
- {{/items}}
29
- </ul>
30
- </nav>
31
- {{/menu_items}}
32
- <form class="search" action="/search" method="get">
33
- <input type="search" class="quicksearch" name="q" value="{{search_query}}" placeholder="Search..."/>
34
- <button type="submit"><i class="bx bx-search"></i></button>
35
- </form>
1
+ <div class="container">
2
+ <a href="/">Your Site Name Here</a>
36
3
  </div>