jekyll-theme-zer0 0.22.0 → 0.22.19
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +236 -0
- data/README.md +66 -19
- data/_data/navigation/admin.yml +53 -0
- data/_data/theme_backgrounds.yml +121 -0
- data/_includes/components/admin-tabs.html +59 -0
- data/_includes/components/analytics-dashboard.html +232 -0
- data/_includes/components/background-customizer.html +159 -0
- data/_includes/components/background-settings.html +137 -0
- data/_includes/components/collection-manager.html +151 -0
- data/_includes/components/component-showcase.html +452 -0
- data/_includes/components/config-editor.html +207 -0
- data/_includes/components/config-viewer.html +479 -0
- data/_includes/components/env-dashboard.html +154 -0
- data/_includes/components/feature-card.html +94 -0
- data/_includes/components/info-section.html +172 -149
- data/_includes/components/js-cdn.html +4 -1
- data/_includes/components/nav-editor.html +99 -0
- data/_includes/components/setup-banner.html +28 -0
- data/_includes/components/setup-check.html +53 -0
- data/_includes/components/svg-background.html +42 -0
- data/_includes/components/theme-customizer.html +46 -0
- data/_includes/content/seo.html +68 -135
- data/_includes/core/footer.html +1 -1
- data/_includes/core/head.html +3 -2
- data/_includes/core/header.html +14 -7
- data/_includes/landing/landing-install-cards.html +18 -7
- data/_includes/navigation/admin-nav.html +95 -0
- data/_includes/navigation/navbar.html +43 -5
- data/_includes/navigation/sidebar-left.html +1 -1
- data/_includes/setup/wizard.html +330 -0
- data/_layouts/admin.html +166 -0
- data/_layouts/landing.html +23 -9
- data/_layouts/root.html +12 -6
- data/_layouts/setup.html +73 -0
- data/_plugins/preview_image_generator.rb +26 -12
- data/_sass/core/_navbar.scss +2 -2
- data/_sass/custom.scss +28 -6
- data/_sass/theme/_background-mixins.scss +95 -0
- data/_sass/theme/_backgrounds.scss +156 -0
- data/_sass/theme/_color-modes.scss +2 -1
- data/assets/backgrounds/gradients/air.svg +15 -0
- data/assets/backgrounds/gradients/aqua.svg +15 -0
- data/assets/backgrounds/gradients/contrast.svg +15 -0
- data/assets/backgrounds/gradients/dark.svg +15 -0
- data/assets/backgrounds/gradients/dirt.svg +15 -0
- data/assets/backgrounds/gradients/mint.svg +15 -0
- data/assets/backgrounds/gradients/neon.svg +15 -0
- data/assets/backgrounds/gradients/plum.svg +15 -0
- data/assets/backgrounds/gradients/sunrise.svg +15 -0
- data/assets/backgrounds/noise/air.svg +8 -0
- data/assets/backgrounds/noise/aqua.svg +8 -0
- data/assets/backgrounds/noise/contrast.svg +8 -0
- data/assets/backgrounds/noise/dark.svg +8 -0
- data/assets/backgrounds/noise/dirt.svg +8 -0
- data/assets/backgrounds/noise/mint.svg +8 -0
- data/assets/backgrounds/noise/neon.svg +8 -0
- data/assets/backgrounds/noise/plum.svg +8 -0
- data/assets/backgrounds/noise/sunrise.svg +8 -0
- data/assets/backgrounds/patterns/air.svg +7 -0
- data/assets/backgrounds/patterns/aqua.svg +7 -0
- data/assets/backgrounds/patterns/contrast.svg +4 -0
- data/assets/backgrounds/patterns/dark.svg +5 -0
- data/assets/backgrounds/patterns/dirt.svg +5 -0
- data/assets/backgrounds/patterns/mint.svg +6 -0
- data/assets/backgrounds/patterns/neon.svg +6 -0
- data/assets/backgrounds/patterns/plum.svg +6 -0
- data/assets/backgrounds/patterns/sunrise.svg +5 -0
- data/assets/js/background-customizer.js +73 -0
- data/assets/js/code-copy.js +18 -47
- data/assets/js/config-utility.js +307 -0
- data/assets/js/nav-editor.js +39 -0
- data/assets/js/palette-generator.js +415 -0
- data/assets/js/search-modal.js +31 -11
- data/assets/js/setup-wizard.js +306 -0
- data/assets/js/skin-editor.js +645 -0
- data/assets/js/theme-customizer.js +102 -0
- data/assets/js/ui-enhancements.js +15 -24
- data/assets/vendor/bootstrap/css/bootstrap.min.css +1 -0
- data/assets/vendor/bootstrap/js/bootstrap.bundle.min.js +1 -0
- data/scripts/README.md +45 -0
- data/scripts/features/generate-preview-images +297 -7
- data/scripts/features/install-preview-generator +51 -33
- data/scripts/fork-cleanup.sh +92 -19
- data/scripts/github-setup.sh +284 -0
- data/scripts/init_setup.sh +0 -1
- data/scripts/lib/frontmatter.sh +543 -0
- data/scripts/lib/migrate.sh +265 -0
- data/scripts/lib/preview_generator.py +607 -32
- data/scripts/lint-pages +505 -0
- data/scripts/migrate.sh +201 -0
- data/scripts/platform/setup-linux.sh +244 -0
- data/scripts/platform/setup-macos.sh +187 -0
- data/scripts/platform/setup-wsl.sh +196 -0
- metadata +71 -6
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ===================================================================
|
|
3
|
+
* Setup Wizard — _config.yml Generator
|
|
4
|
+
* ===================================================================
|
|
5
|
+
*
|
|
6
|
+
* Reads form inputs from the wizard include, builds a YAML string,
|
|
7
|
+
* and offers Download / Copy actions. Pure vanilla JS, no deps
|
|
8
|
+
* beyond Bootstrap 5 (already on the page).
|
|
9
|
+
*
|
|
10
|
+
* ===================================================================
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
(function () {
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
// ── helpers ────────────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Escape a YAML scalar string value (wrap in quotes if needed).
|
|
20
|
+
* Multi-line input (e.g., textarea newlines) is intentionally collapsed to
|
|
21
|
+
* a single line with spaces so the generated _config.yml remains valid YAML.
|
|
22
|
+
* All form fields in this wizard expect single-line values.
|
|
23
|
+
*/
|
|
24
|
+
function yamlValue(val) {
|
|
25
|
+
if (val === '' || val === null || val === undefined) return '""';
|
|
26
|
+
|
|
27
|
+
// Normalize newlines and collapse whitespace to keep scalar values single-line
|
|
28
|
+
var normalized = String(val)
|
|
29
|
+
.replace(/\r\n|\r|\n/g, ' ')
|
|
30
|
+
.replace(/\s{2,}/g, ' ')
|
|
31
|
+
.trim();
|
|
32
|
+
|
|
33
|
+
if (normalized === '') return '""';
|
|
34
|
+
if (normalized === 'true' || normalized === 'false') return normalized;
|
|
35
|
+
if (/^[0-9]+$/.test(normalized)) return normalized;
|
|
36
|
+
// Wrap in quotes if it contains special chars
|
|
37
|
+
if (/[:#{}[\],&*?|>!%@`]/.test(normalized) || normalized.includes("'") || normalized.includes('"')) {
|
|
38
|
+
return '"' + normalized.replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"';
|
|
39
|
+
}
|
|
40
|
+
return '"' + normalized + '"';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Pad a YAML key to 25 chars for alignment. */
|
|
44
|
+
function pad(key, width) {
|
|
45
|
+
width = width || 25;
|
|
46
|
+
return (key + ' '.repeat(width)).slice(0, width);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Return the permalink pattern for a given collection name. */
|
|
50
|
+
function collectionPermalink(col) {
|
|
51
|
+
switch (col) {
|
|
52
|
+
case 'posts': return '/posts/:title/';
|
|
53
|
+
case 'docs': return '/docs/:path/';
|
|
54
|
+
case 'about': return '/about/:path/';
|
|
55
|
+
default: return '/' + col + '/:path/';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ── YAML builder ──────────────────────────────────────────────────
|
|
60
|
+
|
|
61
|
+
function buildYAML() {
|
|
62
|
+
var fields = {};
|
|
63
|
+
|
|
64
|
+
// Read simple fields
|
|
65
|
+
document.querySelectorAll('.cfg-field').forEach(function (el) {
|
|
66
|
+
var key = el.getAttribute('data-key');
|
|
67
|
+
if (!key) return;
|
|
68
|
+
var val = (el.tagName === 'TEXTAREA' || el.tagName === 'SELECT')
|
|
69
|
+
? el.value.trim()
|
|
70
|
+
: el.value.trim();
|
|
71
|
+
if (val) fields[key] = val;
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Read collection toggles
|
|
75
|
+
var collections = [];
|
|
76
|
+
document.querySelectorAll('.cfg-collection').forEach(function (el) {
|
|
77
|
+
if (el.checked) {
|
|
78
|
+
collections.push(el.getAttribute('data-col'));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Read PostHog toggle
|
|
83
|
+
var posthogEnabled = document.getElementById('cfg-posthog-enabled');
|
|
84
|
+
var posthogOn = posthogEnabled && posthogEnabled.checked;
|
|
85
|
+
|
|
86
|
+
// Build YAML
|
|
87
|
+
var lines = [];
|
|
88
|
+
lines.push('# =============================================================================');
|
|
89
|
+
lines.push('# Site Configuration — generated by Setup Wizard');
|
|
90
|
+
lines.push('# Docs: https://jekyllrb.com/docs/configuration/');
|
|
91
|
+
lines.push('# =============================================================================');
|
|
92
|
+
lines.push('');
|
|
93
|
+
|
|
94
|
+
// Site Identity
|
|
95
|
+
lines.push('# ── Site Identity ──────────────────────────────────────────────────');
|
|
96
|
+
lines.push(pad('title') + ': ' + yamlValue(fields.title || 'My Site'));
|
|
97
|
+
if (fields.subtitle) {
|
|
98
|
+
lines.push(pad('subtitle') + ': ' + yamlValue(fields.subtitle));
|
|
99
|
+
}
|
|
100
|
+
lines.push(pad('description') + ': ' + yamlValue(fields.description || ''));
|
|
101
|
+
lines.push(pad('founder') + ': ' + yamlValue(fields.founder || ''));
|
|
102
|
+
if (fields.email) {
|
|
103
|
+
lines.push(pad('email') + ': ' + yamlValue(fields.email));
|
|
104
|
+
}
|
|
105
|
+
lines.push('');
|
|
106
|
+
|
|
107
|
+
// GitHub
|
|
108
|
+
lines.push('# ── GitHub ─────────────────────────────────────────────────────────');
|
|
109
|
+
var ghUser = fields.github_user || 'your-username';
|
|
110
|
+
var repoName = fields.repository_name || (ghUser !== 'your-username' ? ghUser + '-site' : 'my-site');
|
|
111
|
+
lines.push(pad('github_user') + ': &github_user ' + yamlValue(ghUser));
|
|
112
|
+
lines.push(pad('repository_name') + ': &github_repository ' + yamlValue(repoName));
|
|
113
|
+
lines.push('');
|
|
114
|
+
|
|
115
|
+
// URLs
|
|
116
|
+
lines.push('# ── URLs & Deployment ──────────────────────────────────────────────');
|
|
117
|
+
lines.push(pad('url') + ': ' + yamlValue(fields.url || 'https://' + ghUser + '.github.io'));
|
|
118
|
+
lines.push(pad('baseurl') + ': ' + yamlValue(fields.baseurl || ''));
|
|
119
|
+
lines.push(pad('remote_theme') + ': ' + yamlValue(fields.remote_theme || 'bamr87/zer0-mistakes'));
|
|
120
|
+
lines.push(pad('permalink') + ': ' + (fields.permalink || '/:categories/:title/'));
|
|
121
|
+
lines.push(pad('port') + ': 4000');
|
|
122
|
+
lines.push('');
|
|
123
|
+
|
|
124
|
+
// Collections
|
|
125
|
+
lines.push('# ── Collections ────────────────────────────────────────────────────');
|
|
126
|
+
lines.push('collections:');
|
|
127
|
+
collections.forEach(function (col) {
|
|
128
|
+
lines.push(' ' + col + ':');
|
|
129
|
+
lines.push(' output: true');
|
|
130
|
+
lines.push(' permalink: ' + collectionPermalink(col));
|
|
131
|
+
});
|
|
132
|
+
lines.push('');
|
|
133
|
+
|
|
134
|
+
// Defaults
|
|
135
|
+
lines.push('# ── Default Front Matter ───────────────────────────────────────────');
|
|
136
|
+
lines.push('defaults:');
|
|
137
|
+
if (collections.indexOf('posts') !== -1) {
|
|
138
|
+
lines.push(' - scope:');
|
|
139
|
+
lines.push(' path: ""');
|
|
140
|
+
lines.push(' type: "posts"');
|
|
141
|
+
lines.push(' values:');
|
|
142
|
+
lines.push(' layout: "article"');
|
|
143
|
+
lines.push(' author: "default"');
|
|
144
|
+
}
|
|
145
|
+
if (collections.indexOf('docs') !== -1) {
|
|
146
|
+
lines.push(' - scope:');
|
|
147
|
+
lines.push(' path: ""');
|
|
148
|
+
lines.push(' type: "docs"');
|
|
149
|
+
lines.push(' values:');
|
|
150
|
+
lines.push(' layout: "default"');
|
|
151
|
+
}
|
|
152
|
+
if (collections.indexOf('about') !== -1) {
|
|
153
|
+
lines.push(' - scope:');
|
|
154
|
+
lines.push(' path: ""');
|
|
155
|
+
lines.push(' type: "about"');
|
|
156
|
+
lines.push(' values:');
|
|
157
|
+
lines.push(' layout: "default"');
|
|
158
|
+
}
|
|
159
|
+
lines.push(' - scope:');
|
|
160
|
+
lines.push(' path: ""');
|
|
161
|
+
lines.push(' type: "pages"');
|
|
162
|
+
lines.push(' values:');
|
|
163
|
+
lines.push(' layout: "default"');
|
|
164
|
+
lines.push('');
|
|
165
|
+
|
|
166
|
+
// Build settings
|
|
167
|
+
lines.push('# ── Build ──────────────────────────────────────────────────────────');
|
|
168
|
+
lines.push(pad('markdown') + ': kramdown');
|
|
169
|
+
lines.push(pad('highlighter') + ': rouge');
|
|
170
|
+
lines.push(pad('public_folder') + ': assets');
|
|
171
|
+
lines.push('');
|
|
172
|
+
|
|
173
|
+
// Plugins
|
|
174
|
+
lines.push('# ── Plugins ────────────────────────────────────────────────────────');
|
|
175
|
+
lines.push('plugins:');
|
|
176
|
+
lines.push(' - jekyll-feed');
|
|
177
|
+
lines.push(' - jekyll-sitemap');
|
|
178
|
+
lines.push(' - jekyll-seo-tag');
|
|
179
|
+
lines.push(' - jekyll-remote-theme');
|
|
180
|
+
lines.push('');
|
|
181
|
+
|
|
182
|
+
// Analytics
|
|
183
|
+
lines.push('# ── Analytics ──────────────────────────────────────────────────────');
|
|
184
|
+
if (fields.google_analytics) {
|
|
185
|
+
lines.push(pad('google_analytics') + ': ' + yamlValue(fields.google_analytics));
|
|
186
|
+
} else {
|
|
187
|
+
lines.push(pad('google_analytics') + ': ""');
|
|
188
|
+
}
|
|
189
|
+
lines.push('posthog:');
|
|
190
|
+
lines.push(' enabled: ' + (posthogOn ? 'true' : 'false'));
|
|
191
|
+
lines.push(' api_key: ' + yamlValue(fields['posthog.api_key'] || ''));
|
|
192
|
+
lines.push('');
|
|
193
|
+
|
|
194
|
+
// Social
|
|
195
|
+
if (fields.twitter_username || fields.linkedin_username) {
|
|
196
|
+
lines.push('# ── Social ─────────────────────────────────────────────────────────');
|
|
197
|
+
if (fields.twitter_username) {
|
|
198
|
+
lines.push(pad('twitter_username') + ': ' + yamlValue(fields.twitter_username));
|
|
199
|
+
}
|
|
200
|
+
if (fields.linkedin_username) {
|
|
201
|
+
lines.push(pad('linkedin_username') + ': ' + yamlValue(fields.linkedin_username));
|
|
202
|
+
}
|
|
203
|
+
lines.push('');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Exclude
|
|
207
|
+
lines.push('# ── Exclude from build ─────────────────────────────────────────────');
|
|
208
|
+
lines.push('exclude:');
|
|
209
|
+
lines.push(' - .sass-cache/');
|
|
210
|
+
lines.push(' - .jekyll-cache/');
|
|
211
|
+
lines.push(' - node_modules/');
|
|
212
|
+
lines.push(' - vendor/');
|
|
213
|
+
lines.push(' - Gemfile.lock');
|
|
214
|
+
lines.push(' - scripts/');
|
|
215
|
+
lines.push(' - test/');
|
|
216
|
+
lines.push(' - templates/');
|
|
217
|
+
lines.push(' - "*.log"');
|
|
218
|
+
|
|
219
|
+
return lines.join('\n');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ── actions ────────────────────────────────────────────────────────
|
|
223
|
+
|
|
224
|
+
function updatePreview() {
|
|
225
|
+
var preview = document.getElementById('yaml-preview');
|
|
226
|
+
if (preview) {
|
|
227
|
+
preview.textContent = buildYAML();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function downloadYAML() {
|
|
232
|
+
var yaml = buildYAML();
|
|
233
|
+
var blob = new Blob([yaml], { type: 'text/yaml;charset=utf-8' });
|
|
234
|
+
var url = URL.createObjectURL(blob);
|
|
235
|
+
var a = document.createElement('a');
|
|
236
|
+
a.href = url;
|
|
237
|
+
a.download = '_config.yml';
|
|
238
|
+
document.body.appendChild(a);
|
|
239
|
+
a.click();
|
|
240
|
+
document.body.removeChild(a);
|
|
241
|
+
URL.revokeObjectURL(url);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function copyYAML() {
|
|
245
|
+
var yaml = buildYAML();
|
|
246
|
+
navigator.clipboard.writeText(yaml).then(function () {
|
|
247
|
+
var btn = document.getElementById('btn-copy-full') || document.getElementById('btn-copy');
|
|
248
|
+
if (btn) {
|
|
249
|
+
var orig = btn.innerHTML;
|
|
250
|
+
btn.innerHTML = '<i class="bi bi-check-lg"></i> Copied!';
|
|
251
|
+
setTimeout(function () { btn.innerHTML = orig; }, 2000);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ── wiring ─────────────────────────────────────────────────────────
|
|
257
|
+
|
|
258
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
259
|
+
// Next / Prev buttons
|
|
260
|
+
document.querySelectorAll('.btn-next').forEach(function (btn) {
|
|
261
|
+
btn.addEventListener('click', function () {
|
|
262
|
+
var target = btn.getAttribute('data-next');
|
|
263
|
+
var tab = document.getElementById(target);
|
|
264
|
+
if (tab) new bootstrap.Tab(tab).show();
|
|
265
|
+
updatePreview();
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
document.querySelectorAll('.btn-prev').forEach(function (btn) {
|
|
270
|
+
btn.addEventListener('click', function () {
|
|
271
|
+
var target = btn.getAttribute('data-prev');
|
|
272
|
+
var tab = document.getElementById(target);
|
|
273
|
+
if (tab) new bootstrap.Tab(tab).show();
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
// Live update on review tab activation
|
|
278
|
+
var reviewTab = document.getElementById('tab-review');
|
|
279
|
+
if (reviewTab) {
|
|
280
|
+
reviewTab.addEventListener('shown.bs.tab', updatePreview);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Description char count
|
|
284
|
+
var descField = document.getElementById('cfg-description');
|
|
285
|
+
var descCount = document.getElementById('desc-count');
|
|
286
|
+
if (descField && descCount) {
|
|
287
|
+
descField.addEventListener('input', function () {
|
|
288
|
+
descCount.textContent = descField.value.length;
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Download / Copy
|
|
293
|
+
var dlBtn = document.getElementById('btn-download');
|
|
294
|
+
if (dlBtn) dlBtn.addEventListener('click', downloadYAML);
|
|
295
|
+
|
|
296
|
+
var copyBtn = document.getElementById('btn-copy');
|
|
297
|
+
if (copyBtn) copyBtn.addEventListener('click', copyYAML);
|
|
298
|
+
|
|
299
|
+
var copyFullBtn = document.getElementById('btn-copy-full');
|
|
300
|
+
if (copyFullBtn) copyFullBtn.addEventListener('click', copyYAML);
|
|
301
|
+
|
|
302
|
+
// Initial preview
|
|
303
|
+
updatePreview();
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
})();
|