jekyll-theme-zer0 0.16.0 → 0.17.2
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 +115 -10
- data/README.md +7 -7
- data/_data/authors.yml +2 -2
- data/_data/features.yml +676 -0
- data/_data/navigation/README.md +54 -0
- data/_data/navigation/about.yml +7 -5
- data/_data/navigation/docs.yml +77 -31
- data/_data/navigation/home.yml +4 -3
- data/_data/navigation/main.yml +16 -7
- data/_data/navigation/quickstart.yml +4 -2
- data/_includes/components/cookie-consent.html +81 -9
- data/_includes/components/js-cdn.html +2 -2
- data/_includes/components/mermaid.html +260 -14
- data/_includes/core/head.html +1 -0
- data/_includes/landing/landing-install-cards.html +8 -8
- data/_includes/landing/landing-quick-links.html +4 -4
- data/_includes/navigation/breadcrumbs.html +29 -6
- data/_includes/navigation/nav-tree.html +181 -0
- data/_includes/navigation/navbar.html +262 -9
- data/_includes/navigation/sidebar-left.html +22 -23
- data/_layouts/default.html +1 -1
- data/_layouts/landing.html +21 -21
- data/_layouts/notebook.html +4 -4
- data/_layouts/root.html +2 -2
- data/_sass/core/_nav-tree.scss +145 -0
- data/_sass/core/code-copy.scss +45 -6
- data/_sass/custom.scss +541 -1
- data/assets/js/code-copy.js +79 -13
- data/assets/js/modules/navigation/config.js +149 -0
- data/assets/js/modules/navigation/focus.js +189 -0
- data/assets/js/modules/navigation/gestures.js +179 -0
- data/assets/js/modules/navigation/index.js +227 -0
- data/assets/js/modules/navigation/keyboard.js +237 -0
- data/assets/js/modules/navigation/scroll-spy.js +219 -0
- data/assets/js/modules/navigation/sidebar-state.js +267 -0
- data/assets/js/modules/navigation/smooth-scroll.js +153 -0
- data/assets/js/ui-enhancements.js +194 -0
- data/scripts/migrate-nav-modes.sh +146 -0
- metadata +20 -7
- data/assets/js/sidebar.js +0 -511
|
@@ -47,6 +47,108 @@
|
|
|
47
47
|
<!-- Initialize Mermaid with custom configuration -->
|
|
48
48
|
<script>
|
|
49
49
|
document.addEventListener('DOMContentLoaded', function() {
|
|
50
|
+
// ============================================================
|
|
51
|
+
// Helper function to detect Bootstrap theme
|
|
52
|
+
// ============================================================
|
|
53
|
+
function getBootstrapTheme() {
|
|
54
|
+
// Check data-bs-theme attribute on html element
|
|
55
|
+
var htmlTheme = document.documentElement.getAttribute('data-bs-theme');
|
|
56
|
+
if (htmlTheme === 'dark' || htmlTheme === 'light') {
|
|
57
|
+
return htmlTheme;
|
|
58
|
+
}
|
|
59
|
+
// Fallback to prefers-color-scheme
|
|
60
|
+
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
61
|
+
return 'dark';
|
|
62
|
+
}
|
|
63
|
+
return 'light';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ============================================================
|
|
67
|
+
// Helper function to get Mermaid theme configuration
|
|
68
|
+
// ============================================================
|
|
69
|
+
function getMermaidConfig(theme) {
|
|
70
|
+
var isDark = theme === 'dark';
|
|
71
|
+
|
|
72
|
+
if (isDark) {
|
|
73
|
+
// Dark mode configuration
|
|
74
|
+
return {
|
|
75
|
+
theme: 'dark',
|
|
76
|
+
themeVariables: {
|
|
77
|
+
primaryColor: '#0d6efd',
|
|
78
|
+
primaryTextColor: '#ffffff',
|
|
79
|
+
primaryBorderColor: '#0a58ca',
|
|
80
|
+
lineColor: '#6c757d',
|
|
81
|
+
secondaryColor: '#6c757d',
|
|
82
|
+
tertiaryColor: '#212529',
|
|
83
|
+
background: '#212529',
|
|
84
|
+
mainBkg: '#212529',
|
|
85
|
+
secondBkg: '#343a40',
|
|
86
|
+
tertiaryBkg: '#495057',
|
|
87
|
+
textColor: '#ffffff',
|
|
88
|
+
secondaryTextColor: '#adb5bd',
|
|
89
|
+
tertiaryTextColor: '#6c757d',
|
|
90
|
+
lineColor: '#6c757d',
|
|
91
|
+
border1: '#495057',
|
|
92
|
+
border2: '#6c757d',
|
|
93
|
+
noteBkgColor: '#343a40',
|
|
94
|
+
noteTextColor: '#ffffff',
|
|
95
|
+
noteBorderColor: '#6c757d',
|
|
96
|
+
actorBkg: '#0d6efd',
|
|
97
|
+
actorBorder: '#0a58ca',
|
|
98
|
+
actorTextColor: '#ffffff',
|
|
99
|
+
actorLineColor: '#ffffff',
|
|
100
|
+
signalColor: '#ffffff',
|
|
101
|
+
signalTextColor: '#ffffff',
|
|
102
|
+
labelBoxBkgColor: '#343a40',
|
|
103
|
+
labelBoxBorderColor: '#6c757d',
|
|
104
|
+
labelTextColor: '#ffffff',
|
|
105
|
+
loopTextColor: '#ffffff',
|
|
106
|
+
activationBorderColor: '#0d6efd',
|
|
107
|
+
activationBkgColor: '#0d6efd',
|
|
108
|
+
sequenceNumberColor: '#ffffff',
|
|
109
|
+
sectionBkgColor: '#343a40',
|
|
110
|
+
altSectionBkgColor: '#495057',
|
|
111
|
+
excludeBkgColor: '#495057',
|
|
112
|
+
taskBorderColor: '#0d6efd',
|
|
113
|
+
taskBkgColor: '#0d6efd',
|
|
114
|
+
taskTextLightColor: '#ffffff',
|
|
115
|
+
taskTextColor: '#ffffff',
|
|
116
|
+
taskTextDarkColor: '#000000',
|
|
117
|
+
taskTextOutsideColor: '#ffffff',
|
|
118
|
+
taskTextClickableColor: '#0d6efd',
|
|
119
|
+
activeTaskBorderColor: '#0a58ca',
|
|
120
|
+
activeTaskBkgColor: '#0a58ca',
|
|
121
|
+
gridColor: '#6c757d',
|
|
122
|
+
doneTaskBkgColor: '#198754',
|
|
123
|
+
doneTaskBorderColor: '#146c43',
|
|
124
|
+
critBorderColor: '#dc3545',
|
|
125
|
+
critBkgColor: '#dc3545',
|
|
126
|
+
todayLineColor: '#ffc107'
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
} else {
|
|
130
|
+
// Light mode configuration
|
|
131
|
+
return {
|
|
132
|
+
theme: 'default',
|
|
133
|
+
themeVariables: {
|
|
134
|
+
primaryColor: '#007bff',
|
|
135
|
+
primaryTextColor: '#fff',
|
|
136
|
+
primaryBorderColor: '#0056b3',
|
|
137
|
+
lineColor: '#6c757d',
|
|
138
|
+
secondaryColor: '#6c757d',
|
|
139
|
+
tertiaryColor: '#f8f9fa',
|
|
140
|
+
background: '#ffffff',
|
|
141
|
+
mainBkg: '#ffffff',
|
|
142
|
+
secondBkg: '#f8f9fa',
|
|
143
|
+
tertiaryBkg: '#e9ecef',
|
|
144
|
+
textColor: '#212529',
|
|
145
|
+
secondaryTextColor: '#6c757d',
|
|
146
|
+
tertiaryTextColor: '#adb5bd'
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
50
152
|
// ============================================================
|
|
51
153
|
// Step 1: Convert native markdown code blocks to mermaid divs
|
|
52
154
|
// This enables ```mermaid syntax to work with GitHub Pages
|
|
@@ -86,20 +188,16 @@
|
|
|
86
188
|
});
|
|
87
189
|
|
|
88
190
|
// ============================================================
|
|
89
|
-
// Step 2: Initialize Mermaid with
|
|
191
|
+
// Step 2: Initialize Mermaid with theme-aware configuration
|
|
90
192
|
// ============================================================
|
|
91
193
|
|
|
194
|
+
var bootstrapTheme = getBootstrapTheme();
|
|
195
|
+
var mermaidThemeConfig = getMermaidConfig(bootstrapTheme);
|
|
196
|
+
|
|
92
197
|
mermaid.initialize({
|
|
93
198
|
startOnLoad: false, // We'll manually run after conversion
|
|
94
|
-
theme:
|
|
95
|
-
themeVariables:
|
|
96
|
-
primaryColor: '#007bff',
|
|
97
|
-
primaryTextColor: '#fff',
|
|
98
|
-
primaryBorderColor: '#0056b3',
|
|
99
|
-
lineColor: '#6c757d',
|
|
100
|
-
secondaryColor: '#6c757d',
|
|
101
|
-
tertiaryColor: '#f8f9fa'
|
|
102
|
-
},
|
|
199
|
+
theme: mermaidThemeConfig.theme,
|
|
200
|
+
themeVariables: mermaidThemeConfig.themeVariables,
|
|
103
201
|
flowchart: {
|
|
104
202
|
useMaxWidth: true,
|
|
105
203
|
htmlLabels: true,
|
|
@@ -139,10 +237,82 @@
|
|
|
139
237
|
|
|
140
238
|
// Run mermaid to render all .mermaid divs
|
|
141
239
|
mermaid.run().then(function() {
|
|
142
|
-
console.log('Mermaid.js: All diagrams rendered successfully');
|
|
240
|
+
console.log('Mermaid.js: All diagrams rendered successfully with theme:', bootstrapTheme);
|
|
143
241
|
}).catch(function(error) {
|
|
144
242
|
console.warn('Mermaid.js: Some diagrams failed to render', error);
|
|
145
243
|
});
|
|
244
|
+
|
|
245
|
+
// ============================================================
|
|
246
|
+
// Step 4: Watch for theme changes and re-render diagrams
|
|
247
|
+
// ============================================================
|
|
248
|
+
|
|
249
|
+
// Create a MutationObserver to watch for theme changes
|
|
250
|
+
var themeObserver = new MutationObserver(function(mutations) {
|
|
251
|
+
mutations.forEach(function(mutation) {
|
|
252
|
+
if (mutation.type === 'attributes' && mutation.attributeName === 'data-bs-theme') {
|
|
253
|
+
var newTheme = getBootstrapTheme();
|
|
254
|
+
var newMermaidConfig = getMermaidConfig(newTheme);
|
|
255
|
+
|
|
256
|
+
// Update Mermaid configuration
|
|
257
|
+
mermaid.initialize({
|
|
258
|
+
startOnLoad: false,
|
|
259
|
+
theme: newMermaidConfig.theme,
|
|
260
|
+
themeVariables: newMermaidConfig.themeVariables,
|
|
261
|
+
flowchart: {
|
|
262
|
+
useMaxWidth: true,
|
|
263
|
+
htmlLabels: true,
|
|
264
|
+
curve: 'basis'
|
|
265
|
+
},
|
|
266
|
+
sequence: {
|
|
267
|
+
diagramMarginX: 50,
|
|
268
|
+
diagramMarginY: 10,
|
|
269
|
+
actorMargin: 50,
|
|
270
|
+
width: 150,
|
|
271
|
+
height: 65,
|
|
272
|
+
boxMargin: 10,
|
|
273
|
+
boxTextMargin: 5,
|
|
274
|
+
noteMargin: 10,
|
|
275
|
+
messageMargin: 35,
|
|
276
|
+
mirrorActors: true,
|
|
277
|
+
bottomMarginAdj: 1,
|
|
278
|
+
useMaxWidth: true
|
|
279
|
+
},
|
|
280
|
+
gantt: {
|
|
281
|
+
titleTopMargin: 25,
|
|
282
|
+
barHeight: 20,
|
|
283
|
+
barGap: 4,
|
|
284
|
+
topPadding: 50,
|
|
285
|
+
leftPadding: 75,
|
|
286
|
+
gridLineStartPadding: 35,
|
|
287
|
+
fontSize: 11,
|
|
288
|
+
numberSectionStyles: 4,
|
|
289
|
+
axisFormat: '%Y-%m-%d'
|
|
290
|
+
},
|
|
291
|
+
securityLevel: 'loose'
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Re-render all diagrams with new theme
|
|
295
|
+
var mermaidDivs = document.querySelectorAll('.mermaid');
|
|
296
|
+
mermaidDivs.forEach(function(div) {
|
|
297
|
+
var content = div.textContent || div.innerText;
|
|
298
|
+
div.innerHTML = '';
|
|
299
|
+
div.textContent = content;
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
mermaid.run().then(function() {
|
|
303
|
+
console.log('Mermaid.js: Diagrams re-rendered with theme:', newTheme);
|
|
304
|
+
}).catch(function(error) {
|
|
305
|
+
console.warn('Mermaid.js: Some diagrams failed to re-render', error);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Start observing the html element for theme changes
|
|
312
|
+
themeObserver.observe(document.documentElement, {
|
|
313
|
+
attributes: true,
|
|
314
|
+
attributeFilter: ['data-bs-theme']
|
|
315
|
+
});
|
|
146
316
|
});
|
|
147
317
|
</script>
|
|
148
318
|
|
|
@@ -157,12 +327,17 @@
|
|
|
157
327
|
margin: 2rem auto;
|
|
158
328
|
background-color: transparent;
|
|
159
329
|
overflow-x: auto;
|
|
330
|
+
padding: 1rem;
|
|
331
|
+
border-radius: 0.5rem;
|
|
332
|
+
transition: background-color 0.3s ease;
|
|
160
333
|
}
|
|
161
334
|
|
|
162
335
|
/* Ensure diagrams are responsive */
|
|
163
336
|
.mermaid svg {
|
|
164
337
|
max-width: 100%;
|
|
165
338
|
height: auto;
|
|
339
|
+
display: block;
|
|
340
|
+
margin: 0 auto;
|
|
166
341
|
}
|
|
167
342
|
|
|
168
343
|
/* Hide code blocks before conversion (prevent flash of unstyled content) */
|
|
@@ -173,15 +348,86 @@
|
|
|
173
348
|
transition: opacity 0.2s;
|
|
174
349
|
}
|
|
175
350
|
|
|
176
|
-
/* Dark mode compatibility */
|
|
351
|
+
/* Dark mode compatibility - Bootstrap theme aware */
|
|
352
|
+
[data-bs-theme="dark"] .mermaid {
|
|
353
|
+
background-color: rgba(33, 37, 41, 0.5);
|
|
354
|
+
border: 1px solid rgba(108, 117, 125, 0.2);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
[data-bs-theme="dark"] .mermaid svg {
|
|
358
|
+
/* Ensure SVG elements are visible in dark mode */
|
|
359
|
+
color-scheme: dark;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
[data-bs-theme="dark"] .mermaid svg text {
|
|
363
|
+
fill: #ffffff !important;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
[data-bs-theme="dark"] .mermaid svg .node rect,
|
|
367
|
+
[data-bs-theme="dark"] .mermaid svg .node polygon,
|
|
368
|
+
[data-bs-theme="dark"] .mermaid svg .cluster rect {
|
|
369
|
+
fill: #343a40 !important;
|
|
370
|
+
stroke: #6c757d !important;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
[data-bs-theme="dark"] .mermaid svg .edgePath .path {
|
|
374
|
+
stroke: #6c757d !important;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
[data-bs-theme="dark"] .mermaid svg .edgeLabel {
|
|
378
|
+
background-color: #212529 !important;
|
|
379
|
+
color: #ffffff !important;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
[data-bs-theme="dark"] .mermaid svg .edgeLabel text {
|
|
383
|
+
fill: #ffffff !important;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/* Light mode styling */
|
|
387
|
+
[data-bs-theme="light"] .mermaid {
|
|
388
|
+
background-color: rgba(248, 249, 250, 0.5);
|
|
389
|
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
[data-bs-theme="light"] .mermaid svg text {
|
|
393
|
+
fill: #212529 !important;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/* Fallback for prefers-color-scheme if data-bs-theme is not set */
|
|
177
397
|
@media (prefers-color-scheme: dark) {
|
|
178
|
-
.mermaid {
|
|
179
|
-
|
|
398
|
+
html:not([data-bs-theme]) .mermaid {
|
|
399
|
+
background-color: rgba(33, 37, 41, 0.5);
|
|
400
|
+
border: 1px solid rgba(108, 117, 125, 0.2);
|
|
180
401
|
}
|
|
181
402
|
}
|
|
182
403
|
|
|
404
|
+
/* Smooth theme transition */
|
|
405
|
+
.mermaid svg {
|
|
406
|
+
transition: opacity 0.3s ease;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/* Loading state */
|
|
410
|
+
.mermaid:not(:has(svg)) {
|
|
411
|
+
min-height: 100px;
|
|
412
|
+
display: flex;
|
|
413
|
+
align-items: center;
|
|
414
|
+
justify-content: center;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.mermaid:not(:has(svg))::after {
|
|
418
|
+
content: 'Loading diagram...';
|
|
419
|
+
color: var(--bs-secondary);
|
|
420
|
+
font-size: 0.875rem;
|
|
421
|
+
}
|
|
422
|
+
|
|
183
423
|
/* Print styles */
|
|
184
424
|
@media print {
|
|
425
|
+
.mermaid {
|
|
426
|
+
background-color: transparent !important;
|
|
427
|
+
border: none !important;
|
|
428
|
+
page-break-inside: avoid;
|
|
429
|
+
}
|
|
430
|
+
|
|
185
431
|
.mermaid svg {
|
|
186
432
|
max-width: 100% !important;
|
|
187
433
|
page-break-inside: avoid;
|
data/_includes/core/head.html
CHANGED
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
<script defer src="{{ '/assets/js/halfmoon.js' | relative_url }}"></script>
|
|
43
43
|
<script defer src="{{ '/assets/js/side-bar-folders.js' | relative_url }}"></script>
|
|
44
44
|
<script defer src="{{ '/assets/js/code-copy.js' | relative_url }}"></script>
|
|
45
|
+
<script defer src="{{ '/assets/js/ui-enhancements.js' | relative_url }}"></script>
|
|
45
46
|
|
|
46
47
|
<!-- ================================ -->
|
|
47
48
|
<!-- THIRD PARTY INTEGRATIONS -->
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<div class="card-body p-4 d-flex flex-column text-center">
|
|
9
9
|
<p class="card-text mb-3">Install the theme as a Ruby gem for classic Jekyll workflows.</p>
|
|
10
10
|
<pre class="bg-dark text-light p-3 rounded mb-3 small text-start overflow-auto"><code>gem install {{ site.resources.rubygems.name | default: 'zer0-mistakes' }}</code></pre>
|
|
11
|
-
<a class="btn btn-outline-primary btn-sm mt-auto" href="{{ site.resources.rubygems.url | default: '#' }}" target="_blank" rel="noopener">View on RubyGems</a>
|
|
11
|
+
<a class="btn btn-outline-primary btn-sm mt-auto" href="{{ site.resources.rubygems.url | default: '' | join: '' | default: '#' }}" target="_blank" rel="noopener">View on RubyGems</a>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
14
|
</div>
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
</div>
|
|
21
21
|
<div class="card-body p-4 d-flex flex-column text-center">
|
|
22
22
|
<p class="card-text mb-3">Run locally with zero Ruby setup using Docker.</p>
|
|
23
|
-
<pre class="bg-dark text-light p-3 rounded mb-3 small text-start overflow-auto"><code>docker pull {{ site.resources.docker.image | default: 'bamr87/zer0-mistakes' }}
|
|
24
|
-
docker run -p 4000:4000 {{ site.resources.docker.image | default: 'bamr87/zer0-mistakes' }}</code></pre>
|
|
25
|
-
<a class="btn btn-outline-info btn-sm mt-auto" href="{{ site.resources.docker.hub_url | default: '#' }}" target="_blank" rel="noopener">View on Docker Hub</a>
|
|
23
|
+
<pre class="bg-dark text-light p-3 rounded mb-3 small text-start overflow-auto"><code>docker pull {{ site.resources.docker.image | default: '' | join: '' | default: 'bamr87/zer0-mistakes' }}
|
|
24
|
+
docker run -p 4000:4000 {{ site.resources.docker.image | default: '' | join: '' | default: 'bamr87/zer0-mistakes' }}</code></pre>
|
|
25
|
+
<a class="btn btn-outline-info btn-sm mt-auto" href="{{ site.resources.docker.hub_url | default: '' | join: '' | default: '#' }}" target="_blank" rel="noopener">View on Docker Hub</a>
|
|
26
26
|
</div>
|
|
27
27
|
</div>
|
|
28
28
|
</div>
|
|
@@ -34,11 +34,11 @@ docker run -p 4000:4000 {{ site.resources.docker.image | default: 'bamr87/zer0-m
|
|
|
34
34
|
</div>
|
|
35
35
|
<div class="card-body p-4 d-flex flex-column text-center">
|
|
36
36
|
<p class="card-text mb-3">Improve the theme by forking the repo and opening a PR.</p>
|
|
37
|
-
<pre class="bg-dark text-light p-3 rounded mb-3 small text-start overflow-auto"><code>git clone {{ site.resources.github_repo | default: site.github.repository_url }}
|
|
37
|
+
<pre class="bg-dark text-light p-3 rounded mb-3 small text-start overflow-auto"><code>git clone {{ site.resources.github_repo | default: '' | join: '' | default: site.github.repository_url }}
|
|
38
38
|
cd {{ site.local_repo | default: site.repository_name | default: 'repo' }}
|
|
39
|
-
git remote add upstream {{ site.resources.github_repo | default: site.github.repository_url }}
|
|
39
|
+
git remote add upstream {{ site.resources.github_repo | default: '' | join: '' | default: site.github.repository_url }}
|
|
40
40
|
git checkout -b feature/your-change</code></pre>
|
|
41
|
-
<a class="btn btn-outline-secondary btn-sm mt-auto" href="{{ site.resources.github_fork | default: site.github.repository_url | append: '/fork' }}" target="_blank" rel="noopener">Fork on GitHub</a>
|
|
41
|
+
<a class="btn btn-outline-secondary btn-sm mt-auto" href="{{ site.resources.github_fork | default: '' | join: '' | default: site.github.repository_url | append: '/fork' }}" target="_blank" rel="noopener">Fork on GitHub</a>
|
|
42
42
|
</div>
|
|
43
43
|
</div>
|
|
44
44
|
</div>
|
|
@@ -46,7 +46,7 @@ git checkout -b feature/your-change</code></pre>
|
|
|
46
46
|
|
|
47
47
|
<!-- Contributing guide call-to-action placed below all cards -->
|
|
48
48
|
<div class="text-center mt-4">
|
|
49
|
-
<a class="btn btn-outline-secondary" href="{{ site.resources.contributing | default: '#' }}" target="_blank" rel="noopener">
|
|
49
|
+
<a class="btn btn-outline-secondary" href="{{ site.resources.contributing | default: '' | join: '' | default: '#' }}" target="_blank" rel="noopener">
|
|
50
50
|
<i class="bi bi-journal-text me-2"></i>Read the Contributing Guide
|
|
51
51
|
</a>
|
|
52
52
|
</div>
|
|
@@ -3,22 +3,22 @@
|
|
|
3
3
|
<div class="container-xl px-4 px-md-5">
|
|
4
4
|
<div class="row g-3 justify-content-center text-center align-items-center">
|
|
5
5
|
<div class="col-6 col-md-3 d-flex justify-content-center">
|
|
6
|
-
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.github_repo | default: site.github.repository_url | default: '/' }}" target="_blank" rel="noopener">
|
|
6
|
+
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.github_repo | default: '' | join: '' | default: site.github.repository_url | default: '/' }}" target="_blank" rel="noopener">
|
|
7
7
|
<i class="bi bi-github me-2"></i> GitHub
|
|
8
8
|
</a>
|
|
9
9
|
</div>
|
|
10
10
|
<div class="col-6 col-md-3 d-flex justify-content-center">
|
|
11
|
-
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.rubygems.url | default: '#' }}" target="_blank" rel="noopener">
|
|
11
|
+
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.rubygems.url | default: '' | join: '' | default: '#' }}" target="_blank" rel="noopener">
|
|
12
12
|
<i class="bi bi-gem me-2"></i> RubyGems
|
|
13
13
|
</a>
|
|
14
14
|
</div>
|
|
15
15
|
<div class="col-6 col-md-3 d-flex justify-content-center">
|
|
16
|
-
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.docker.hub_url | default: '#' }}" target="_blank" rel="noopener">
|
|
16
|
+
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.docker.hub_url | default: '' | join: '' | default: '#' }}" target="_blank" rel="noopener">
|
|
17
17
|
<i class="bi bi-box-seam me-2"></i> Docker Hub
|
|
18
18
|
</a>
|
|
19
19
|
</div>
|
|
20
20
|
<div class="col-6 col-md-3 d-flex justify-content-center">
|
|
21
|
-
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.github_fork | default: site.github.repository_url | append: '/fork' }}" target="_blank" rel="noopener">
|
|
21
|
+
<a class="btn btn-outline-light btn-sm w-100" href="{{ site.resources.github_fork | default: '' | join: '' | default: site.github.repository_url | append: '/fork' }}" target="_blank" rel="noopener">
|
|
22
22
|
<i class="bi bi-git me-2"></i> Fork Project
|
|
23
23
|
</a>
|
|
24
24
|
</div>
|
|
@@ -10,14 +10,37 @@
|
|
|
10
10
|
<ol itemscope itemtype="https://schema.org/BreadcrumbList">
|
|
11
11
|
<i class="bi bi-folder"></i>
|
|
12
12
|
{% assign crumbs = page.url | remove:'/index.html' | split: '/' %}
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
{% assign section = crumbs[1] | default: '' %}
|
|
14
|
+
<a href="{{ '/' | relative_url }}">root</a>
|
|
15
|
+
|
|
16
|
+
{% comment %}
|
|
17
|
+
Avoid linking to intermediate directories that don't have index pages.
|
|
18
|
+
Example: posts are /posts/YYYY/MM/DD/slug/ (only /posts/ and the leaf page exist).
|
|
19
|
+
{% endcomment %}
|
|
20
|
+
{% if section == 'posts' %}
|
|
21
|
+
/ <a href="{{ '/posts/' | relative_url }}">Posts</a>
|
|
22
|
+
/ {{ page.title }}
|
|
23
|
+
{% elsif section == 'notebooks' %}
|
|
24
|
+
/ <a href="{{ '/notebooks/' | relative_url }}">Notebooks</a>
|
|
25
|
+
/ {{ page.title }}
|
|
26
|
+
{% elsif section == 'notes' %}
|
|
27
|
+
/ <a href="{{ '/notes/' | relative_url }}">Notes</a>
|
|
28
|
+
/ {{ page.title }}
|
|
29
|
+
{% elsif section == 'docs' %}
|
|
30
|
+
/ <a href="{{ '/docs/' | relative_url }}">Docs</a>
|
|
31
|
+
/ {{ page.title }}
|
|
17
32
|
{% else %}
|
|
18
|
-
|
|
33
|
+
{% for crumb in crumbs offset: 1 %}
|
|
34
|
+
{% if forloop.last %}
|
|
35
|
+
/ {{ page.title }}
|
|
36
|
+
{% elsif forloop.first %}
|
|
37
|
+
/ <a href="{{ '/' | append: crumb | append: '/' | relative_url }}">{{ crumb | replace:'-',' ' | remove:'.html' | capitalize }}</a>
|
|
38
|
+
{% else %}
|
|
39
|
+
{% comment %} Keep intermediate crumbs as plain text to avoid dead links {% endcomment %}
|
|
40
|
+
/ {{ crumb | replace:'-',' ' | remove:'.html' | capitalize }}
|
|
41
|
+
{% endif %}
|
|
42
|
+
{% endfor %}
|
|
19
43
|
{% endif %}
|
|
20
|
-
{% endfor %}
|
|
21
44
|
</ol>
|
|
22
45
|
</nav>
|
|
23
46
|
<!-- Secret Search bar -->
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
===================================================================
|
|
3
|
+
NAV TREE - Flat YAML Navigation Renderer
|
|
4
|
+
===================================================================
|
|
5
|
+
|
|
6
|
+
File: nav-tree.html
|
|
7
|
+
Path: _includes/navigation/nav-tree.html
|
|
8
|
+
Purpose: Render hierarchical navigation from YAML data files
|
|
9
|
+
|
|
10
|
+
Parameters:
|
|
11
|
+
- nav: Name of navigation file in _data/navigation/ (e.g., "docs", "main")
|
|
12
|
+
|
|
13
|
+
Data Schema (expected in _data/navigation/*.yml):
|
|
14
|
+
- title: string (required) - Display text
|
|
15
|
+
- url: string (optional) - Link URL
|
|
16
|
+
- icon: string (optional) - Bootstrap Icons class (e.g., "bi-folder")
|
|
17
|
+
- expanded: boolean (optional) - Default expanded state (default: false)
|
|
18
|
+
- children: array (optional) - Nested navigation items (max 2 levels)
|
|
19
|
+
|
|
20
|
+
Note: This implementation supports 2 levels of nesting to avoid Jekyll's
|
|
21
|
+
include depth limit. For deeper nesting, consider a plugin approach.
|
|
22
|
+
|
|
23
|
+
Dependencies:
|
|
24
|
+
- site.data.navigation[nav]: Navigation YAML data
|
|
25
|
+
- Bootstrap 5 collapse component
|
|
26
|
+
- Bootstrap Icons for visual indicators
|
|
27
|
+
|
|
28
|
+
Usage:
|
|
29
|
+
include navigation/nav-tree.html nav="docs"
|
|
30
|
+
===================================================================
|
|
31
|
+
-->
|
|
32
|
+
|
|
33
|
+
{% assign navigation = site.data.navigation[include.nav] %}
|
|
34
|
+
|
|
35
|
+
{% if navigation %}
|
|
36
|
+
<ul class="list-unstyled fw-normal pb-2 small nav-tree-root">
|
|
37
|
+
{% for item in navigation %}
|
|
38
|
+
{% assign item_id = item.title | slugify | prepend: "nav-" %}
|
|
39
|
+
{% assign is_active = page.url == item.url %}
|
|
40
|
+
{% assign is_expanded = item.expanded | default: false %}
|
|
41
|
+
{% assign has_children = item.children and item.children.size > 0 %}
|
|
42
|
+
|
|
43
|
+
<li class="mb-1 nav-tree-item" data-depth="0">
|
|
44
|
+
{% if has_children %}
|
|
45
|
+
<!-- Parent item with children - collapsible -->
|
|
46
|
+
<div class="d-flex align-items-center">
|
|
47
|
+
{% if item.url %}
|
|
48
|
+
<a href="{{ item.url | relative_url }}"
|
|
49
|
+
class="nav-tree-link flex-grow-1 d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if is_active %} active{% endif %}">
|
|
50
|
+
{% if item.icon %}<i class="{{ item.icon }} me-2"></i>{% endif %}
|
|
51
|
+
<span>{{ item.title }}</span>
|
|
52
|
+
</a>
|
|
53
|
+
<button class="btn btn-sm btn-link nav-tree-toggle p-1{% unless is_expanded %} collapsed{% endunless %}"
|
|
54
|
+
type="button"
|
|
55
|
+
data-bs-toggle="collapse"
|
|
56
|
+
data-bs-target="#{{ item_id }}"
|
|
57
|
+
aria-expanded="{{ is_expanded }}"
|
|
58
|
+
aria-controls="{{ item_id }}"
|
|
59
|
+
aria-label="Toggle {{ item.title }} submenu">
|
|
60
|
+
<i class="bi bi-chevron-down"></i>
|
|
61
|
+
</button>
|
|
62
|
+
{% else %}
|
|
63
|
+
<button class="btn btn-link nav-tree-toggle w-100 d-flex align-items-center text-start fw-semibold py-1 px-2{% unless is_expanded %} collapsed{% endunless %}"
|
|
64
|
+
type="button"
|
|
65
|
+
data-bs-toggle="collapse"
|
|
66
|
+
data-bs-target="#{{ item_id }}"
|
|
67
|
+
aria-expanded="{{ is_expanded }}"
|
|
68
|
+
aria-controls="{{ item_id }}">
|
|
69
|
+
{% if item.icon %}<i class="{{ item.icon }} me-2"></i>{% endif %}
|
|
70
|
+
<span class="flex-grow-1">{{ item.title }}</span>
|
|
71
|
+
<i class="bi bi-chevron-down nav-tree-chevron"></i>
|
|
72
|
+
</button>
|
|
73
|
+
{% endif %}
|
|
74
|
+
</div>
|
|
75
|
+
|
|
76
|
+
<!-- Children container (Level 1) -->
|
|
77
|
+
<div class="collapse{% if is_expanded %} show{% endif %}" id="{{ item_id }}">
|
|
78
|
+
<ul class="list-unstyled fw-normal ps-3 nav-tree-children">
|
|
79
|
+
{% for child in item.children %}
|
|
80
|
+
{% assign child_id = child.title | slugify | prepend: "nav-" %}
|
|
81
|
+
{% assign child_active = page.url == child.url %}
|
|
82
|
+
{% assign child_expanded = child.expanded | default: false %}
|
|
83
|
+
{% assign child_has_children = child.children and child.children.size > 0 %}
|
|
84
|
+
|
|
85
|
+
<li class="mb-1 nav-tree-item" data-depth="1">
|
|
86
|
+
{% if child_has_children %}
|
|
87
|
+
<!-- Level 1 parent with children -->
|
|
88
|
+
<div class="d-flex align-items-center">
|
|
89
|
+
{% if child.url %}
|
|
90
|
+
<a href="{{ child.url | relative_url }}"
|
|
91
|
+
class="nav-tree-link flex-grow-1 d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if child_active %} active{% endif %}">
|
|
92
|
+
{% if child.icon %}<i class="{{ child.icon }} me-2"></i>{% endif %}
|
|
93
|
+
<span>{{ child.title }}</span>
|
|
94
|
+
</a>
|
|
95
|
+
<button class="btn btn-sm btn-link nav-tree-toggle p-1{% unless child_expanded %} collapsed{% endunless %}"
|
|
96
|
+
type="button"
|
|
97
|
+
data-bs-toggle="collapse"
|
|
98
|
+
data-bs-target="#{{ child_id }}"
|
|
99
|
+
aria-expanded="{{ child_expanded }}"
|
|
100
|
+
aria-controls="{{ child_id }}">
|
|
101
|
+
<i class="bi bi-chevron-down"></i>
|
|
102
|
+
</button>
|
|
103
|
+
{% else %}
|
|
104
|
+
<button class="btn btn-link nav-tree-toggle w-100 d-flex align-items-center text-start py-1 px-2{% unless child_expanded %} collapsed{% endunless %}"
|
|
105
|
+
type="button"
|
|
106
|
+
data-bs-toggle="collapse"
|
|
107
|
+
data-bs-target="#{{ child_id }}"
|
|
108
|
+
aria-expanded="{{ child_expanded }}"
|
|
109
|
+
aria-controls="{{ child_id }}">
|
|
110
|
+
{% if child.icon %}<i class="{{ child.icon }} me-2"></i>{% endif %}
|
|
111
|
+
<span class="flex-grow-1">{{ child.title }}</span>
|
|
112
|
+
<i class="bi bi-chevron-down nav-tree-chevron"></i>
|
|
113
|
+
</button>
|
|
114
|
+
{% endif %}
|
|
115
|
+
</div>
|
|
116
|
+
|
|
117
|
+
<!-- Children container (Level 2) -->
|
|
118
|
+
<div class="collapse{% if child_expanded %} show{% endif %}" id="{{ child_id }}">
|
|
119
|
+
<ul class="list-unstyled fw-normal ps-3 nav-tree-children">
|
|
120
|
+
{% for grandchild in child.children %}
|
|
121
|
+
{% assign gc_active = page.url == grandchild.url %}
|
|
122
|
+
<li class="mb-1 nav-tree-item" data-depth="2">
|
|
123
|
+
{% if grandchild.url %}
|
|
124
|
+
<a href="{{ grandchild.url | relative_url }}"
|
|
125
|
+
class="nav-tree-link d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if gc_active %} active{% endif %}">
|
|
126
|
+
{% if grandchild.icon %}<i class="{{ grandchild.icon }} me-2"></i>{% endif %}
|
|
127
|
+
<span>{{ grandchild.title }}</span>
|
|
128
|
+
</a>
|
|
129
|
+
{% else %}
|
|
130
|
+
<span class="nav-tree-text d-inline-flex align-items-center py-1 px-2 text-muted">
|
|
131
|
+
{% if grandchild.icon %}<i class="{{ grandchild.icon }} me-2"></i>{% endif %}
|
|
132
|
+
<span>{{ grandchild.title }}</span>
|
|
133
|
+
</span>
|
|
134
|
+
{% endif %}
|
|
135
|
+
</li>
|
|
136
|
+
{% endfor %}
|
|
137
|
+
</ul>
|
|
138
|
+
</div>
|
|
139
|
+
{% else %}
|
|
140
|
+
<!-- Level 1 leaf item -->
|
|
141
|
+
{% if child.url %}
|
|
142
|
+
<a href="{{ child.url | relative_url }}"
|
|
143
|
+
class="nav-tree-link d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if child_active %} active{% endif %}">
|
|
144
|
+
{% if child.icon %}<i class="{{ child.icon }} me-2"></i>{% endif %}
|
|
145
|
+
<span>{{ child.title }}</span>
|
|
146
|
+
</a>
|
|
147
|
+
{% else %}
|
|
148
|
+
<span class="nav-tree-text d-inline-flex align-items-center py-1 px-2 text-muted">
|
|
149
|
+
{% if child.icon %}<i class="{{ child.icon }} me-2"></i>{% endif %}
|
|
150
|
+
<span>{{ child.title }}</span>
|
|
151
|
+
</span>
|
|
152
|
+
{% endif %}
|
|
153
|
+
{% endif %}
|
|
154
|
+
</li>
|
|
155
|
+
{% endfor %}
|
|
156
|
+
</ul>
|
|
157
|
+
</div>
|
|
158
|
+
{% else %}
|
|
159
|
+
<!-- Root level leaf item -->
|
|
160
|
+
{% if item.url %}
|
|
161
|
+
<a href="{{ item.url | relative_url }}"
|
|
162
|
+
class="nav-tree-link d-inline-flex align-items-center rounded py-1 px-2 text-decoration-none{% if is_active %} active{% endif %}">
|
|
163
|
+
{% if item.icon %}<i class="{{ item.icon }} me-2"></i>{% endif %}
|
|
164
|
+
<span>{{ item.title }}</span>
|
|
165
|
+
</a>
|
|
166
|
+
{% else %}
|
|
167
|
+
<span class="nav-tree-text d-inline-flex align-items-center py-1 px-2 text-muted">
|
|
168
|
+
{% if item.icon %}<i class="{{ item.icon }} me-2"></i>{% endif %}
|
|
169
|
+
<span>{{ item.title }}</span>
|
|
170
|
+
</span>
|
|
171
|
+
{% endif %}
|
|
172
|
+
{% endif %}
|
|
173
|
+
</li>
|
|
174
|
+
{% endfor %}
|
|
175
|
+
</ul>
|
|
176
|
+
{% else %}
|
|
177
|
+
<p class="text-muted small">
|
|
178
|
+
<i class="bi bi-exclamation-triangle me-1"></i>
|
|
179
|
+
Navigation "{{ include.nav }}" not found in _data/navigation/
|
|
180
|
+
</p>
|
|
181
|
+
{% endif %}
|