cyber-elx 1.0.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/DEV_DOC.md +567 -0
- package/ELX_PAGES.md +186 -0
- package/README.md +92 -0
- package/bin/cyber-elx.js +3 -0
- package/package.json +27 -0
- package/src/api.js +35 -0
- package/src/cache.js +53 -0
- package/src/config.js +57 -0
- package/src/files.js +114 -0
- package/src/index.js +314 -0
- package/src/prompts.js +70 -0
package/ELX_PAGES.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# ELX Custom Pages API Documentation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
These endpoints allow you to retrieve and update custom ELX (E-Learning Experience) pages. The pages are Liquid templates that can be customized for different sections of the e-learning platform.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Authentication
|
|
10
|
+
|
|
11
|
+
All endpoints require authentication. You must include the `_token` header in your requests.
|
|
12
|
+
|
|
13
|
+
**Required Header:**
|
|
14
|
+
|
|
15
|
+
| Header | Description |
|
|
16
|
+
|--------|-------------|
|
|
17
|
+
| `_token` | Your authentication token |
|
|
18
|
+
|
|
19
|
+
**Unauthorized Response (403):**
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"success": false,
|
|
24
|
+
"message": "Unauthorized"
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
> **Note:** Only users with `admin` role can access these endpoints.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Endpoints
|
|
33
|
+
|
|
34
|
+
### 1. Get ELX Pages
|
|
35
|
+
|
|
36
|
+
Retrieves all custom ELX pages.
|
|
37
|
+
|
|
38
|
+
**URL:** `GET https://domain_name.com/api/plugin_api/el-x/get_elx_pages`
|
|
39
|
+
|
|
40
|
+
**Response:**
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"success": true,
|
|
45
|
+
"pages": [
|
|
46
|
+
{
|
|
47
|
+
"type": "template", // "template" or "section"
|
|
48
|
+
"key": "home_page",
|
|
49
|
+
"content": "<!-- Liquid template content -->",
|
|
50
|
+
"created_at": 123456798,
|
|
51
|
+
"updated_at": 123456798
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"type": "template", // "template" or "section"
|
|
55
|
+
"key": "courses_page",
|
|
56
|
+
"content": "<!-- Liquid template content -->",
|
|
57
|
+
"created_at": 123456798,
|
|
58
|
+
"updated_at": 123456798
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Default Page Keys (Templates):**
|
|
65
|
+
|
|
66
|
+
| Key | Description |
|
|
67
|
+
|-----|-------------|
|
|
68
|
+
| `home_page` | Home page template |
|
|
69
|
+
| `courses_page` | Courses listing page template |
|
|
70
|
+
| `course_page` | Single course page template |
|
|
71
|
+
| `about_page` | About page template |
|
|
72
|
+
| `category_page` | Category page template |
|
|
73
|
+
| `blogs_page` | Blogs listing page template |
|
|
74
|
+
| `blog_page` | Single blog page template |
|
|
75
|
+
| `contact_page` | Contact page template |
|
|
76
|
+
|
|
77
|
+
- The API may return sections or more pages, so if detected just created them locally, and when updating, update the sections and pages.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
### 2. Update ELX Pages
|
|
82
|
+
|
|
83
|
+
Updates one or more custom ELX pages.
|
|
84
|
+
|
|
85
|
+
**URL:** `POST https://domain_name.com/api/plugin_api/el-x/update_elx_pages`
|
|
86
|
+
|
|
87
|
+
**Request Body:**
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{
|
|
91
|
+
"pages": [
|
|
92
|
+
{
|
|
93
|
+
"type": "template", // "template" or "section"
|
|
94
|
+
"key": "home_page",
|
|
95
|
+
"content": "<!-- Your custom Liquid template -->"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"type": "template", // "template" or "section"
|
|
99
|
+
"key": "courses_page",
|
|
100
|
+
"content": "<!-- Your custom Liquid template -->"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Allowed Page Keys:**
|
|
107
|
+
|
|
108
|
+
- `home_page`
|
|
109
|
+
- `courses_page`
|
|
110
|
+
- `course_page`
|
|
111
|
+
- `about_page`
|
|
112
|
+
- `category_page`
|
|
113
|
+
- `blogs_page`
|
|
114
|
+
- `blog_page`
|
|
115
|
+
- `contact_page`
|
|
116
|
+
|
|
117
|
+
**Response (Success):**
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"success": true,
|
|
122
|
+
"message": "Pages updated successfully",
|
|
123
|
+
"updatedpages": [
|
|
124
|
+
{
|
|
125
|
+
"type": "template", // "template" or "section"
|
|
126
|
+
"key": "home_page",
|
|
127
|
+
"content": "<!-- Your custom Liquid template -->",
|
|
128
|
+
"created_at": 123456798,
|
|
129
|
+
"updated_at": 123456798
|
|
130
|
+
},
|
|
131
|
+
...
|
|
132
|
+
]
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Response (No valid pages):**
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"success": true,
|
|
141
|
+
"message": "No pages to update, Allowed pages are 0",
|
|
142
|
+
"updatedpages": []
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
### 3. Get ELX Default Pages (As an example for the user)
|
|
149
|
+
|
|
150
|
+
Retrieves all default ELX pages.
|
|
151
|
+
|
|
152
|
+
**URL:** `GET https://domain_name.com/api/plugin_api/el-x/get_defaults_for_elx_pages`
|
|
153
|
+
|
|
154
|
+
**Response:**
|
|
155
|
+
|
|
156
|
+
```json
|
|
157
|
+
{
|
|
158
|
+
"success": true,
|
|
159
|
+
"pages": [
|
|
160
|
+
{
|
|
161
|
+
"type": "template", // "template" or "section"
|
|
162
|
+
"key": "home_page",
|
|
163
|
+
"content": "<!-- Liquid template content -->",
|
|
164
|
+
"created_at": 123456798,
|
|
165
|
+
"updated_at": 123456798
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"type": "template", // "template" or "section"
|
|
169
|
+
"key": "courses_page",
|
|
170
|
+
"content": "<!-- Liquid template content -->",
|
|
171
|
+
"created_at": 123456798,
|
|
172
|
+
"updated_at": 123456798
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
- The API will return all defaults (Defaults may change in the future at any given time)
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Behavior Notes
|
|
183
|
+
|
|
184
|
+
1. **Empty Content:** Pages with empty or whitespace-only content will be skipped during update.
|
|
185
|
+
|
|
186
|
+
2. **Validation:** Only pages with keys matching the allowed list will be processed. Invalid keys are silently ignored.
|
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# cyber-elx
|
|
2
|
+
|
|
3
|
+
CLI tool to upload/download ELX custom pages (Liquid templates).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g .
|
|
9
|
+
# or
|
|
10
|
+
npm link
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Initialize a new project
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd /path/to/your/project
|
|
19
|
+
cyber-elx init
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This will:
|
|
23
|
+
1. Prompt for your website URL and authentication token
|
|
24
|
+
2. Create `cyber-elx.jsonc` config file
|
|
25
|
+
3. Download all pages from the server
|
|
26
|
+
|
|
27
|
+
### Download pages
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cyber-elx download
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Downloads pages from the server. If local files have been modified, you'll be prompted before overwriting.
|
|
34
|
+
|
|
35
|
+
Options:
|
|
36
|
+
- `-f, --force` - Force download without confirmation prompts
|
|
37
|
+
|
|
38
|
+
### Upload pages
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cyber-elx upload
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Uploads local pages to the server. If server pages have been modified since last download, you'll be prompted before overwriting.
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
- `-f, --force` - Force upload without confirmation prompts
|
|
48
|
+
|
|
49
|
+
## Folder Structure
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
your-project/
|
|
53
|
+
├── cyber-elx.jsonc # Config file (url + token)
|
|
54
|
+
├── .cache # Timestamps cache (auto-generated)
|
|
55
|
+
├── layouts/ # Custom layouts (*.liquid)
|
|
56
|
+
├── sections/ # Custom sections (*.liquid)
|
|
57
|
+
├── templates/ # Custom templates (*.liquid)
|
|
58
|
+
└── defaults/ # Read-only default templates
|
|
59
|
+
├── sections/
|
|
60
|
+
└── templates/
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Config File
|
|
64
|
+
|
|
65
|
+
The `cyber-elx.jsonc` file contains your website URL and authentication token:
|
|
66
|
+
|
|
67
|
+
```jsonc
|
|
68
|
+
{
|
|
69
|
+
// ELX Custom Pages Configuration
|
|
70
|
+
"url": "https://my-website.net",
|
|
71
|
+
"token": "your-auth-token"
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Default Templates
|
|
76
|
+
|
|
77
|
+
The `defaults/` folder contains read-only copies of the default templates. Use these as reference when creating your custom pages. If a custom page is empty, the default will be used automatically by the server.
|
|
78
|
+
|
|
79
|
+
## Available Page Keys
|
|
80
|
+
|
|
81
|
+
### Templates
|
|
82
|
+
- `home_page` - Home page
|
|
83
|
+
- `courses_page` - Courses listing
|
|
84
|
+
- `course_page` - Single course
|
|
85
|
+
- `about_page` - About page
|
|
86
|
+
- `category_page` - Category page
|
|
87
|
+
- `blogs_page` - Blogs listing
|
|
88
|
+
- `blog_page` - Single blog
|
|
89
|
+
- `contact_page` - Contact page
|
|
90
|
+
|
|
91
|
+
### Sections
|
|
92
|
+
Additional sections may be available depending on your server configuration.
|
package/bin/cyber-elx.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cyber-elx",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool to upload/download ELX custom pages",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cyber-elx": "./bin/cyber-elx.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"elx",
|
|
14
|
+
"cli",
|
|
15
|
+
"liquid",
|
|
16
|
+
"templates"
|
|
17
|
+
],
|
|
18
|
+
"author": "",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"axios": "^1.6.0",
|
|
22
|
+
"chalk": "^4.1.2",
|
|
23
|
+
"commander": "^11.1.0",
|
|
24
|
+
"inquirer": "^8.2.6",
|
|
25
|
+
"jsonc-parser": "^3.2.0"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/api.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const axios = require('axios');
|
|
2
|
+
|
|
3
|
+
function createApiClient(config) {
|
|
4
|
+
const client = axios.create({
|
|
5
|
+
baseURL: config.url,
|
|
6
|
+
headers: {
|
|
7
|
+
'_token': config.token,
|
|
8
|
+
'Content-Type': 'application/json'
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
async getPages() {
|
|
14
|
+
const response = await client.get('/api/plugin_api/el-x/get_elx_pages');
|
|
15
|
+
return response.data;
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
async updatePages(pages) {
|
|
19
|
+
try {
|
|
20
|
+
const response = await client.post('/api/plugin_api/el-x/update_elx_pages', { pages });
|
|
21
|
+
return response.data;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error(error);
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
async getDefaultPages() {
|
|
29
|
+
const response = await client.get('/api/plugin_api/el-x/get_defaults_for_elx_pages');
|
|
30
|
+
return response.data;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = { createApiClient };
|
package/src/cache.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const CACHE_FILE = '.cache';
|
|
5
|
+
|
|
6
|
+
function getCachePath(cwd = process.cwd()) {
|
|
7
|
+
return path.join(cwd, CACHE_FILE);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function readCache(cwd = process.cwd()) {
|
|
11
|
+
const cachePath = getCachePath(cwd);
|
|
12
|
+
if (!fs.existsSync(cachePath)) {
|
|
13
|
+
return { pages: {} };
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const content = fs.readFileSync(cachePath, 'utf-8');
|
|
17
|
+
return JSON.parse(content);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
return { pages: {} };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function writeCache(cache, cwd = process.cwd()) {
|
|
24
|
+
const cachePath = getCachePath(cwd);
|
|
25
|
+
fs.writeFileSync(cachePath, JSON.stringify(cache, null, 2), 'utf-8');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function getPageCacheKey(type, key) {
|
|
29
|
+
return `${type}:${key}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getPageTimestamp(cache, type, key) {
|
|
33
|
+
const cacheKey = getPageCacheKey(type, key);
|
|
34
|
+
return cache.pages[cacheKey]?.updated_at || null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function setPageTimestamp(cache, type, key, updated_at) {
|
|
38
|
+
const cacheKey = getPageCacheKey(type, key);
|
|
39
|
+
if (!cache.pages) {
|
|
40
|
+
cache.pages = {};
|
|
41
|
+
}
|
|
42
|
+
cache.pages[cacheKey] = { updated_at };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = {
|
|
46
|
+
CACHE_FILE,
|
|
47
|
+
getCachePath,
|
|
48
|
+
readCache,
|
|
49
|
+
writeCache,
|
|
50
|
+
getPageCacheKey,
|
|
51
|
+
getPageTimestamp,
|
|
52
|
+
setPageTimestamp
|
|
53
|
+
};
|
package/src/config.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const jsonc = require('jsonc-parser');
|
|
4
|
+
|
|
5
|
+
const CONFIG_FILE = 'cyber-elx.jsonc';
|
|
6
|
+
|
|
7
|
+
function getConfigPath(cwd = process.cwd()) {
|
|
8
|
+
return path.join(cwd, CONFIG_FILE);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function configExists(cwd = process.cwd()) {
|
|
12
|
+
return fs.existsSync(getConfigPath(cwd));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function readConfig(cwd = process.cwd()) {
|
|
16
|
+
const configPath = getConfigPath(cwd);
|
|
17
|
+
if (!fs.existsSync(configPath)) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
21
|
+
return jsonc.parse(content);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function writeConfig(config, cwd = process.cwd()) {
|
|
25
|
+
const configPath = getConfigPath(cwd);
|
|
26
|
+
const content = `{
|
|
27
|
+
// ELX Custom Pages Configuration
|
|
28
|
+
// URL of your website (without trailing slash)
|
|
29
|
+
"url": "${config.url}",
|
|
30
|
+
// Authentication token (get from admin panel)
|
|
31
|
+
"token": "${config.token}"
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
34
|
+
fs.writeFileSync(configPath, content, 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function validateConfig(config) {
|
|
38
|
+
if (!config) {
|
|
39
|
+
return { valid: false, error: 'Config file not found. Run "cyber-elx init" first.' };
|
|
40
|
+
}
|
|
41
|
+
if (!config.url) {
|
|
42
|
+
return { valid: false, error: 'Missing "url" in config file.' };
|
|
43
|
+
}
|
|
44
|
+
if (!config.token) {
|
|
45
|
+
return { valid: false, error: 'Missing "token" in config file.' };
|
|
46
|
+
}
|
|
47
|
+
return { valid: true };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
module.exports = {
|
|
51
|
+
CONFIG_FILE,
|
|
52
|
+
getConfigPath,
|
|
53
|
+
configExists,
|
|
54
|
+
readConfig,
|
|
55
|
+
writeConfig,
|
|
56
|
+
validateConfig
|
|
57
|
+
};
|
package/src/files.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const DEFAULT_TEMPLATE_KEYS = [
|
|
5
|
+
'home_page',
|
|
6
|
+
'courses_page',
|
|
7
|
+
'course_page',
|
|
8
|
+
'about_page',
|
|
9
|
+
'category_page',
|
|
10
|
+
'blogs_page',
|
|
11
|
+
'blog_page',
|
|
12
|
+
'contact_page'
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
function ensureDirectories(cwd = process.cwd()) {
|
|
16
|
+
const dirs = [
|
|
17
|
+
path.join(cwd, 'sections'),
|
|
18
|
+
path.join(cwd, 'templates'),
|
|
19
|
+
path.join(cwd, 'layouts'),
|
|
20
|
+
path.join(cwd, 'defaults', 'sections'),
|
|
21
|
+
path.join(cwd, 'defaults', 'templates'),
|
|
22
|
+
path.join(cwd, 'defaults', 'layouts')
|
|
23
|
+
];
|
|
24
|
+
for (const dir of dirs) {
|
|
25
|
+
if (!fs.existsSync(dir)) {
|
|
26
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getFolder(type) {
|
|
32
|
+
if (type === 'template') return 'templates';
|
|
33
|
+
if (type === 'section') return 'sections';
|
|
34
|
+
if (type === 'layout') return 'layouts';
|
|
35
|
+
return type + 's';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getFilePath(type, key, cwd = process.cwd(), isDefault = false) {
|
|
39
|
+
const folder = getFolder(type);
|
|
40
|
+
if (isDefault) {
|
|
41
|
+
return path.join(cwd, 'defaults', folder, `${key}.liquid`);
|
|
42
|
+
}
|
|
43
|
+
return path.join(cwd, folder, `${key}.liquid`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function readPageFile(type, key, cwd = process.cwd()) {
|
|
47
|
+
const filePath = getFilePath(type, key, cwd);
|
|
48
|
+
if (!fs.existsSync(filePath)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return fs.readFileSync(filePath, 'utf-8');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function writePageFile(type, key, content, cwd = process.cwd(), isDefault = false) {
|
|
55
|
+
const filePath = getFilePath(type, key, cwd, isDefault);
|
|
56
|
+
const dir = path.dirname(filePath);
|
|
57
|
+
if (!fs.existsSync(dir)) {
|
|
58
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function fileExists(type, key, cwd = process.cwd()) {
|
|
64
|
+
const filePath = getFilePath(type, key, cwd);
|
|
65
|
+
return fs.existsSync(filePath);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getLocalPages(cwd = process.cwd()) {
|
|
69
|
+
const pages = [];
|
|
70
|
+
|
|
71
|
+
const templatesDir = path.join(cwd, 'templates');
|
|
72
|
+
const sectionsDir = path.join(cwd, 'sections');
|
|
73
|
+
const layoutsDir = path.join(cwd, 'layouts');
|
|
74
|
+
|
|
75
|
+
if (fs.existsSync(templatesDir)) {
|
|
76
|
+
const files = fs.readdirSync(templatesDir).filter(f => f.endsWith('.liquid'));
|
|
77
|
+
for (const file of files) {
|
|
78
|
+
const key = file.replace('.liquid', '');
|
|
79
|
+
const content = fs.readFileSync(path.join(templatesDir, file), 'utf-8');
|
|
80
|
+
pages.push({ type: 'template', key, content });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (fs.existsSync(sectionsDir)) {
|
|
85
|
+
const files = fs.readdirSync(sectionsDir).filter(f => f.endsWith('.liquid'));
|
|
86
|
+
for (const file of files) {
|
|
87
|
+
const key = file.replace('.liquid', '');
|
|
88
|
+
const content = fs.readFileSync(path.join(sectionsDir, file), 'utf-8');
|
|
89
|
+
pages.push({ type: 'section', key, content });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (fs.existsSync(layoutsDir)) {
|
|
94
|
+
const files = fs.readdirSync(layoutsDir).filter(f => f.endsWith('.liquid'));
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
const key = file.replace('.liquid', '');
|
|
97
|
+
const content = fs.readFileSync(path.join(layoutsDir, file), 'utf-8');
|
|
98
|
+
pages.push({ type: 'layout', key, content });
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return pages;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = {
|
|
106
|
+
DEFAULT_TEMPLATE_KEYS,
|
|
107
|
+
ensureDirectories,
|
|
108
|
+
getFolder,
|
|
109
|
+
getFilePath,
|
|
110
|
+
readPageFile,
|
|
111
|
+
writePageFile,
|
|
112
|
+
fileExists,
|
|
113
|
+
getLocalPages
|
|
114
|
+
};
|