@edtools/cli 0.6.2 → 0.7.1
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/dist/adapters/html/index.d.ts +2 -2
- package/dist/adapters/html/index.d.ts.map +1 -1
- package/dist/adapters/html/index.js +39 -5
- package/dist/adapters/html/index.js.map +1 -1
- package/dist/adapters/html/templates/base-layout.ejs +173 -0
- package/dist/adapters/html/templates/blog-index.html.ejs +170 -101
- package/dist/adapters/html/templates/blog-post-enhanced.ejs +655 -0
- package/dist/adapters/html/templates/blog-post-new.ejs +612 -0
- package/dist/adapters/html/templates/components/footer.ejs +330 -0
- package/dist/adapters/html/templates/components/header.ejs +208 -0
- package/dist/adapters/html/templates/components/social-share.ejs +202 -0
- package/dist/chunk-5N3D47CJ.js +823 -0
- package/dist/chunk-EPM74QNH.js +844 -0
- package/dist/chunk-OVFZRN7O.js +850 -0
- package/dist/chunk-TROAGFSZ.js +824 -0
- package/dist/chunk-U77FH5BI.js +823 -0
- package/dist/cli/commands/config.d.ts +17 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +140 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +57 -14
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +114 -0
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +623 -288
- package/dist/cli/index.js.map +1 -1
- package/dist/core/generator.d.ts +4 -1
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/generator.js +118 -3
- package/dist/core/generator.js.map +1 -1
- package/dist/index.d.ts +87 -3
- package/dist/index.js +1 -1
- package/dist/types/adapter.d.ts +17 -2
- package/dist/types/adapter.d.ts.map +1 -1
- package/dist/types/adapter.js.map +1 -1
- package/dist/types/content.d.ts +66 -0
- package/dist/types/content.d.ts.map +1 -1
- package/dist/ui/banner.d.ts.map +1 -1
- package/dist/ui/banner.js +18 -2
- package/dist/ui/banner.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
2
|
+
<html lang="<%= blogConfig.language || 'en' %>">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
|
|
7
|
+
<!-- SEO Meta Tags -->
|
|
8
|
+
<title><%= blogConfig.name || siteName %></title>
|
|
9
|
+
<meta name="description" content="<%= blogConfig.description || siteDescription %>">
|
|
8
10
|
<meta name="robots" content="index, follow">
|
|
9
11
|
|
|
12
|
+
<!-- Canonical URL -->
|
|
13
|
+
<link rel="canonical" href="<%= siteUrl %>">
|
|
14
|
+
|
|
10
15
|
<!-- Open Graph -->
|
|
11
|
-
<meta property="og:title" content="<%= siteName %>
|
|
12
|
-
<meta property="og:description" content="<%= siteDescription %>">
|
|
16
|
+
<meta property="og:title" content="<%= blogConfig.name || siteName %>">
|
|
17
|
+
<meta property="og:description" content="<%= blogConfig.description || siteDescription %>">
|
|
13
18
|
<meta property="og:type" content="website">
|
|
14
19
|
<meta property="og:url" content="<%= siteUrl %>">
|
|
15
20
|
|
|
21
|
+
<!-- Twitter Card -->
|
|
22
|
+
<meta name="twitter:card" content="summary_large_image">
|
|
23
|
+
<meta name="twitter:title" content="<%= blogConfig.name || siteName %>">
|
|
24
|
+
<meta name="twitter:description" content="<%= blogConfig.description || siteDescription %>">
|
|
25
|
+
|
|
26
|
+
<!-- RSS Feed -->
|
|
27
|
+
<link rel="alternate" type="application/rss+xml" title="<%= blogConfig.name || siteName %> RSS Feed" href="/blog/rss.xml">
|
|
28
|
+
|
|
16
29
|
<style>
|
|
30
|
+
:root {
|
|
31
|
+
--primary-color: <%= blogConfig.primaryColor || '#2563eb' %>;
|
|
32
|
+
--text-color: <%= blogConfig.textColor || '#1f2937' %>;
|
|
33
|
+
--text-light: <%= blogConfig.textLight || '#6b7280' %>;
|
|
34
|
+
--border-color: <%= blogConfig.borderColor || '#e5e7eb' %>;
|
|
35
|
+
--bg-light: <%= blogConfig.bgLight || '#f9fafb' %>;
|
|
36
|
+
}
|
|
37
|
+
|
|
17
38
|
* {
|
|
18
39
|
margin: 0;
|
|
19
40
|
padding: 0;
|
|
@@ -21,42 +42,67 @@
|
|
|
21
42
|
}
|
|
22
43
|
|
|
23
44
|
body {
|
|
24
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
|
|
45
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
25
46
|
line-height: 1.6;
|
|
26
|
-
color:
|
|
27
|
-
background-color:
|
|
47
|
+
color: var(--text-color);
|
|
48
|
+
background-color: var(--bg-light);
|
|
28
49
|
}
|
|
29
50
|
|
|
30
51
|
.container {
|
|
31
52
|
max-width: 1200px;
|
|
32
53
|
margin: 0 auto;
|
|
33
|
-
padding:
|
|
54
|
+
padding: 2rem 1rem;
|
|
34
55
|
}
|
|
35
56
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
57
|
+
.breadcrumbs {
|
|
58
|
+
display: flex;
|
|
59
|
+
align-items: center;
|
|
60
|
+
gap: 0.5rem;
|
|
61
|
+
font-size: 0.875rem;
|
|
62
|
+
color: var(--text-light);
|
|
63
|
+
margin-bottom: 2rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.breadcrumbs a {
|
|
67
|
+
color: var(--primary-color);
|
|
68
|
+
text-decoration: none;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.breadcrumbs a:hover {
|
|
72
|
+
text-decoration: underline;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.breadcrumbs span {
|
|
76
|
+
color: var(--text-light);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.blog-header {
|
|
40
80
|
text-align: center;
|
|
41
|
-
|
|
81
|
+
padding: 3rem 1rem;
|
|
82
|
+
background: linear-gradient(135deg, var(--primary-color) 0%, #764ba2 100%);
|
|
83
|
+
color: white;
|
|
84
|
+
border-radius: 1rem;
|
|
85
|
+
margin-bottom: 3rem;
|
|
42
86
|
}
|
|
43
87
|
|
|
44
|
-
header h1 {
|
|
45
|
-
font-size:
|
|
46
|
-
margin-bottom: 10px;
|
|
88
|
+
.blog-header h1 {
|
|
89
|
+
font-size: 3rem;
|
|
47
90
|
font-weight: 700;
|
|
91
|
+
margin-bottom: 1rem;
|
|
48
92
|
}
|
|
49
93
|
|
|
50
|
-
header p {
|
|
51
|
-
font-size: 1.
|
|
52
|
-
opacity: 0.
|
|
94
|
+
.blog-header p {
|
|
95
|
+
font-size: 1.25rem;
|
|
96
|
+
opacity: 0.95;
|
|
97
|
+
max-width: 600px;
|
|
98
|
+
margin: 0 auto;
|
|
53
99
|
}
|
|
54
100
|
|
|
55
101
|
.stats {
|
|
56
102
|
display: flex;
|
|
57
103
|
justify-content: center;
|
|
58
|
-
gap:
|
|
59
|
-
margin-top:
|
|
104
|
+
gap: 3rem;
|
|
105
|
+
margin-top: 2rem;
|
|
60
106
|
flex-wrap: wrap;
|
|
61
107
|
}
|
|
62
108
|
|
|
@@ -65,44 +111,46 @@
|
|
|
65
111
|
}
|
|
66
112
|
|
|
67
113
|
.stat-number {
|
|
68
|
-
font-size: 2.
|
|
69
|
-
font-weight:
|
|
114
|
+
font-size: 2.5rem;
|
|
115
|
+
font-weight: 700;
|
|
70
116
|
display: block;
|
|
71
117
|
}
|
|
72
118
|
|
|
73
119
|
.stat-label {
|
|
74
|
-
font-size: 0.
|
|
75
|
-
opacity: 0.
|
|
120
|
+
font-size: 0.875rem;
|
|
121
|
+
opacity: 0.9;
|
|
76
122
|
text-transform: uppercase;
|
|
77
|
-
letter-spacing:
|
|
123
|
+
letter-spacing: 0.05em;
|
|
78
124
|
}
|
|
79
125
|
|
|
80
126
|
.posts-grid {
|
|
81
127
|
display: grid;
|
|
82
128
|
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
|
83
|
-
gap:
|
|
84
|
-
margin-top:
|
|
129
|
+
gap: 2rem;
|
|
130
|
+
margin-top: 2rem;
|
|
85
131
|
}
|
|
86
132
|
|
|
87
133
|
.post-card {
|
|
88
134
|
background: white;
|
|
89
|
-
border
|
|
135
|
+
border: 1px solid var(--border-color);
|
|
136
|
+
border-radius: 0.75rem;
|
|
90
137
|
overflow: hidden;
|
|
91
|
-
|
|
92
|
-
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
|
138
|
+
transition: all 0.3s ease;
|
|
93
139
|
text-decoration: none;
|
|
94
140
|
color: inherit;
|
|
95
141
|
display: flex;
|
|
96
142
|
flex-direction: column;
|
|
143
|
+
height: 100%;
|
|
97
144
|
}
|
|
98
145
|
|
|
99
146
|
.post-card:hover {
|
|
100
|
-
transform: translateY(-
|
|
101
|
-
box-shadow: 0
|
|
147
|
+
transform: translateY(-4px);
|
|
148
|
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
|
|
149
|
+
border-color: var(--primary-color);
|
|
102
150
|
}
|
|
103
151
|
|
|
104
152
|
.post-card-body {
|
|
105
|
-
padding:
|
|
153
|
+
padding: 1.5rem;
|
|
106
154
|
flex: 1;
|
|
107
155
|
display: flex;
|
|
108
156
|
flex-direction: column;
|
|
@@ -110,115 +158,112 @@
|
|
|
110
158
|
|
|
111
159
|
.post-meta {
|
|
112
160
|
display: flex;
|
|
113
|
-
gap:
|
|
114
|
-
font-size: 0.
|
|
115
|
-
color:
|
|
116
|
-
margin-bottom:
|
|
161
|
+
gap: 0.75rem;
|
|
162
|
+
font-size: 0.875rem;
|
|
163
|
+
color: var(--text-light);
|
|
164
|
+
margin-bottom: 1rem;
|
|
117
165
|
flex-wrap: wrap;
|
|
166
|
+
align-items: center;
|
|
118
167
|
}
|
|
119
168
|
|
|
120
169
|
.post-category {
|
|
121
|
-
background:
|
|
122
|
-
color:
|
|
123
|
-
padding:
|
|
124
|
-
border-radius:
|
|
170
|
+
background: var(--primary-color);
|
|
171
|
+
color: white;
|
|
172
|
+
padding: 0.25rem 0.75rem;
|
|
173
|
+
border-radius: 9999px;
|
|
125
174
|
font-weight: 600;
|
|
175
|
+
font-size: 0.75rem;
|
|
126
176
|
text-transform: uppercase;
|
|
127
|
-
|
|
128
|
-
letter-spacing: 0.5px;
|
|
177
|
+
letter-spacing: 0.025em;
|
|
129
178
|
}
|
|
130
179
|
|
|
131
180
|
.post-read-time {
|
|
132
181
|
display: flex;
|
|
133
182
|
align-items: center;
|
|
134
|
-
gap:
|
|
183
|
+
gap: 0.25rem;
|
|
135
184
|
}
|
|
136
185
|
|
|
137
186
|
.post-title {
|
|
138
|
-
font-size: 1.
|
|
187
|
+
font-size: 1.5rem;
|
|
139
188
|
font-weight: 700;
|
|
140
|
-
margin-bottom:
|
|
141
|
-
color:
|
|
189
|
+
margin-bottom: 0.75rem;
|
|
190
|
+
color: var(--text-color);
|
|
142
191
|
line-height: 1.3;
|
|
143
192
|
}
|
|
144
193
|
|
|
145
194
|
.post-description {
|
|
146
|
-
color:
|
|
147
|
-
margin-bottom:
|
|
195
|
+
color: var(--text-light);
|
|
196
|
+
margin-bottom: 1rem;
|
|
148
197
|
flex: 1;
|
|
198
|
+
line-height: 1.6;
|
|
149
199
|
}
|
|
150
200
|
|
|
151
201
|
.post-tags {
|
|
152
202
|
display: flex;
|
|
153
203
|
flex-wrap: wrap;
|
|
154
|
-
gap:
|
|
204
|
+
gap: 0.5rem;
|
|
155
205
|
margin-top: auto;
|
|
156
|
-
padding-top:
|
|
157
|
-
border-top: 1px solid
|
|
206
|
+
padding-top: 1rem;
|
|
207
|
+
border-top: 1px solid var(--border-color);
|
|
158
208
|
}
|
|
159
209
|
|
|
160
210
|
.tag {
|
|
161
|
-
background:
|
|
162
|
-
color:
|
|
163
|
-
padding:
|
|
164
|
-
border-radius:
|
|
165
|
-
font-size: 0.
|
|
211
|
+
background: var(--bg-light);
|
|
212
|
+
color: var(--text-light);
|
|
213
|
+
padding: 0.25rem 0.5rem;
|
|
214
|
+
border-radius: 0.25rem;
|
|
215
|
+
font-size: 0.8125rem;
|
|
216
|
+
border: 1px solid var(--border-color);
|
|
166
217
|
}
|
|
167
218
|
|
|
168
219
|
.seo-score {
|
|
169
220
|
display: inline-flex;
|
|
170
221
|
align-items: center;
|
|
171
|
-
gap:
|
|
172
|
-
font-size: 0.
|
|
222
|
+
gap: 0.25rem;
|
|
223
|
+
font-size: 0.875rem;
|
|
173
224
|
}
|
|
174
225
|
|
|
175
226
|
.score-badge {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
padding: 2px 8px;
|
|
179
|
-
border-radius: 8px;
|
|
227
|
+
padding: 0.125rem 0.5rem;
|
|
228
|
+
border-radius: 0.25rem;
|
|
180
229
|
font-weight: 600;
|
|
230
|
+
font-size: 0.75rem;
|
|
181
231
|
}
|
|
182
232
|
|
|
183
233
|
.score-badge.good {
|
|
184
|
-
background: #
|
|
234
|
+
background: #d1fae5;
|
|
235
|
+
color: #065f46;
|
|
185
236
|
}
|
|
186
237
|
|
|
187
238
|
.score-badge.medium {
|
|
188
|
-
background: #
|
|
239
|
+
background: #fef3c7;
|
|
240
|
+
color: #92400e;
|
|
189
241
|
}
|
|
190
242
|
|
|
191
243
|
.score-badge.low {
|
|
192
|
-
background: #
|
|
244
|
+
background: #fee2e2;
|
|
245
|
+
color: #991b1b;
|
|
193
246
|
}
|
|
194
247
|
|
|
195
248
|
.loading {
|
|
196
249
|
text-align: center;
|
|
197
|
-
padding:
|
|
198
|
-
font-size: 1.
|
|
199
|
-
color:
|
|
250
|
+
padding: 5rem 1rem;
|
|
251
|
+
font-size: 1.125rem;
|
|
252
|
+
color: var(--text-light);
|
|
200
253
|
}
|
|
201
254
|
|
|
202
255
|
.error {
|
|
203
256
|
background: #fee2e2;
|
|
204
257
|
border: 1px solid #fecaca;
|
|
205
258
|
color: #991b1b;
|
|
206
|
-
padding:
|
|
207
|
-
border-radius:
|
|
208
|
-
text-align: center;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
footer {
|
|
212
|
-
margin-top: 80px;
|
|
213
|
-
padding: 40px 20px;
|
|
214
|
-
background: #1f2937;
|
|
215
|
-
color: white;
|
|
259
|
+
padding: 1.5rem;
|
|
260
|
+
border-radius: 0.5rem;
|
|
216
261
|
text-align: center;
|
|
217
262
|
}
|
|
218
263
|
|
|
219
264
|
@media (max-width: 768px) {
|
|
220
|
-
header h1 {
|
|
221
|
-
font-size:
|
|
265
|
+
.blog-header h1 {
|
|
266
|
+
font-size: 2rem;
|
|
222
267
|
}
|
|
223
268
|
|
|
224
269
|
.posts-grid {
|
|
@@ -226,20 +271,31 @@
|
|
|
226
271
|
}
|
|
227
272
|
|
|
228
273
|
.stats {
|
|
229
|
-
gap:
|
|
274
|
+
gap: 1.5rem;
|
|
230
275
|
}
|
|
231
276
|
|
|
232
277
|
.stat-number {
|
|
233
|
-
font-size:
|
|
278
|
+
font-size: 2rem;
|
|
234
279
|
}
|
|
235
280
|
}
|
|
236
281
|
</style>
|
|
237
282
|
</head>
|
|
238
283
|
<body>
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
284
|
+
<!-- Global Header -->
|
|
285
|
+
<%- include('components/header', { blogConfig }) %>
|
|
286
|
+
|
|
287
|
+
<div class="container">
|
|
288
|
+
<!-- Breadcrumbs -->
|
|
289
|
+
<nav class="breadcrumbs" aria-label="Breadcrumb">
|
|
290
|
+
<a href="<%= blogConfig.websiteUrl || '/' %>">Home</a>
|
|
291
|
+
<span>/</span>
|
|
292
|
+
<span>Blog</span>
|
|
293
|
+
</nav>
|
|
294
|
+
|
|
295
|
+
<!-- Blog Header -->
|
|
296
|
+
<div class="blog-header">
|
|
297
|
+
<h1><%= blogConfig.name || siteName %></h1>
|
|
298
|
+
<p><%= blogConfig.description || siteDescription %></p>
|
|
243
299
|
<div class="stats" id="stats">
|
|
244
300
|
<div class="stat">
|
|
245
301
|
<span class="stat-number" id="total-posts">-</span>
|
|
@@ -251,27 +307,29 @@
|
|
|
251
307
|
</div>
|
|
252
308
|
<div class="stat">
|
|
253
309
|
<span class="stat-number" id="avg-read">-</span>
|
|
254
|
-
<span class="stat-label">Avg Read
|
|
310
|
+
<span class="stat-label">Avg Read</span>
|
|
255
311
|
</div>
|
|
256
312
|
</div>
|
|
257
313
|
</div>
|
|
258
|
-
</header>
|
|
259
314
|
|
|
260
|
-
|
|
315
|
+
<!-- Loading State -->
|
|
261
316
|
<div id="loading" class="loading">
|
|
262
317
|
Loading posts...
|
|
263
318
|
</div>
|
|
319
|
+
|
|
320
|
+
<!-- Error State -->
|
|
264
321
|
<div id="error" class="error" style="display: none;">
|
|
265
322
|
Failed to load posts. Please try again later.
|
|
266
323
|
</div>
|
|
324
|
+
|
|
325
|
+
<!-- Posts Grid -->
|
|
267
326
|
<div id="posts" class="posts-grid" style="display: none;">
|
|
268
|
-
<!-- Posts will be loaded here -->
|
|
327
|
+
<!-- Posts will be loaded here via JavaScript -->
|
|
269
328
|
</div>
|
|
270
329
|
</div>
|
|
271
330
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
</footer>
|
|
331
|
+
<!-- Global Footer -->
|
|
332
|
+
<%- include('components/footer', { blogConfig }) %>
|
|
275
333
|
|
|
276
334
|
<script>
|
|
277
335
|
// Load and display blog posts from index.json
|
|
@@ -291,7 +349,12 @@
|
|
|
291
349
|
const postsContainer = document.getElementById('posts');
|
|
292
350
|
postsContainer.innerHTML = '';
|
|
293
351
|
|
|
294
|
-
|
|
352
|
+
// Sort posts by date (newest first)
|
|
353
|
+
const sortedPosts = [...data.posts].sort((a, b) =>
|
|
354
|
+
new Date(b.publishDate) - new Date(a.publishDate)
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
sortedPosts.forEach(post => {
|
|
295
358
|
const card = document.createElement('a');
|
|
296
359
|
card.href = post.url;
|
|
297
360
|
card.className = 'post-card';
|
|
@@ -301,16 +364,22 @@
|
|
|
301
364
|
card.innerHTML = `
|
|
302
365
|
<div class="post-card-body">
|
|
303
366
|
<div class="post-meta">
|
|
304
|
-
<span class="post-category">${post.category}</span>
|
|
305
|
-
<span class="post-read-time"
|
|
367
|
+
<span class="post-category">${escapeHtml(post.category)}</span>
|
|
368
|
+
<span class="post-read-time">
|
|
369
|
+
<svg width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
|
|
370
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
371
|
+
<polyline points="12 6 12 12 16 14"></polyline>
|
|
372
|
+
</svg>
|
|
373
|
+
${escapeHtml(post.readTime)}
|
|
374
|
+
</span>
|
|
306
375
|
<span class="seo-score">
|
|
307
|
-
SEO
|
|
376
|
+
SEO <span class="score-badge ${scoreClass}">${post.seo.seoScore}</span>
|
|
308
377
|
</span>
|
|
309
378
|
</div>
|
|
310
379
|
<h2 class="post-title">${escapeHtml(post.title)}</h2>
|
|
311
380
|
<p class="post-description">${escapeHtml(post.shortDescription)}</p>
|
|
312
381
|
<div class="post-tags">
|
|
313
|
-
${post.tags.map(tag => `<span class="tag">#${escapeHtml(tag)}</span>`).join('')}
|
|
382
|
+
${post.tags.slice(0, 4).map(tag => `<span class="tag">#${escapeHtml(tag)}</span>`).join('')}
|
|
314
383
|
</div>
|
|
315
384
|
</div>
|
|
316
385
|
`;
|