@docmd/template-summer 0.8.6
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/LICENSE +21 -0
- package/README.md +90 -0
- package/dist/assets/css/summer.css +3418 -0
- package/dist/assets/js/summer.js +660 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +79 -0
- package/dist/templates/404.ejs +156 -0
- package/dist/templates/layout.ejs +609 -0
- package/dist/templates/partials/footer.ejs +69 -0
- package/dist/templates/partials/menubar.ejs +92 -0
- package/dist/templates/partials/options-menu.ejs +45 -0
- package/dist/templates/toc.ejs +53 -0
- package/package.json +61 -0
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
============================================================================
|
|
3
|
+
@docmd/template-summer — layout.ejs
|
|
4
|
+
|
|
5
|
+
A complete, GitBook-inspired documentation layout. Built to feel like its
|
|
6
|
+
own product — not a recolor of the default template. The page is structured
|
|
7
|
+
as five vertically-stacked, sticky-aware bands:
|
|
8
|
+
|
|
9
|
+
1. Top bar — logo, centered search, AI "Ask" button, action menu
|
|
10
|
+
2. Sub navigation — section tabs (Documentation, Guides, …) + extras
|
|
11
|
+
3. Page header — sticky breadcrumb + title + copy widgets
|
|
12
|
+
4. Layout grid — sidebar | main content | right-rail TOC
|
|
13
|
+
5. Footer — branding + links
|
|
14
|
+
|
|
15
|
+
All CSS lives in assets/css/summer.css and is fully self-contained —
|
|
16
|
+
docmd-main.css is intentionally NOT loaded.
|
|
17
|
+
|
|
18
|
+
Note: menubar, footer and TOC partials are INLINED here (not `include`d)
|
|
19
|
+
because the docmd core resolves `include()` paths relative to the
|
|
20
|
+
default layout's directory, not the resolved template's. Inlining
|
|
21
|
+
guarantees the summer-styled partials always render.
|
|
22
|
+
============================================================================
|
|
23
|
+
-->
|
|
24
|
+
<!DOCTYPE html>
|
|
25
|
+
<html lang="<%= (locals.activeLocale && locals.activeLocale.id) ? locals.activeLocale.id : 'en' %>"
|
|
26
|
+
<%= (locals.activeLocale && locals.activeLocale.dir && locals.activeLocale.dir !== 'ltr') ? ' dir="' + locals.activeLocale.dir + '"' : '' %>>
|
|
27
|
+
<head>
|
|
28
|
+
<meta charset="UTF-8">
|
|
29
|
+
<meta name="generator" content="docmd template-summer v0.8.7">
|
|
30
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
31
|
+
<meta name="theme-color" content="#fbfaf6" media="(prefers-color-scheme: light)">
|
|
32
|
+
<meta name="theme-color" content="#13110d" media="(prefers-color-scheme: dark)">
|
|
33
|
+
<title><%= pageTitle %><% if (siteTitle && pageTitle !== siteTitle) { %> · <%= siteTitle %><% } %></title>
|
|
34
|
+
|
|
35
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
36
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
37
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet">
|
|
38
|
+
|
|
39
|
+
<%- themeInitScript %>
|
|
40
|
+
|
|
41
|
+
<% if (locals.localePagesJson) { %>
|
|
42
|
+
<script id="docmd-locale-pages" type="application/json"><%- locals.localePagesJson %></script>
|
|
43
|
+
<% } %>
|
|
44
|
+
|
|
45
|
+
<script>
|
|
46
|
+
window.DOCMD_TEMPLATE = 'summer';
|
|
47
|
+
window.DOCMD_ROOT = "<%= relativePathToRoot %>" || './';
|
|
48
|
+
window.DOCMD_APPEARANCE = "<%= appearance %>";
|
|
49
|
+
window.DOCMD_VERSION_ROOT = "<%= locals.versionRoot || '/' %>";
|
|
50
|
+
window.DOCMD_BASE = "<%= config.base || '/' %>";
|
|
51
|
+
window.DOCMD_LOCALE = "<%= (locals.activeLocale && locals.activeLocale.id) ? locals.activeLocale.id : '' %>";
|
|
52
|
+
window.DOCMD_DEFAULT_LOCALE = "<%= locals.defaultLocale || '' %>";
|
|
53
|
+
const _localePagesEl = document.getElementById('docmd-locale-pages');
|
|
54
|
+
if (_localePagesEl) {
|
|
55
|
+
window.DOCMD_LOCALE_PAGES = JSON.parse(_localePagesEl.textContent);
|
|
56
|
+
}
|
|
57
|
+
</script>
|
|
58
|
+
|
|
59
|
+
<%- typeof faviconLinkHtml !== 'undefined' ? faviconLinkHtml : '' %>
|
|
60
|
+
|
|
61
|
+
<%# ── Highlight.js themes — light + dark, toggled by theme-init ── %>
|
|
62
|
+
<% if (config.theme?.codeHighlight !== false) { const isDarkDefault = appearance === 'dark'; %>
|
|
63
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-highlight-light.css?v=<%= buildHash %>" id="hljs-light" <%= isDarkDefault ? 'disabled' : '' %>>
|
|
64
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %>assets/css/docmd-highlight-dark.css?v=<%= buildHash %>" id="hljs-dark" <%= isDarkDefault ? '' : 'disabled' %>>
|
|
65
|
+
<% } %>
|
|
66
|
+
|
|
67
|
+
<%- pluginHeadScriptsHtml || '' %>
|
|
68
|
+
<% (customCssFiles || []).forEach(cssFile => { %>
|
|
69
|
+
<link rel="stylesheet" href="<%= relativePathToRoot %><%= cssFile.startsWith('/') ? cssFile.substring(1) : cssFile %>?v=<%= buildHash %>">
|
|
70
|
+
<% }); %>
|
|
71
|
+
|
|
72
|
+
<%
|
|
73
|
+
const _noSidebar = (sidebarConfig?.enabled === false);
|
|
74
|
+
const _noToc = (config.theme?.toc === false);
|
|
75
|
+
const _noHeader = (headerConfig?.enabled === false);
|
|
76
|
+
const _hasMenubar = (locals.menubarConfig && menubarConfig?.enabled !== false);
|
|
77
|
+
const _hasBanner = (locals.config && config.layout && config.layout.banner);
|
|
78
|
+
const _bodyClasses = ['summer-template'];
|
|
79
|
+
if (_noSidebar) _bodyClasses.push('no-sidebar');
|
|
80
|
+
if (_noToc) _bodyClasses.push('no-toc');
|
|
81
|
+
if (_noHeader) _bodyClasses.push('no-header');
|
|
82
|
+
if (_hasMenubar) _bodyClasses.push('has-menubar');
|
|
83
|
+
if (_hasBanner) _bodyClasses.push('has-banner');
|
|
84
|
+
%>
|
|
85
|
+
</head>
|
|
86
|
+
<body class="<%= _bodyClasses.join(' ') %>"
|
|
87
|
+
<%# data-* attributes that docmd-main.js reads to wire SPA + features.
|
|
88
|
+
* - spa-enabled: gate the docmd-main.js SPA router
|
|
89
|
+
* - copy-code-enabled: gate the per-pre copy button injection
|
|
90
|
+
* - default-collapsed: matches the sidebar partial's first-paint
|
|
91
|
+
* state for the sidebar groups (summer ignores
|
|
92
|
+
* this and renders all groups open by default). %>
|
|
93
|
+
data-spa-enabled="<%= (config.layout?.spa !== false).toString() %>"
|
|
94
|
+
data-copy-code-enabled="<%= (config.copyCode === true).toString() %>"
|
|
95
|
+
data-default-collapsed="<%= sidebarConfig?.defaultCollapsed === true %>">
|
|
96
|
+
<a href="#main-content" class="skip-link"><%= typeof t === 'function' ? t('skipToContent') : 'Skip to content' %></a>
|
|
97
|
+
|
|
98
|
+
<%# ─────────────────────────────────────────────────────────────
|
|
99
|
+
Optional banner (data-docmd-banner is what docmd-main.js's
|
|
100
|
+
initBanner() listens for so close-state is sessionStorage-persisted)
|
|
101
|
+
───────────────────────────────────────────────────────────── %>
|
|
102
|
+
<% if (_hasBanner) { %>
|
|
103
|
+
<div class="summer-banner" data-docmd-banner role="region" aria-label="Site announcement">
|
|
104
|
+
<div class="summer-banner__inner">
|
|
105
|
+
<span><%- typeof config.layout.banner === 'string' ? config.layout.banner : '' %></span>
|
|
106
|
+
<button class="summer-banner__close sidebar-menu-button" type="button" data-docmd-banner-dismiss aria-label="Dismiss banner">
|
|
107
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
<% } %>
|
|
112
|
+
|
|
113
|
+
<%# ─────────────────────────────────────────────────────────────
|
|
114
|
+
BAND 1: Top bar
|
|
115
|
+
───────────────────────────────────────────────────────────── %>
|
|
116
|
+
<header class="summer-topbar" role="banner">
|
|
117
|
+
<div class="summer-topbar__inner">
|
|
118
|
+
<%# LEFT — Logo + mobile sidebar toggle
|
|
119
|
+
* The button carries both data-summer-sidebar-toggle (for
|
|
120
|
+
* any custom hooks) and the docmd-main.js .sidebar-menu-button
|
|
121
|
+
* class so the standard mobile-drawer behaviour in
|
|
122
|
+
* docmd-main.js (closes on outside click + Escape) just works.
|
|
123
|
+
───────────────────────────────────────────────────────────── %>
|
|
124
|
+
<div class="summer-topbar__left">
|
|
125
|
+
<button class="summer-iconbtn summer-topbar__mobile sidebar-menu-button" type="button" data-summer-sidebar-toggle aria-label="Toggle navigation menu">
|
|
126
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
|
|
127
|
+
</button>
|
|
128
|
+
<% if (logo && (logo.light || logo.dark)) { %>
|
|
129
|
+
<a href="<%= logo.href || relativePathToRoot %>" class="summer-logo" aria-label="<%= logo.alt || siteTitle %> — home">
|
|
130
|
+
<% if (logo.light) { %><img src="<%= relativePathToRoot %><%= logo.light.startsWith('/') ? logo.light.substring(1) : logo.light %>" alt="<%= logo.alt || siteTitle %>" class="summer-logo__light" <% if (logo.height) { %>style="height: <%= logo.height %>;"<% } %>><% } %>
|
|
131
|
+
<% if (logo.dark) { %><img src="<%= relativePathToRoot %><%= logo.dark.startsWith('/') ? logo.dark.substring(1) : logo.dark %>" alt="<%= logo.alt || siteTitle %>" class="summer-logo__dark" <% if (logo.height) { %>style="height: <%= logo.height %>;"<% } %>><% } %>
|
|
132
|
+
</a>
|
|
133
|
+
<% } else { %>
|
|
134
|
+
<a href="<%= relativePathToRoot %>" class="summer-logo summer-logo--text">
|
|
135
|
+
<span class="summer-logo__icon"><%= (siteTitle || 'D').charAt(0).toUpperCase() %></span>
|
|
136
|
+
<span><%= siteTitle %></span>
|
|
137
|
+
</a>
|
|
138
|
+
<% } %>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<%# CENTER — Inline Search Input (GitBook-style dropdown) %>
|
|
142
|
+
<div class="summer-topbar__center">
|
|
143
|
+
<div class="summer-search-container">
|
|
144
|
+
<svg class="summer-search__icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
|
|
145
|
+
<input type="text" class="summer-search-input" placeholder="<%= typeof t === 'function' ? t('search') : 'Search docs' %> (⌘K)" aria-label="Search documentation" autocomplete="off" spellcheck="false">
|
|
146
|
+
<div class="summer-search-dropdown" style="display: none;">
|
|
147
|
+
<div class="summer-search-results-wrapper"></div>
|
|
148
|
+
<div class="summer-search-dropdown-footer">
|
|
149
|
+
<span><kbd>↑</kbd> <kbd>↓</kbd> to navigate</span>
|
|
150
|
+
<span><kbd>ESC</kbd> to close</span>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
</div>
|
|
155
|
+
|
|
156
|
+
<%# RIGHT — Action icons (theme, language, sponsor, github) %>
|
|
157
|
+
<div class="summer-topbar__right">
|
|
158
|
+
<% const _om = locals.optionsMenu; %>
|
|
159
|
+
<% if (!_om || _om.components?.themeSwitch !== false) { %>
|
|
160
|
+
<button class="summer-iconbtn theme-toggle-button" type="button" data-summer-theme-toggle aria-label="Toggle theme">
|
|
161
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2"></path><path d="M12 20v2"></path><path d="m4.93 4.93 1.41 1.41"></path><path d="m17.66 17.66 1.41 1.41"></path><path d="M2 12h2"></path><path d="M20 12h2"></path><path d="m6.34 17.66-1.41 1.41"></path><path d="m19.07 4.93-1.41 1.41"></path></svg>
|
|
162
|
+
</button>
|
|
163
|
+
<% } %>
|
|
164
|
+
|
|
165
|
+
<% if (locals.allLocales && allLocales && allLocales.length > 1 && (!config.i18n || config.i18n.position === 'header' || config.i18n.position === 'options-menu' || config.i18n.position === 'topbar')) { %>
|
|
166
|
+
<div class="summer-options-menu__item">
|
|
167
|
+
<%- await include('partials/language-switcher', { allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config, renderIcon, compact: true, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix }) %>
|
|
168
|
+
</div>
|
|
169
|
+
<% } %>
|
|
170
|
+
|
|
171
|
+
<%# Sponsor link — rendered in the topbar unless its position is
|
|
172
|
+
explicitly set to 'footer' (in which case it's rendered in the
|
|
173
|
+
footer only). Use position: 'both' to show in both zones. %>
|
|
174
|
+
<% const _sponsorUrl = _om && _om.components?.sponsor; %>
|
|
175
|
+
<% const _sponsorPos = _om && _om.components?.sponsorPosition
|
|
176
|
+
? _om.components.sponsorPosition
|
|
177
|
+
: (_om && _om.position === 'footer' ? 'footer' : 'top'); %>
|
|
178
|
+
<% if (_sponsorUrl && (_sponsorPos === 'top' || _sponsorPos === 'both')) { %>
|
|
179
|
+
<a href="<%= _sponsorUrl %>" target="_blank" rel="noopener" class="summer-iconbtn" aria-label="Sponsor">
|
|
180
|
+
<svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
|
|
181
|
+
</a>
|
|
182
|
+
<% } %>
|
|
183
|
+
|
|
184
|
+
<% if (_om && _om.components?.github) { %>
|
|
185
|
+
<a href="<%= _om.components.github %>" target="_blank" rel="noopener" class="summer-iconbtn" aria-label="GitHub">
|
|
186
|
+
<svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><path d="M12 .5C5.4.5 0 5.9 0 12.5c0 5.3 3.4 9.8 8.2 11.4.6.1.8-.3.8-.6v-2.2c-3.3.7-4-1.6-4-1.6-.5-1.4-1.3-1.7-1.3-1.7-1.1-.7.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1.1 1.8 2.8 1.3 3.5 1 .1-.8.4-1.3.8-1.6-2.7-.3-5.5-1.3-5.5-6 0-1.3.5-2.4 1.3-3.2-.1-.3-.6-1.5.1-3.2 0 0 1-.3 3.3 1.2 1-.3 2-.4 3-.4s2 .1 3 .4c2.3-1.5 3.3-1.2 3.3-1.2.7 1.7.2 2.9.1 3.2.8.8 1.3 1.9 1.3 3.2 0 4.7-2.8 5.7-5.5 6 .4.4.8 1.1.8 2.3v3.4c0 .3.2.7.8.6 4.8-1.6 8.2-6.1 8.2-11.4C24 5.9 18.6.5 12 .5z"/></svg>
|
|
187
|
+
</a>
|
|
188
|
+
<% } %>
|
|
189
|
+
|
|
190
|
+
<% if (config.versions && config.versions.position === 'header') { %>
|
|
191
|
+
<div class="summer-options-menu__item">
|
|
192
|
+
<%- await include('partials/version-dropdown', { versions: config.versions, activeVersion: config._activeVersion, relativePathToRoot, localePrefix: locals.localePrefix, config }) %>
|
|
193
|
+
</div>
|
|
194
|
+
<% } %>
|
|
195
|
+
|
|
196
|
+
<% if (locals.workspace && workspace.switcher.enabled && workspace.switcher.position === 'header') { %>
|
|
197
|
+
<div class="summer-options-menu__item">
|
|
198
|
+
<%- await include('partials/project-switcher', { workspace, config, renderIcon, compact: true }) %>
|
|
199
|
+
</div>
|
|
200
|
+
<% } %>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</header>
|
|
204
|
+
|
|
205
|
+
<%# ─────────────────────────────────────────────────────────────
|
|
206
|
+
BAND 2: Sub-navigation (menubar) — INLINED
|
|
207
|
+
───────────────────────────────────────────────────────────── %>
|
|
208
|
+
<% if (_hasMenubar) { %>
|
|
209
|
+
<nav class="summer-subnav" aria-label="Section navigation">
|
|
210
|
+
<%
|
|
211
|
+
const _mb = (typeof menubarConfig !== 'undefined' ? menubarConfig : (locals.menubarConfig || {}));
|
|
212
|
+
const _mbLeft = Array.isArray(_mb.left) ? _mb.left : [];
|
|
213
|
+
const _mbRight = Array.isArray(_mb.right) ? _mb.right : [];
|
|
214
|
+
|
|
215
|
+
function _isActive(item) {
|
|
216
|
+
if (item.active) return true;
|
|
217
|
+
if (!currentPagePath) return false;
|
|
218
|
+
const iu = (item.url || item.path || '').replace(/^\/+/, '').replace(/^index\.html$/, '').replace(/\/$/, '');
|
|
219
|
+
const cu = (currentPagePath || '').replace(/^\/+/, '').replace(/^index\.html$/, '').replace(/\/$/, '');
|
|
220
|
+
if (!iu) return false;
|
|
221
|
+
return cu === iu || cu.startsWith(iu + '/');
|
|
222
|
+
}
|
|
223
|
+
function _itemHref(item) {
|
|
224
|
+
if (item.url) return buildRelativeUrl(item.url);
|
|
225
|
+
if (item.path) return buildRelativeUrl(item.path);
|
|
226
|
+
return '#';
|
|
227
|
+
}
|
|
228
|
+
%>
|
|
229
|
+
<div class="summer-subnav__inner">
|
|
230
|
+
<% _mbLeft.forEach(item => { %>
|
|
231
|
+
<% if (item.type === 'dropdown') { %>
|
|
232
|
+
<div class="summer-subnav__dropdown" data-summer-dropdown>
|
|
233
|
+
<button type="button" class="summer-subnav__tab" aria-haspopup="true" aria-expanded="false">
|
|
234
|
+
<% if (item.icon) { %><span class="summer-subnav__tab-icon"><%- renderIcon(item.icon) %></span><% } %>
|
|
235
|
+
<span><%= item.text || item.title %></span>
|
|
236
|
+
<span class="summer-subnav__tab-chevron"><%- renderIcon('chevron-down', { class: 'summer-subnav__tab-chev' }) %></span>
|
|
237
|
+
</button>
|
|
238
|
+
<div class="summer-subnav__menu" role="menu">
|
|
239
|
+
<% (item.items || []).forEach(sub => { %>
|
|
240
|
+
<a href="<%= sub.external ? (sub.url || '#') : buildRelativeUrl(sub.url || sub.path || '#') %>" class="summer-subnav__menuitem" role="menuitem" <%= sub.external ? 'target="_blank" rel="noopener noreferrer"' : '' %>>
|
|
241
|
+
<% if (sub.icon) { %><span class="summer-subnav__menuitem-icon"><%- renderIcon(sub.icon) %></span><% } %>
|
|
242
|
+
<span><%= sub.text || sub.title %></span>
|
|
243
|
+
<% if (sub.description) { %><span class="summer-subnav__menuitem-desc"><%= sub.description %></span><% } %>
|
|
244
|
+
</a>
|
|
245
|
+
<% }) %>
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
<% } else { %>
|
|
249
|
+
<% const _active = _isActive(item); const _href = _itemHref(item); const _ext = !!item.external; %>
|
|
250
|
+
<a href="<%= _href %>" class="summer-subnav__tab<%= _active ? ' active' : '' %>" <%= _ext ? 'target="_blank" rel="noopener noreferrer"' : '' %><%= _active ? ' aria-current="page"' : '' %>>
|
|
251
|
+
<% if (item.icon) { %><span class="summer-subnav__tab-icon"><%- renderIcon(item.icon) %></span><% } %>
|
|
252
|
+
<span><%= item.text || item.title || '' %></span>
|
|
253
|
+
<% if (_ext) { %><span class="summer-subnav__tab-chevron">↗</span><% } %>
|
|
254
|
+
</a>
|
|
255
|
+
<% } %>
|
|
256
|
+
<% }) %>
|
|
257
|
+
|
|
258
|
+
<% if (_mbLeft.length && _mbRight.length) { %>
|
|
259
|
+
<div class="summer-subnav__spacer"></div>
|
|
260
|
+
<% } %>
|
|
261
|
+
|
|
262
|
+
<div class="summer-subnav__right">
|
|
263
|
+
<% _mbRight.forEach(item => { %>
|
|
264
|
+
<% if (item.type === 'dropdown') { %>
|
|
265
|
+
<div class="summer-subnav__dropdown" data-summer-dropdown>
|
|
266
|
+
<button type="button" class="summer-subnav__tab" aria-haspopup="true" aria-expanded="false">
|
|
267
|
+
<% if (item.icon) { %><span class="summer-subnav__tab-icon"><%- renderIcon(item.icon) %></span><% } %>
|
|
268
|
+
<span><%= item.text || item.title %></span>
|
|
269
|
+
<span class="summer-subnav__tab-chevron"><%- renderIcon('chevron-down', { class: 'summer-subnav__tab-chev' }) %></span>
|
|
270
|
+
</button>
|
|
271
|
+
<div class="summer-subnav__menu" role="menu">
|
|
272
|
+
<% (item.items || []).forEach(sub => { %>
|
|
273
|
+
<a href="<%= sub.external ? (sub.url || '#') : buildRelativeUrl(sub.url || sub.path || '#') %>" class="summer-subnav__menuitem" role="menuitem" <%= sub.external ? 'target="_blank" rel="noopener noreferrer"' : '' %>>
|
|
274
|
+
<% if (sub.icon) { %><span class="summer-subnav__menuitem-icon"><%- renderIcon(sub.icon) %></span><% } %>
|
|
275
|
+
<span><%= sub.text || sub.title %></span>
|
|
276
|
+
</a>
|
|
277
|
+
<% }) %>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
<% } else { %>
|
|
281
|
+
<% const _active = _isActive(item); const _href = _itemHref(item); const _ext = !!item.external; %>
|
|
282
|
+
<a href="<%= _href %>" class="summer-subnav__tab<%= _active ? ' active' : '' %>" <%= _ext ? 'target="_blank" rel="noopener noreferrer"' : '' %><%= _active ? ' aria-current="page"' : '' %>>
|
|
283
|
+
<% if (item.icon) { %><span class="summer-subnav__tab-icon"><%- renderIcon(item.icon) %></span><% } %>
|
|
284
|
+
<span><%= item.text || item.title || '' %></span>
|
|
285
|
+
<% if (_ext) { %><span class="summer-subnav__tab-chevron">↗</span><% } %>
|
|
286
|
+
</a>
|
|
287
|
+
<% } %>
|
|
288
|
+
<% }) %>
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
</nav>
|
|
292
|
+
<% } %>
|
|
293
|
+
|
|
294
|
+
<%# ─────────────────────────────────────────────────────────────
|
|
295
|
+
BAND 4: Layout grid (sidebar / main / TOC)
|
|
296
|
+
───────────────────────────────────────────────────────────── %>
|
|
297
|
+
<div class="summer-layout">
|
|
298
|
+
|
|
299
|
+
<%# ── Sidebar (left) ── %>
|
|
300
|
+
<% if (!_noSidebar) { %>
|
|
301
|
+
<aside class="summer-sidebar" aria-label="Documentation navigation">
|
|
302
|
+
<button class="summer-sidebar-close summer-iconbtn" type="button" data-summer-sidebar-close aria-label="Close navigation">
|
|
303
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
|
|
304
|
+
</button>
|
|
305
|
+
|
|
306
|
+
<div class="summer-sidebar__top">
|
|
307
|
+
<% if (locals.workspace && workspace.switcher.enabled && workspace.switcher.position === 'sidebar-top') { %>
|
|
308
|
+
<div class="summer-sidebar-widget">
|
|
309
|
+
<%- await include('partials/project-switcher', { workspace, config, renderIcon, compact: false }) %>
|
|
310
|
+
</div>
|
|
311
|
+
<% } %>
|
|
312
|
+
<% if (config.versions && config.versions.position === 'sidebar-top') { %>
|
|
313
|
+
<div class="summer-sidebar-widget">
|
|
314
|
+
<%- await include('partials/version-dropdown', { versions: config.versions, activeVersion: config._activeVersion, relativePathToRoot, localePrefix: locals.localePrefix, config }) %>
|
|
315
|
+
</div>
|
|
316
|
+
<% } %>
|
|
317
|
+
<% if (locals.allLocales && allLocales && allLocales.length > 1 && config.i18n && config.i18n.position === 'sidebar-top') { %>
|
|
318
|
+
<div class="summer-sidebar-widget">
|
|
319
|
+
<%- await include('partials/language-switcher', { allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config, renderIcon, compact: false, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix }) %>
|
|
320
|
+
</div>
|
|
321
|
+
<% } %>
|
|
322
|
+
</div>
|
|
323
|
+
|
|
324
|
+
<%- navigationHtml %>
|
|
325
|
+
|
|
326
|
+
<div class="summer-sidebar__bottom">
|
|
327
|
+
<% if (config.versions && config.versions.position === 'sidebar-bottom') { %>
|
|
328
|
+
<div class="summer-sidebar-widget">
|
|
329
|
+
<%- await include('partials/version-dropdown', { versions: config.versions, activeVersion: config._activeVersion, relativePathToRoot, localePrefix: locals.localePrefix, config }) %>
|
|
330
|
+
</div>
|
|
331
|
+
<% } %>
|
|
332
|
+
<% if (locals.allLocales && allLocales && allLocales.length > 1 && config.i18n && config.i18n.position === 'sidebar-bottom') { %>
|
|
333
|
+
<div class="summer-sidebar-widget">
|
|
334
|
+
<%- await include('partials/language-switcher', { allLocales, activeLocale: locals.activeLocale, defaultLocale: locals.defaultLocale, config, renderIcon, compact: false, currentPagePath: locals.currentPagePath, localePrefix: locals.localePrefix }) %>
|
|
335
|
+
</div>
|
|
336
|
+
<% } %>
|
|
337
|
+
<% if (locals.workspace && workspace.switcher.enabled && workspace.switcher.position === 'sidebar-bottom') { %>
|
|
338
|
+
<div class="summer-sidebar-widget">
|
|
339
|
+
<%- await include('partials/project-switcher', { workspace, config, renderIcon, compact: false }) %>
|
|
340
|
+
</div>
|
|
341
|
+
<% } %>
|
|
342
|
+
<% if (locals.optionsMenu && optionsMenu.position === 'sidebar-bottom') { %>
|
|
343
|
+
<div class="summer-sidebar-widget">
|
|
344
|
+
<%- await include('partials/options-menu', { optionsMenu, config, renderIcon, relativePathToRoot, buildHash }) %>
|
|
345
|
+
</div>
|
|
346
|
+
<% } %>
|
|
347
|
+
</div>
|
|
348
|
+
</aside>
|
|
349
|
+
<% } %>
|
|
350
|
+
|
|
351
|
+
<%# ── Main content (center) ── %>
|
|
352
|
+
<main class="summer-main" id="main-content">
|
|
353
|
+
<% if (headerConfig?.enabled !== false) { %>
|
|
354
|
+
<div class="summer-pageheader">
|
|
355
|
+
<div class="summer-pageheader__inner">
|
|
356
|
+
<%# Breadcrumb + page title row %>
|
|
357
|
+
<div class="summer-pageheader__meta">
|
|
358
|
+
<% if (config.layout?.breadcrumbs !== false && locals.breadcrumbs && breadcrumbs.length > 0) { %>
|
|
359
|
+
<nav aria-label="<%= typeof t === 'function' ? t('breadcrumb') : 'Breadcrumb' %>" class="summer-breadcrumbs">
|
|
360
|
+
<ol class="summer-breadcrumbs__list">
|
|
361
|
+
<% const _bcPrefix = (typeof outputPrefix !== 'undefined' && outputPrefix) ? outputPrefix : ''; %>
|
|
362
|
+
<% breadcrumbs.forEach((crumb, index) => { %>
|
|
363
|
+
<li class="summer-breadcrumbs__item <%= index === breadcrumbs.length - 1 ? 'is-current' : '' %>" <%= index === breadcrumbs.length - 1 ? 'aria-current="page"' : '' %>>
|
|
364
|
+
<% if (crumb.path && index < breadcrumbs.length - 1) { %>
|
|
365
|
+
<a href="<%= relativePathToRoot %><%= _bcPrefix %><%= crumb.path.startsWith('/') ? crumb.path.substring(1) : crumb.path %>" class="summer-breadcrumbs__link"><%= crumb.title %></a>
|
|
366
|
+
<% } else { %>
|
|
367
|
+
<span class="summer-breadcrumbs__current"><%= crumb.title %></span>
|
|
368
|
+
<% } %>
|
|
369
|
+
</li>
|
|
370
|
+
<% }) %>
|
|
371
|
+
</ol>
|
|
372
|
+
</nav>
|
|
373
|
+
<% } %>
|
|
374
|
+
</div>
|
|
375
|
+
|
|
376
|
+
<div class="summer-copy-widgets">
|
|
377
|
+
<% if (config.theme?.copyWidgets?.raw !== false) { %>
|
|
378
|
+
<button class="summer-copy-btn docmd-copy-raw-btn" type="button" data-copied="<%= typeof t === 'function' ? t('copiedToClipboard') : 'Copied!' %>" title="<%= typeof t === 'function' ? t('copyMarkdown') : 'Copy page as Markdown' %>" aria-label="<%= typeof t === 'function' ? t('copyMarkdown') : 'Copy Markdown' %>">
|
|
379
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
|
|
380
|
+
<span><%= typeof t === 'function' ? t('copyMarkdown') : 'Copy page' %></span>
|
|
381
|
+
</button>
|
|
382
|
+
<% } %>
|
|
383
|
+
<% if (config.theme?.copyWidgets?.context !== false) { %>
|
|
384
|
+
<button class="summer-copy-btn docmd-copy-context-btn" type="button" data-copied="<%= typeof t === 'function' ? t('copiedToClipboard') : 'Copied!' %>" title="<%= typeof t === 'function' ? t('copyContext') : 'Copy page + context for AI' %>" aria-label="<%= typeof t === 'function' ? t('copyContext') : 'Copy Context' %>">
|
|
385
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>
|
|
386
|
+
<span><%= typeof t === 'function' ? t('copyContext') : 'Copy context' %></span>
|
|
387
|
+
</button>
|
|
388
|
+
<% } %>
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
</div>
|
|
392
|
+
<% } %>
|
|
393
|
+
|
|
394
|
+
<% if (headerConfig?.enabled === false) { %>
|
|
395
|
+
<h1 class="summer-content__title"><%= pageTitle %></h1>
|
|
396
|
+
<% } %>
|
|
397
|
+
|
|
398
|
+
<div id="docmd-raw-markdown" data-content="<%= encodeURIComponent(typeof rawMarkdown !== 'undefined' ? rawMarkdown : '') %>" style="display: none;"></div>
|
|
399
|
+
|
|
400
|
+
<article class="summer-content">
|
|
401
|
+
<%- content %>
|
|
402
|
+
</article>
|
|
403
|
+
|
|
404
|
+
<% if (config.pageNavigation && (prevPage || nextPage)) { %>
|
|
405
|
+
<nav class="summer-pagenav<%= (!prevPage ? ' no-prev' : '') %><%= (!nextPage ? ' no-next' : '') %>" aria-label="Page navigation">
|
|
406
|
+
<% if (prevPage) { %>
|
|
407
|
+
<a href="<%= prevPage.url %>" class="summer-pagenav__link summer-pagenav__link--prev">
|
|
408
|
+
<svg class="summer-pagenav__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline></svg>
|
|
409
|
+
<span class="summer-pagenav__label">
|
|
410
|
+
<span class="summer-pagenav__small"><%= typeof t === 'function' ? t('previous') : 'Previous' %></span>
|
|
411
|
+
<span class="summer-pagenav__title"><%= prevPage.title %></span>
|
|
412
|
+
</span>
|
|
413
|
+
</a>
|
|
414
|
+
<% } %>
|
|
415
|
+
<% if (nextPage) { %>
|
|
416
|
+
<a href="<%= nextPage.url %>" class="summer-pagenav__link summer-pagenav__link--next">
|
|
417
|
+
<span class="summer-pagenav__label">
|
|
418
|
+
<span class="summer-pagenav__small"><%= typeof t === 'function' ? t('next') : 'Next' %></span>
|
|
419
|
+
<span class="summer-pagenav__title"><%= nextPage.title %></span>
|
|
420
|
+
</span>
|
|
421
|
+
<svg class="summer-pagenav__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline></svg>
|
|
422
|
+
</a>
|
|
423
|
+
<% } %>
|
|
424
|
+
</nav>
|
|
425
|
+
<% } %>
|
|
426
|
+
|
|
427
|
+
<% if (locals.frontmatter?._git?.lastUpdatedTimestamp || locals.editUrl) { %>
|
|
428
|
+
<div class="summer-pagefooter">
|
|
429
|
+
<% if (locals.editUrl) { %>
|
|
430
|
+
<a href="<%= editUrl %>" target="_blank" rel="noopener noreferrer" title="<%= typeof editLinkText !== 'undefined' ? editLinkText : 'Edit this page' %>">
|
|
431
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
|
|
432
|
+
<span><%= typeof editLinkText !== 'undefined' ? editLinkText : 'Edit this page' %></span>
|
|
433
|
+
</a>
|
|
434
|
+
<% } else { %>
|
|
435
|
+
<span></span>
|
|
436
|
+
<% } %>
|
|
437
|
+
<% if (locals.frontmatter?._git?.lastUpdatedTimestamp) { %>
|
|
438
|
+
<span class="summer-pagefooter__time<%= (locals.frontmatter._git.commits && locals.frontmatter._git.commits.length > 0) ? ' has-commits' : '' %>" data-timestamp="<%= locals.frontmatter._git.lastUpdatedTimestamp %>" tabindex="0" aria-haspopup="true" aria-expanded="false">
|
|
439
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline></svg>
|
|
440
|
+
<span><%= typeof t === 'function' ? t('lastUpdated') : 'Last updated' %>: <time datetime="<%= new Date(locals.frontmatter._git.lastUpdatedTimestamp).toISOString() %>"><%= new Date(locals.frontmatter._git.lastUpdatedTimestamp).toLocaleDateString() %></time></span>
|
|
441
|
+
<% if (locals.frontmatter._git.commits && locals.frontmatter._git.commits.length > 0) { %>
|
|
442
|
+
<div class="summer-git-popover" role="tooltip">
|
|
443
|
+
<div class="summer-git-popover__title"><%= typeof t === 'function' ? t('recentCommits') : 'Recent commits' %></div>
|
|
444
|
+
<ul class="summer-git-popover__list">
|
|
445
|
+
<% locals.frontmatter._git.commits.slice(0, 6).forEach(function(commit) { %>
|
|
446
|
+
<li class="summer-git-popover__item">
|
|
447
|
+
<div class="summer-git-popover__avatar" title="<%= commit.author %>">
|
|
448
|
+
<% if (commit.avatarUrl) { %>
|
|
449
|
+
<img src="<%= commit.avatarUrl %>" alt="<%= commit.author %>" loading="lazy">
|
|
450
|
+
<% } else { %>
|
|
451
|
+
<%= commit.author.split(' ').map(function(n){return n[0];}).join('').substring(0, 2).toUpperCase() %>
|
|
452
|
+
<% } %>
|
|
453
|
+
</div>
|
|
454
|
+
<div class="summer-git-popover__details">
|
|
455
|
+
<div class="summer-git-popover__msg" title="<%= commit.message %>"><%= commit.message.length > 60 ? commit.message.substring(0, 57) + '…' : commit.message %></div>
|
|
456
|
+
<div class="summer-git-popover__meta">
|
|
457
|
+
<span class="summer-git-popover__author"><%= commit.author %></span>
|
|
458
|
+
<span class="summer-git-popover__date" data-timestamp="<%= commit.timestamp %>"></span>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
</li>
|
|
462
|
+
<% }); %>
|
|
463
|
+
</ul>
|
|
464
|
+
</div>
|
|
465
|
+
<% } %>
|
|
466
|
+
</span>
|
|
467
|
+
<% } %>
|
|
468
|
+
</div>
|
|
469
|
+
<% } %>
|
|
470
|
+
</main>
|
|
471
|
+
|
|
472
|
+
<%# ── Right-rail TOC (INLINED) ── %>
|
|
473
|
+
<% if (!_noToc) { %>
|
|
474
|
+
<%
|
|
475
|
+
const _tocDisabled = (frontmatter && (frontmatter.toc === false || frontmatter.toc === 'false' || frontmatter.toc === 'hidden'));
|
|
476
|
+
let _tocHeadings = [];
|
|
477
|
+
if (!_tocDisabled) {
|
|
478
|
+
if (typeof headings !== 'undefined' && Array.isArray(headings) && headings.length > 0) {
|
|
479
|
+
_tocHeadings = headings.filter(h => h.level >= 1 && h.level <= 4);
|
|
480
|
+
} else if (typeof content !== 'undefined' && content) {
|
|
481
|
+
const _hr = /<h([1-4])[^>]*?(?:id="([^"]*)")?[^>]*?>([\s\S]*?)<\/h\1>/g;
|
|
482
|
+
const _cs = content.toString();
|
|
483
|
+
for (const _m of _cs.matchAll(_hr)) {
|
|
484
|
+
const _lvl = parseInt(_m[1], 10);
|
|
485
|
+
let _id = _m[2];
|
|
486
|
+
const _txt = String(_m[3]).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, ' ').replace(/<\/?\w+[^>]*>/g, '');
|
|
487
|
+
if (!_id) _id = _txt.toLowerCase().replace(/\s+/g, '-').replace(/[^\w-]/g, '').replace(/--+/g, '-').replace(/^-+|-+$/g, '');
|
|
488
|
+
_tocHeadings.push({ id: _id, level: _lvl, text: _txt });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
%>
|
|
493
|
+
<% if (_tocHeadings.length > 1) { %>
|
|
494
|
+
<div class="summer-toc" aria-label="On this page">
|
|
495
|
+
<aside class="summer-toc__inner">
|
|
496
|
+
<h2 class="summer-toc__title">
|
|
497
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="14" height="14" aria-hidden="true">
|
|
498
|
+
<line x1="21" y1="5" x2="3" y2="5"></line>
|
|
499
|
+
<line x1="15" y1="12" x2="3" y2="12"></line>
|
|
500
|
+
<line x1="17" y1="19" x2="3" y2="19"></line>
|
|
501
|
+
</svg>
|
|
502
|
+
<span><%= typeof t === 'function' ? t('onThisPage') : 'On this page' %></span>
|
|
503
|
+
</h2>
|
|
504
|
+
<ul class="summer-toc__list">
|
|
505
|
+
<% _tocHeadings.forEach((h, idx) => {
|
|
506
|
+
const prevHeading = idx > 0 ? _tocHeadings[idx - 1] : null;
|
|
507
|
+
const prevLevel = prevHeading ? prevHeading.level : h.level;
|
|
508
|
+
%>
|
|
509
|
+
<li class="summer-toc__item summer-toc__item--level-<%= h.level %>" data-prev-level="<%= prevLevel %>" data-level="<%= h.level %>">
|
|
510
|
+
<a href="#<%= h.id %>" class="summer-toc__link" data-toc-level="<%= h.level %>"><%= h.text %></a>
|
|
511
|
+
</li>
|
|
512
|
+
<% }) %>
|
|
513
|
+
</ul>
|
|
514
|
+
</aside>
|
|
515
|
+
</div>
|
|
516
|
+
<% } %>
|
|
517
|
+
<% } %>
|
|
518
|
+
</div>
|
|
519
|
+
|
|
520
|
+
<button class="summer-totop" type="button" aria-label="Scroll to top">
|
|
521
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>
|
|
522
|
+
</button>
|
|
523
|
+
|
|
524
|
+
<%# ─────────────────────────────────────────────────────────────
|
|
525
|
+
BAND 5: Footer — INLINED
|
|
526
|
+
───────────────────────────────────────────────────────────── %>
|
|
527
|
+
<%
|
|
528
|
+
const _fc = (typeof footerConfig !== 'undefined' ? footerConfig : (locals.footerConfig || {}));
|
|
529
|
+
%>
|
|
530
|
+
<% if (_fc?.style === 'complete' && Array.isArray(_fc.columns) && _fc.columns.length) { %>
|
|
531
|
+
<footer class="summer-footer summer-footer--complete">
|
|
532
|
+
<div class="summer-footer__top">
|
|
533
|
+
<div class="summer-footer__brand">
|
|
534
|
+
<div class="summer-footer__brand-logo">
|
|
535
|
+
<% if (logo && (logo.light || logo.dark)) { %>
|
|
536
|
+
<a href="<%= logo.href || relativePathToRoot %>" aria-label="<%= logo.alt || siteTitle %>">
|
|
537
|
+
<% if (logo.light) { %><img src="<%= relativePathToRoot %><%= logo.light.startsWith('/') ? logo.light.substring(1) : logo.light %>" alt="<%= logo.alt || siteTitle %>" class="summer-logo__light"><% } %>
|
|
538
|
+
<% if (logo.dark) { %><img src="<%= relativePathToRoot %><%= logo.dark.startsWith('/') ? logo.dark.substring(1) : logo.dark %>" alt="<%= logo.alt || siteTitle %>" class="summer-logo__dark"><% } %>
|
|
539
|
+
</a>
|
|
540
|
+
<% } else { %>
|
|
541
|
+
<span class="summer-logo summer-logo--text"><span class="summer-logo__icon"><%= (siteTitle || 'D').charAt(0).toUpperCase() %></span><span><%= siteTitle %></span></span>
|
|
542
|
+
<% } %>
|
|
543
|
+
</div>
|
|
544
|
+
<% if (_fc.description) { %>
|
|
545
|
+
<p class="summer-footer__desc"><%= _fc.description %></p>
|
|
546
|
+
<% } %>
|
|
547
|
+
</div>
|
|
548
|
+
<% _fc.columns.forEach(col => { %>
|
|
549
|
+
<div class="summer-footer__col">
|
|
550
|
+
<h4 class="summer-footer__col-title"><%= col.title %></h4>
|
|
551
|
+
<ul>
|
|
552
|
+
<% (col.links || []).forEach(link => { %>
|
|
553
|
+
<li><a href="<%= link.external ? (link.url || '#') : buildRelativeUrl(link.url || '#') %>" <%= link.external ? 'target="_blank" rel="noopener noreferrer"' : '' %>><%= link.text %></a></li>
|
|
554
|
+
<% }) %>
|
|
555
|
+
</ul>
|
|
556
|
+
</div>
|
|
557
|
+
<% }) %>
|
|
558
|
+
</div>
|
|
559
|
+
<div class="summer-footer__inner">
|
|
560
|
+
<div class="summer-footer__user"><%- footerHtml || (_fc.copyright ? _fc.copyright : '') %></div>
|
|
561
|
+
<% if (_fc.branding !== false) { %>
|
|
562
|
+
<div class="summer-footer__branding">
|
|
563
|
+
<span><%= typeof t === 'function' ? t('builtWith') : 'Built with' %></span>
|
|
564
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"></path></svg>
|
|
565
|
+
<a href="https://docmd.io" target="_blank" rel="noopener">docmd</a>
|
|
566
|
+
<% if (_sponsorUrl && (_sponsorPos === 'footer' || _sponsorPos === 'both')) { %>
|
|
567
|
+
<span class="summer-footer__sep" aria-hidden="true">·</span>
|
|
568
|
+
<a href="<%= _sponsorUrl %>" target="_blank" rel="noopener" class="summer-footer__sponsor">
|
|
569
|
+
<svg viewBox="0 0 24 24" fill="currentColor" stroke="none" width="14" height="14" aria-hidden="true"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
|
|
570
|
+
<span>Sponsor</span>
|
|
571
|
+
</a>
|
|
572
|
+
<% } %>
|
|
573
|
+
</div>
|
|
574
|
+
<% } %>
|
|
575
|
+
</div>
|
|
576
|
+
</footer>
|
|
577
|
+
<% } else { %>
|
|
578
|
+
<footer class="summer-footer">
|
|
579
|
+
<div class="summer-footer__inner">
|
|
580
|
+
<div class="summer-footer__user"><%- footerHtml || (_fc?.copyright ? _fc.copyright : '') %></div>
|
|
581
|
+
<% if (_fc?.branding !== false) { %>
|
|
582
|
+
<div class="summer-footer__branding">
|
|
583
|
+
<span><%= typeof t === 'function' ? t('builtWith') : 'Built with' %></span>
|
|
584
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z"></path></svg>
|
|
585
|
+
<a href="https://docmd.io" target="_blank" rel="noopener">docmd</a>
|
|
586
|
+
<% if (_sponsorUrl && (_sponsorPos === 'footer' || _sponsorPos === 'both')) { %>
|
|
587
|
+
<span class="summer-footer__sep" aria-hidden="true">·</span>
|
|
588
|
+
<a href="<%= _sponsorUrl %>" target="_blank" rel="noopener" class="summer-footer__sponsor">
|
|
589
|
+
<svg viewBox="0 0 24 24" fill="currentColor" stroke="none" width="14" height="14" aria-hidden="true"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
|
|
590
|
+
<span>Sponsor</span>
|
|
591
|
+
</a>
|
|
592
|
+
<% } %>
|
|
593
|
+
</div>
|
|
594
|
+
<% } %>
|
|
595
|
+
</div>
|
|
596
|
+
</footer>
|
|
597
|
+
<% } %>
|
|
598
|
+
|
|
599
|
+
<% if (locals.allLocales && allLocales && allLocales.length > 1) { %>
|
|
600
|
+
<script src="<%= relativePathToRoot %>assets/js/docmd-i18n-manifest.js?v=<%= buildHash %>"></script>
|
|
601
|
+
<% } %>
|
|
602
|
+
<script src="<%= relativePathToRoot %>assets/js/docmd-main.js?v=<%= buildHash %>"></script>
|
|
603
|
+
|
|
604
|
+
<%- pluginBodyScriptsHtml || '' %>
|
|
605
|
+
<% (customJsFiles || []).forEach(jsFile => { if (jsFile && jsFile.trim() !== '') { %>
|
|
606
|
+
<script src="<%= relativePathToRoot %><%= jsFile.startsWith('/') ? jsFile.substring(1) : jsFile %>?v=<%= buildHash %>"></script>
|
|
607
|
+
<% } }); %>
|
|
608
|
+
</body>
|
|
609
|
+
</html>
|