@reldens/cms 0.9.0 → 0.11.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/README.md CHANGED
@@ -1,112 +1,354 @@
1
1
  [![Reldens - GitHub - Release](https://www.dwdeveloper.com/media/reldens/reldens-mmorpg-platform.png)](https://github.com/damian-pastorini/reldens)
2
2
 
3
- # Reldens - CMS
3
+ # Reldens CMS
4
4
 
5
- ## About
6
-
7
- Reldens CMS is a straightforward content management system designed for easy setup and extensibility.
8
- It provides both an administration panel for content management and a frontend for content delivery.
5
+ A powerful, flexible Content Management System built with Node.js, featuring an admin panel, multi-domain frontend support, enhanced templating with reusable content blocks, and automated installation.
9
6
 
10
7
  ## Features
11
8
 
12
- - Simple installation process
13
- - Administration panel for content management
14
- - Support for multiple database drivers (Prisma, Objection.js)
15
- - Template-based content rendering
16
- - SEO-friendly routes and meta-data
17
- - Modular architecture
9
+ ### - Quick Setup
10
+ - **Web-based installer** with a guided setup process
11
+ - **Automatic database schema creation** and seeding
12
+ - **Environment configuration generation**
13
+ - **Directory structure initialization**
14
+
15
+ ### - Frontend Engine
16
+ - **Multi-domain support** with domain-specific templates and partials
17
+ - **Dynamic routing** from database-driven routes
18
+ - **Entity-based URLs** (e.g., `/articles/123`)
19
+ - **Template fallback system** (domain → default → base)
20
+ - **Layout system** with body content layouts and page wrappers
21
+ - **Reusable content blocks** with `{{ entity() }}` template functions
22
+ - **Entity access control** for public/private content
23
+ - **Static asset serving** with Express integration as default
24
+ - **Template engine** with Mustache integration as default
25
+ - **Custom 404 handling**
26
+
27
+ ### - Admin Panel
28
+ - **Full CRUD operations** for all entities including content blocks
29
+ - **File upload handling** with multiple storage buckets
30
+ - **Role-based authentication** and access control
31
+ - **Advanced filtering and search** across entity properties
32
+ - **Bulk operations** (delete multiple records)
33
+ - **Relationship management** with foreign key support
34
+ - **Template-driven UI** with customizable admin themes
35
+
36
+ ### -️ Database & Entities
37
+ - **Multiple database drivers** (Prisma by default, others via DriversMap)
38
+ - **Automatic entity generation** from a database schema
39
+ - **Relationship mapping** and foreign key handling
40
+ - **Custom entity configuration** with validation rules
41
+ - **Translation support** for entity labels and properties
42
+ - **Content blocks management** via cms_blocks table
43
+ - **Entity access control** via cms_entity_access table
44
+
45
+ ### - Configuration & Architecture
46
+ - **Environment-based configuration** (.env file)
47
+ - **Modular service architecture** (Frontend, AdminManager, DataServer)
48
+ - **Event-driven system** with hooks for customization
49
+ - **Extensible authentication** (database users or custom callbacks)
50
+ - **File security** with path validation and dangerous key filtering
18
51
 
19
52
  ## Installation
20
53
 
21
- ### Option 1: NPX Installation (Recommended)
22
-
23
- The easiest way to install Reldens CMS is using NPX:
24
-
54
+ ### Method 1: Automated Web Installer
25
55
  ```bash
26
- npx @reldens/cms [directory]
56
+ npx reldens-cms
27
57
  ```
58
+ Navigate to `http://localhost:8080` and follow the installation wizard.
28
59
 
29
- This will start the installer in your browser, allowing you to configure your CMS installation.
30
-
31
- ### Option 2: Manual Installation
60
+ ### Method 2: Manual Setup
61
+ ```javascript
62
+ const { Manager } = require('@reldens/cms');
32
63
 
33
- 1. Install the package:
64
+ const cms = new Manager({
65
+ projectRoot: process.cwd(),
66
+ entityAccess: {
67
+ cmsPages: { public: true, operations: ['read'] },
68
+ products: { public: true, operations: ['read'] },
69
+ users: { public: false }
70
+ }
71
+ });
34
72
 
35
- ```bash
36
- npm install @reldens/cms
73
+ cms.start();
37
74
  ```
38
75
 
39
- 2. Create a basic implementation:
76
+ ## Configuration
77
+
78
+ ### Environment Variables
79
+ ```env
80
+ RELDENS_APP_HOST=http://localhost
81
+ RELDENS_APP_PORT=8080
82
+ RELDENS_ADMIN_ROUTE_PATH=/admin
83
+ RELDENS_ADMIN_SECRET=your-secret-key
84
+
85
+ RELDENS_DB_CLIENT=mysql
86
+ RELDENS_DB_HOST=localhost
87
+ RELDENS_DB_PORT=3306
88
+ RELDENS_DB_NAME=cms_db
89
+ RELDENS_DB_USER=username
90
+ RELDENS_DB_PASSWORD=password
91
+ RELDENS_STORAGE_DRIVER=prisma
92
+
93
+ RELDENS_DEFAULT_DOMAIN=example.com
94
+ RELDENS_DOMAIN_MAPPING={"dev.example.com":"development"}
95
+ RELDENS_SITE_KEY_MAPPING={"example.com":"main"}
96
+ ```
40
97
 
98
+ ### Custom Entity Configuration
41
99
  ```javascript
42
- const { Manager } = require('@reldens/cms');
100
+ const entityConfig = {
101
+ articles: {
102
+ listProperties: ['title', 'status', 'created_at'],
103
+ showProperties: ['title', 'content', 'author', 'status'],
104
+ editProperties: ['title', 'content', 'author_id', 'status'],
105
+ filterProperties: ['status', 'author_id'],
106
+ titleProperty: 'title',
107
+ parentItemLabel: 'Content',
108
+ properties: {
109
+ title: { type: 'string', isRequired: true },
110
+ content: { type: 'text' },
111
+ author_id: { type: 'reference', reference: 'users' },
112
+ featured_image: {
113
+ type: 'string',
114
+ isUpload: true,
115
+ allowedTypes: 'image',
116
+ bucket: 'uploads'
117
+ }
118
+ }
119
+ }
120
+ };
43
121
 
44
- const manager = new Manager({
45
- projectRoot: './your-project-root',
46
- authenticationMethod: 'db-users' // or 'callback'
122
+ const cms = new Manager({
123
+ entitiesConfig: entityConfig
47
124
  });
48
-
49
- manager.start().catch(console.error);
50
125
  ```
51
126
 
52
- ## Authentication Methods
127
+ ## Enhanced Templating System
53
128
 
54
- Reldens CMS supports two authentication methods:
129
+ ### Template Functions
130
+ Templates now support dynamic content blocks and entity rendering:
131
+ ```html
132
+ <!-- Render content blocks -->
133
+ {{ entity('cms_blocks', 'header-main') }}
134
+ {{ entity('cms_blocks', 'sidebar-left') }}
55
135
 
56
- 1. **db-users**: Uses the built-in users table for authentication
57
- 2. **callback**: Use a custom authentication function
136
+ <!-- Render other entities -->
137
+ {{ entity('products', '123') }}
138
+ {{ entity('cms_pages', '1') }}
139
+ ```
58
140
 
59
- Example with custom authentication:
141
+ ### Layout System
142
+ The CMS uses a two-tier layout system:
143
+
144
+ **page.html** - Full HTML wrapper:
145
+ ```html
146
+ <!DOCTYPE html>
147
+ <html lang="{{locale}}">
148
+ <head>
149
+ <title>{{title}}</title>
150
+ <meta name="description" content="{{description}}"/>
151
+ <link href="/css/styles.css" rel="stylesheet"/>
152
+ </head>
153
+ <body class="{{siteHandle}}">
154
+ {{{content}}}
155
+ <script src="/js/scripts.js"></script>
156
+ </body>
157
+ </html>
158
+ ```
60
159
 
160
+ **layouts/default.html** - Body content only:
161
+ ```html
162
+ {{ entity('cms_blocks', 'header-main') }}
163
+
164
+ <main id="main" class="main-container">
165
+ <div class="container">
166
+ <div class="row">
167
+ <div class="col-md-3">
168
+ {{ entity('cms_blocks', 'sidebar-left') }}
169
+ </div>
170
+ <div class="col-md-9">
171
+ {{{content}}}
172
+ </div>
173
+ </div>
174
+ </div>
175
+ </main>
176
+
177
+ {{ entity('cms_blocks', 'footer-main') }}
178
+ ```
179
+
180
+ Pages can use different layouts by setting the `layout` field in `cms_pages`:
181
+ - `default` - Header, sidebar, main content, footer
182
+ - `full-width` - Full width without sidebars
183
+ - `minimal` - Basic layout with minimal styling
184
+
185
+ ### Content Blocks
186
+ Create reusable content blocks in the `cms_blocks` table via admin panel:
187
+ ```sql
188
+ INSERT INTO cms_blocks (name, title, content) VALUES
189
+ ('contact-info', 'Contact Information', '<p>Email: info@example.com</p>'),
190
+ ('product-sidebar', 'Product Categories',
191
+ '<div class="categories"><h3>Categories</h3><ul><li><a href="/products/electronics">Electronics</a></li></ul></div>');
192
+ ```
193
+
194
+ ### Entity Access Control
195
+ Control which entities are publicly accessible:
61
196
  ```javascript
62
- const manager = new Manager({
63
- authenticationMethod: 'callback',
64
- authenticationCallback: async (email, password, roleId) => {
65
- // Your custom authentication logic
66
- // Must return a user object or false
197
+ const cms = new Manager({
198
+ entityAccess: {
199
+ products: { public: true, operations: ['read'] },
200
+ cmsPages: { public: true, operations: ['read'] },
201
+ users: { public: false }
67
202
  }
68
203
  });
69
204
  ```
70
205
 
71
- ## Extending with Custom Entities
206
+ ## Multi-Domain Setup
207
+
208
+ ### Directory Structure
209
+ ```
210
+ templates/
211
+ ├── layouts/
212
+ │ ├── default.html # Body content layouts
213
+ │ ├── full-width.html
214
+ │ └── minimal.html
215
+ ├── domains/
216
+ │ ├── example.com/
217
+ │ │ ├── layouts/ # Domain-specific layouts
218
+ │ │ ├── partials/
219
+ │ │ │ ├── header.html
220
+ │ │ │ └── footer.html
221
+ │ │ ├── page.html # Domain-specific page wrapper
222
+ │ │ └── index.html
223
+ │ └── dev.example.com/
224
+ │ └── page.html
225
+ ├── partials/
226
+ │ ├── header.html (default)
227
+ │ └── footer.html (default)
228
+ ├── page.html (base HTML wrapper)
229
+ └── 404.html
230
+ ```
231
+
232
+ ## Advanced Usage
72
233
 
73
- You can extend the CMS with your own entities:
234
+ ### Custom Authentication
235
+ ```javascript
236
+ const customAuth = async (email, password, roleId) => {
237
+ const user = await yourAuthService.authenticate(email, password);
238
+ return user && user.role_id === roleId ? user : false;
239
+ };
240
+
241
+ const cms = new Manager({
242
+ authenticationMethod: 'custom',
243
+ authenticationCallback: customAuth
244
+ });
245
+ ```
74
246
 
247
+ ### File Upload Configuration
75
248
  ```javascript
76
- const manager = new Manager({
77
- entities: {
78
- products: {
79
- config: {
80
- listProperties: ['id', 'name', 'price', 'status'],
81
- showProperties: ['id', 'name', 'price', 'description', 'status', 'created_at'],
82
- filterProperties: ['name', 'status'],
83
- editProperties: ['name', 'price', 'description', 'status'],
84
- properties: {
85
- id: { isId: true },
86
- name: { isRequired: true },
87
- price: { type: 'number', isRequired: true },
88
- description: { type: 'textarea' },
89
- status: { type: 'boolean' },
90
- created_at: { type: 'datetime' }
91
- },
92
- titleProperty: 'name',
93
- navigationPosition: 100
94
- }
95
- }
249
+ const uploadConfig = {
250
+ mimeTypes: {
251
+ image: ['image/jpeg', 'image/png', 'image/webp'],
252
+ document: ['application/pdf', 'text/plain']
253
+ },
254
+ allowedExtensions: {
255
+ image: ['.jpg', '.jpeg', '.png', '.webp'],
256
+ document: ['.pdf', '.txt']
96
257
  }
258
+ };
259
+
260
+ const cms = new Manager(uploadConfig);
261
+ ```
262
+
263
+ ### Event Hooks
264
+ ```javascript
265
+ cms.events.on('reldens.setupAdminRoutes', ({adminManager}) => {
266
+ // Add custom admin routes
267
+ adminManager.adminRouter.get('/custom', (req, res) => {
268
+ res.send('Custom admin page');
269
+ });
270
+ });
271
+
272
+ cms.events.on('adminEntityExtraData', ({entitySerializedData, entity}) => {
273
+ // Add extra data to admin views
274
+ entitySerializedData.customField = 'Custom Value';
97
275
  });
98
276
  ```
99
277
 
100
- ## Templates
278
+ ## Default database Schema
279
+
280
+ ### Core Tables
281
+ - `routes` - URL routing and SEO metadata
282
+ - `cms_pages` - Page content with layout assignments
283
+ - `cms_blocks` - Reusable content blocks
284
+ - `cms_entity_access` - Entity access control rules
285
+ - `entities_meta` - Generic metadata storage
286
+ - `cms_pages_meta` - Page-specific metadata
287
+
288
+ ### Installation Options
289
+ The installer provides checkboxes for:
290
+ - CMS core tables
291
+ - User authentication system
292
+ - Default admin user
293
+ - Default homepage
294
+ - Default content blocks
295
+ - Entity access control rules
296
+
297
+ ## API Reference
298
+
299
+ ### Manager Class
300
+ - `start()` - Initialize and start the CMS
301
+ - `isInstalled()` - Check if CMS is installed
302
+ - `initializeServices()` - Initialize all services
303
+
304
+ ### Frontend Class
305
+ - `initialize()` - Setup frontend routes and templates
306
+ - `handleRequest(req, res)` - Main request handler
307
+ - `findRouteByPath(path)` - Database route lookup
308
+ - `findEntityByPath(path)` - Entity-based URL handling
309
+ - `processCustomTemplateFunctions(template)` - Process {{ entity() }} functions
310
+
311
+ ### AdminManager Class
312
+ - `setupAdmin()` - Initialize admin panel
313
+ - `generateListRouteContent()` - Entity list pages
314
+ - `generateEditRouteContent()` - Entity edit forms
315
+ - `processSaveEntity()` - Handle form submissions
316
+
317
+ ### Installer Class
318
+ - `prepareSetup()` - Setup installation routes
319
+ - `executeInstallProcess()` - Run installation
320
+ - `generateEntities()` - Create entity files
321
+
322
+ ## File Structure
101
323
 
102
- Reldens CMS uses templates for rendering content. Templates are stored in the `templates` directory and use Mustache for rendering.
324
+ ```
325
+ project/
326
+ ├── admin/
327
+ │ └── templates/ # Admin panel templates
328
+ ├── templates/
329
+ │ ├── layouts/ # Body content layouts
330
+ │ ├── domains/ # Domain-specific templates
331
+ │ ├── partials/ # Shared template partials
332
+ │ ├── page.html # Base HTML wrapper
333
+ │ └── 404.html # Error page
334
+ ├── public/
335
+ │ ├── css/ # Stylesheets
336
+ │ ├── js/ # Client scripts
337
+ │ └── assets/ # Static assets
338
+ ├── entities/ # Generated entity classes
339
+ ├── .env # Environment configuration
340
+ ├── install.lock # Installation lock file
341
+ └── index.js # Main application file
342
+ ```
103
343
 
104
- Default templates include:
105
- - `layout.html`: The main layout template
106
- - `page.html`: Default page template
107
- - `404.html`: Not found page
344
+ ---
108
345
 
109
- You can create custom templates for different content types or override the default ones.
346
+ ## Contributing
347
+
348
+ 1. Fork the repository
349
+ 2. Create a feature branch
350
+ 3. Follow the coding standards in the JavaScript rules
351
+ 4. Submit a pull request
110
352
 
111
353
  ---
112
354
 
@@ -120,6 +362,12 @@ Need something specific?
120
362
 
121
363
  ---
122
364
 
365
+ ## License
366
+
367
+ MIT License - see LICENSE file for details.
368
+
369
+ ---
370
+
123
371
  ### [Reldens](https://github.com/damian-pastorini/reldens/ "Reldens")
124
372
 
125
373
  ##### [By DwDeveloper](https://www.dwdeveloper.com/ "DwDeveloper")
@@ -313,6 +313,11 @@
313
313
  }
314
314
  }
315
315
 
316
+ & textarea {
317
+ resize: vertical;
318
+ min-height: 300px;
319
+ }
320
+
316
321
  & .table-container {
317
322
  width: 96%;
318
323
  margin: auto;
@@ -1 +1 @@
1
- <input type="text" name="{{&fieldName}}" id="{{&fieldName}}" value="{{fieldValue}}"{{&required}}{{&fieldDisabled}}/>
1
+ <input type="{{&inputType}}" name="{{&fieldName}}" id="{{&fieldName}}" value="{{fieldValue}}"{{&required}}{{&fieldDisabled}}/>
@@ -40,6 +40,14 @@ body {
40
40
  margin-bottom: 15px;
41
41
  }
42
42
 
43
+ .input-checkbox {
44
+ display: flex;
45
+
46
+ label {
47
+ margin-bottom: 0;
48
+ }
49
+ }
50
+
43
51
  label {
44
52
  display: block;
45
53
  margin-bottom: 5px;
@@ -32,7 +32,7 @@
32
32
  </div>
33
33
  <div class="input-box app-admin-secret">
34
34
  <label for="app-admin-secret">Admin Panel Secret</label>
35
- <input type="text" name="app-admin-secret" id="app-admin-secret" value="{{app-admin-secret}}"/>
35
+ <input type="text" name="app-admin-secret" id="app-admin-secret" value="{{app-admin-secret}}" required/>
36
36
  </div>
37
37
  <div class="input-box app-error">
38
38
  <p class="error installation-process-failed">There was an error during the installation process.</p>
@@ -77,25 +77,33 @@
77
77
  <p class="error db-installation-process-failed">There was an error during the installation process.</p>
78
78
  </div>
79
79
  <h3 class="form-title">Installation Options</h3>
80
- <div class="input-box install-cms-tables">
80
+ <div class="input-box input-checkbox install-cms-tables">
81
81
  <input type="checkbox" name="install-cms-tables" id="install-cms-tables" checked/>
82
82
  <label for="install-cms-tables">Install default CMS pages tables</label>
83
83
  </div>
84
- <div class="input-box install-user-auth">
84
+ <div class="input-box input-checkbox install-user-auth">
85
85
  <input type="checkbox" name="install-user-auth" id="install-user-auth" checked/>
86
86
  <label for="install-user-auth">Install users authentication</label>
87
87
  </div>
88
- <div class="input-box install-default-user">
88
+ <div class="input-box input-checkbox install-default-user">
89
89
  <input type="checkbox" name="install-default-user" id="install-default-user" checked/>
90
90
  <label for="install-default-user">Install default admin user (root@cms-admin.com / root)</label>
91
91
  </div>
92
- <div class="input-box install-default-homepage">
92
+ <div class="input-box input-checkbox install-default-homepage">
93
93
  <input type="checkbox" name="install-default-homepage" id="install-default-homepage" checked/>
94
94
  <label for="install-default-homepage">Install default homepage</label>
95
95
  </div>
96
+ <div class="input-box input-checkbox install-default-blocks">
97
+ <input type="checkbox" name="install-default-blocks" id="install-default-blocks" checked/>
98
+ <label for="install-default-blocks">Install default content blocks</label>
99
+ </div>
100
+ <div class="input-box input-checkbox install-entity-access">
101
+ <input type="checkbox" name="install-entity-access" id="install-entity-access" checked/>
102
+ <label for="install-entity-access">Install entity access control rules</label>
103
+ </div>
96
104
  <div class="input-box submit-container">
97
- <img class="install-loading hidden" src="/install-assets/img/loading.gif"/>
98
105
  <input id="install-submit-button" type="submit" value="Install"/>
106
+ <img class="install-loading hidden" src="/install-assets/img/loading.gif"/>
99
107
  </div>
100
108
  <div class="input-box response-error"></div>
101
109
  </form>
@@ -1,36 +1,38 @@
1
1
  <!DOCTYPE html>
2
- <html>
2
+ <html lang="en">
3
3
  <head>
4
4
  <title>Reldens CMS - Installation</title>
5
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
6
- <link rel="stylesheet" href="/install-assets/css/installer.css">
7
- <script src="/install-assets/js/installer.js"></script>
5
+ <meta charset="utf-8"/>
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
+ <link rel="stylesheet" href="/install-assets/css/installer.css"/>
8
9
  </head>
9
10
  <body>
10
- <div class="wrapper">
11
- <div class="header">
12
- <h1 class="title">
13
- <strong>Reldens CMS</strong> - Installation
14
- </h1>
15
- </div>
16
- <div class="content">
17
- <div class="forms-container">
18
- <div class="row">
19
- Installation completed!
20
- <p>
21
- Default data<br/>
22
- username: root
23
- email: root@cms-admin.com
24
- password: root
25
- </p>
11
+ <div class="wrapper">
12
+ <div class="header">
13
+ <h1 class="title">
14
+ <strong>Reldens CMS</strong> - Installation
15
+ </h1>
16
+ </div>
17
+ <div class="content">
18
+ <div class="forms-container">
19
+ <div class="row">
20
+ Installation completed!
21
+ <p>
22
+ Default data<br/>
23
+ username: root
24
+ email: root@cms-admin.com
25
+ password: root
26
+ </p>
27
+ </div>
26
28
  </div>
27
29
  </div>
28
- </div>
29
- <div class="footer">
30
- <div class="copyright">
31
- &copy; 2025 Reldens CMS
30
+ <div class="footer">
31
+ <div class="copyright">
32
+ &copy;{{currentYear}} Reldens CMS
33
+ </div>
32
34
  </div>
33
35
  </div>
34
- </div>
36
+ <script type="text/javascript" defer src="/install-assets/js/installer.js"/>
35
37
  </body>
36
38
  </html>