@apleasantview/eleventy-plugin-baseline 0.1.0-next.22 → 0.1.0-next.28
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/README.md +3 -1
- package/core/debug.js +5 -5
- package/core/filters/isString.js +1 -1
- package/core/filters/markdown.js +3 -5
- package/core/filters/related-posts.js +4 -5
- package/core/filters.js +4 -4
- package/core/globals/date.js +4 -4
- package/core/globals.js +1 -1
- package/core/helpers.js +21 -33
- package/core/modules.js +8 -8
- package/core/shortcodes/image.js +30 -39
- package/core/shortcodes.js +1 -1
- package/eleventy.config.js +71 -38
- package/modules/assets-core/plugins/assets-core.js +12 -12
- package/modules/assets-esbuild/filters/inline-esbuild.js +3 -3
- package/modules/assets-esbuild/plugins/assets-esbuild.js +22 -25
- package/modules/assets-postcss/fallback/postcss.config.js +9 -11
- package/modules/assets-postcss/filters/inline-postcss.js +7 -7
- package/modules/assets-postcss/plugins/assets-postcss.js +19 -19
- package/modules/head-core/drivers/posthtml-head-elements.js +106 -122
- package/modules/head-core/plugins/head-core.js +14 -17
- package/modules/head-core/utils/head-utils.js +57 -67
- package/modules/multilang-core/filters/i18n-default-translation.js +14 -0
- package/modules/multilang-core/filters/i18n-translation-in.js +16 -0
- package/modules/multilang-core/filters/i18n-translations-for.js +10 -0
- package/modules/multilang-core/plugins/multilang-core.js +78 -12
- package/modules/navigator-core/plugins/navigator-core.js +16 -14
- package/modules/navigator-core/templates/navigator-core.html +33 -17
- package/modules/sitemap-core/plugins/sitemap-core.js +21 -21
- package/modules/sitemap-core/templates/sitemap-core.html +4 -4
- package/package.json +1 -1
|
@@ -1,23 +1,22 @@
|
|
|
1
|
-
import Merge from
|
|
2
|
-
import { TemplatePath } from
|
|
1
|
+
import Merge from '@11ty/eleventy-utils/src/Merge.js';
|
|
2
|
+
import { TemplatePath } from '@11ty/eleventy-utils';
|
|
3
3
|
|
|
4
4
|
const pick = (...values) => values.find((v) => v !== undefined && v !== null);
|
|
5
5
|
|
|
6
|
-
const normalizePathPrefix = (pathPrefix =
|
|
6
|
+
const normalizePathPrefix = (pathPrefix = '') => {
|
|
7
7
|
// Align with Eleventy’s normalizeUrlPath behavior
|
|
8
|
-
const normalized = TemplatePath.normalizeUrlPath(
|
|
9
|
-
return normalized ===
|
|
8
|
+
const normalized = TemplatePath.normalizeUrlPath('/', pathPrefix);
|
|
9
|
+
return normalized === '/' ? '' : normalized; // empty means root
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
const isAbsoluteUrl = (url =
|
|
13
|
-
/^[a-z][a-z\d+\-.]*:\/\//i.test(url) || url.startsWith("//");
|
|
12
|
+
const isAbsoluteUrl = (url = '') => /^[a-z][a-z\d+\-.]*:\/\//i.test(url) || url.startsWith('//');
|
|
14
13
|
|
|
15
14
|
const absoluteUrl = (siteUrl, pathPrefix, url) => {
|
|
16
15
|
if (!url) return url;
|
|
17
16
|
if (isAbsoluteUrl(url)) return url;
|
|
18
17
|
const prefix = normalizePathPrefix(pathPrefix);
|
|
19
|
-
const joined = TemplatePath.normalizeUrlPath(prefix ||
|
|
20
|
-
return siteUrl ? `${siteUrl.replace(/\/+$/,
|
|
18
|
+
const joined = TemplatePath.normalizeUrlPath(prefix || '/', url);
|
|
19
|
+
return siteUrl ? `${siteUrl.replace(/\/+$/, '')}${joined}` : joined;
|
|
21
20
|
};
|
|
22
21
|
|
|
23
22
|
const mergeBaseHead = (site, user, page, title, description, noindex, url) => {
|
|
@@ -26,47 +25,52 @@ const mergeBaseHead = (site, user, page, title, description, noindex, url) => {
|
|
|
26
25
|
{
|
|
27
26
|
title,
|
|
28
27
|
meta: [
|
|
29
|
-
{ charset:
|
|
30
|
-
{ name:
|
|
31
|
-
{ name:
|
|
32
|
-
{ name:
|
|
28
|
+
{ charset: 'UTF-8' },
|
|
29
|
+
{ name: 'viewport', content: 'width=device-width, initial-scale=1.0' },
|
|
30
|
+
{ name: 'description', content: description },
|
|
31
|
+
{ name: 'robots', content: noindex ? 'noindex, nofollow' : 'index, follow' }
|
|
33
32
|
],
|
|
34
33
|
link: [],
|
|
35
34
|
script: [],
|
|
36
35
|
style: [],
|
|
37
36
|
hreflang: [],
|
|
38
37
|
openGraph: {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
'og:title': title,
|
|
39
|
+
'og:description': description,
|
|
40
|
+
'og:type': 'website',
|
|
41
|
+
'og:url': url || '',
|
|
42
|
+
'og:image': ''
|
|
44
43
|
},
|
|
45
44
|
twitter: {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
'twitter:card': 'summary_large_image',
|
|
46
|
+
'twitter:title': title,
|
|
47
|
+
'twitter:description': description,
|
|
48
|
+
'twitter:image': ''
|
|
50
49
|
},
|
|
51
50
|
miscMeta: [],
|
|
52
|
-
structuredData: null
|
|
51
|
+
structuredData: null
|
|
53
52
|
},
|
|
54
53
|
user
|
|
55
54
|
);
|
|
56
55
|
};
|
|
57
56
|
|
|
58
57
|
const resolveCanonical = (head, page, contentMap, env = {}) => {
|
|
59
|
-
const { siteUrl, pathPrefix =
|
|
58
|
+
const { siteUrl, pathPrefix = '', pageUrlOverride, verbose } = env;
|
|
60
59
|
const explicit = pick(head.canonical);
|
|
61
|
-
if (explicit)
|
|
60
|
+
if (explicit) {
|
|
61
|
+
if (!siteUrl && verbose) {
|
|
62
|
+
console.warn('[baseline] site.url is missing; canonical will be relative.');
|
|
63
|
+
}
|
|
64
|
+
return absoluteUrl(siteUrl, pathPrefix, explicit);
|
|
65
|
+
}
|
|
62
66
|
|
|
63
|
-
const url = pick(
|
|
64
|
-
pageUrlOverride,
|
|
65
|
-
page?.url,
|
|
66
|
-
page?.inputPath && contentMap?.inputPathToUrl?.[page.inputPath]?.[0]
|
|
67
|
-
);
|
|
67
|
+
const url = pick(pageUrlOverride, page?.url, page?.inputPath && contentMap?.inputPathToUrl?.[page.inputPath]?.[0]);
|
|
68
68
|
if (!url) return undefined;
|
|
69
69
|
|
|
70
|
+
if (!siteUrl && verbose) {
|
|
71
|
+
console.warn('[baseline] site.url is missing; canonical will be relative.');
|
|
72
|
+
}
|
|
73
|
+
|
|
70
74
|
return absoluteUrl(siteUrl, pathPrefix, url);
|
|
71
75
|
};
|
|
72
76
|
|
|
@@ -75,16 +79,15 @@ const dedupeMeta = (arr = []) => {
|
|
|
75
79
|
const out = [];
|
|
76
80
|
for (let i = arr.length - 1; i >= 0; i--) {
|
|
77
81
|
const m = arr[i];
|
|
78
|
-
const key =
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
: m.name
|
|
82
|
+
const key = m.charset
|
|
83
|
+
? 'charset'
|
|
84
|
+
: m.name
|
|
82
85
|
? `name:${m.name}`
|
|
83
86
|
: m.property
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
? `prop:${m.property}`
|
|
88
|
+
: m['http-equiv']
|
|
89
|
+
? `http:${m['http-equiv']}`
|
|
90
|
+
: null;
|
|
88
91
|
if (!key || seen.has(key)) continue;
|
|
89
92
|
seen.add(key);
|
|
90
93
|
out.push(m);
|
|
@@ -119,61 +122,55 @@ const flattenHead = (head = {}, canonical) => {
|
|
|
119
122
|
? Object.entries(head.twitter)
|
|
120
123
|
.filter(([, v]) => v)
|
|
121
124
|
.map(([k, v]) => ({ name: k, content: v }))
|
|
122
|
-
: [])
|
|
125
|
+
: [])
|
|
123
126
|
]);
|
|
124
127
|
|
|
125
128
|
const style = [...(head.style || [])];
|
|
126
129
|
|
|
127
|
-
const linkCanonical = canonical ? [{ rel:
|
|
130
|
+
const linkCanonical = canonical ? [{ rel: 'canonical', href: canonical }] : [];
|
|
128
131
|
const link = dedupeLink([...(head.link || []), ...(head.hreflang || [])].filter(Boolean));
|
|
129
132
|
|
|
130
133
|
const script = [...(head.script || [])];
|
|
131
134
|
if (head.structuredData) {
|
|
132
135
|
script.unshift({
|
|
133
|
-
type:
|
|
134
|
-
content: JSON.stringify(head.structuredData)
|
|
136
|
+
type: 'application/ld+json',
|
|
137
|
+
content: JSON.stringify(head.structuredData)
|
|
135
138
|
});
|
|
136
139
|
}
|
|
137
140
|
|
|
138
141
|
// Key order matters for posthtml-head-elements.
|
|
139
142
|
return {
|
|
140
143
|
meta: baseMeta,
|
|
141
|
-
title: head.title ||
|
|
144
|
+
title: head.title || '',
|
|
142
145
|
linkCanonical,
|
|
143
146
|
style,
|
|
144
147
|
link,
|
|
145
148
|
script,
|
|
146
|
-
meta_social: socialMeta
|
|
149
|
+
meta_social: socialMeta
|
|
147
150
|
};
|
|
148
151
|
};
|
|
149
152
|
|
|
150
153
|
const buildHead = (data = {}, env = {}) => {
|
|
151
|
-
const { userKey =
|
|
154
|
+
const { userKey = 'head', contentMap = {}, siteUrl, pathPrefix } = env;
|
|
152
155
|
const site = data.site || {};
|
|
153
156
|
const user = userKey ? data[userKey] || {} : {};
|
|
154
157
|
const page = data.page || {};
|
|
155
158
|
const resolvedSiteUrl =
|
|
156
|
-
siteUrl ||
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
process.env.DEPLOY_PRIME_URL;
|
|
161
|
-
|
|
162
|
-
const siteTitle = site.title || "";
|
|
163
|
-
const pageTitle = pick(data.title, user.title, site.title, "");
|
|
159
|
+
siteUrl || site.url || process.env.URL || process.env.DEPLOY_URL || process.env.DEPLOY_PRIME_URL;
|
|
160
|
+
|
|
161
|
+
const siteTitle = site.title || '';
|
|
162
|
+
const pageTitle = pick(data.title, user.title, site.title, '');
|
|
164
163
|
const title =
|
|
165
|
-
siteTitle && pageTitle && siteTitle !== pageTitle
|
|
166
|
-
? `${pageTitle} | ${siteTitle}`
|
|
167
|
-
: pageTitle || siteTitle || "";
|
|
164
|
+
siteTitle && pageTitle && siteTitle !== pageTitle ? `${pageTitle} | ${siteTitle}` : pageTitle || siteTitle || '';
|
|
168
165
|
|
|
169
|
-
const description = pick(data.description, user.description, site.tagline,
|
|
170
|
-
const noindex = pick(page.noindex, user.noindex, site.noindex, false);
|
|
166
|
+
const description = pick(data.description, user.description, site.tagline, '');
|
|
167
|
+
const noindex = pick(data.noindex, page.noindex, user.noindex, site.noindex, false);
|
|
171
168
|
|
|
172
169
|
const canonical = resolveCanonical(
|
|
173
170
|
{ canonical: absoluteUrl(resolvedSiteUrl, pathPrefix, user.canonical) },
|
|
174
171
|
page,
|
|
175
172
|
contentMap,
|
|
176
|
-
{ ...env, siteUrl: resolvedSiteUrl }
|
|
173
|
+
{ ...env, siteUrl: resolvedSiteUrl, verbose: env.verbose }
|
|
177
174
|
);
|
|
178
175
|
const merged = mergeBaseHead(site, user, page, title, description, noindex, canonical);
|
|
179
176
|
return flattenHead(merged, canonical);
|
|
@@ -183,11 +180,4 @@ const buildHeadSpec = (context, contentMap, env = {}) => {
|
|
|
183
180
|
return buildHead(context, { ...env, contentMap });
|
|
184
181
|
};
|
|
185
182
|
|
|
186
|
-
export {
|
|
187
|
-
pick,
|
|
188
|
-
resolveCanonical,
|
|
189
|
-
flattenHead,
|
|
190
|
-
buildHead,
|
|
191
|
-
buildHeadSpec,
|
|
192
|
-
absoluteUrl,
|
|
193
|
-
};
|
|
183
|
+
export { pick, resolveCanonical, flattenHead, buildHead, buildHeadSpec, absoluteUrl };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the default-language variant for the current page.
|
|
3
|
+
* @param {object} page
|
|
4
|
+
* @param {Array<object>} collection
|
|
5
|
+
* @returns {object|null}
|
|
6
|
+
*/
|
|
7
|
+
export default function i18nDefaultTranslation(page, collection) {
|
|
8
|
+
if (!page?.locale?.translationKey) return null;
|
|
9
|
+
return (
|
|
10
|
+
collection.find(
|
|
11
|
+
(p) => p.locale && p.locale.translationKey === page.locale.translationKey && p.locale.isDefaultLang
|
|
12
|
+
) || null
|
|
13
|
+
);
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get a specific language variant for the current page.
|
|
3
|
+
* @param {object} page
|
|
4
|
+
* @param {Array<object>} collection
|
|
5
|
+
* @param {string} lang
|
|
6
|
+
* @returns {object|null}
|
|
7
|
+
*/
|
|
8
|
+
export default function i18nTranslationIn(page, collection, lang) {
|
|
9
|
+
if (!page?.locale?.translationKey) return null;
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
collection.find(
|
|
13
|
+
(p) => p.locale && p.locale.translationKey === page.locale.translationKey && p.locale.lang === lang
|
|
14
|
+
) || null
|
|
15
|
+
);
|
|
16
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get all translations for the current page.
|
|
3
|
+
* @param {object} page
|
|
4
|
+
* @param {Array<object>} collection
|
|
5
|
+
* @returns {Array<object>}
|
|
6
|
+
*/
|
|
7
|
+
export default function i18nTranslationsFor(page, collection) {
|
|
8
|
+
if (!page?.locale?.translationKey) return [];
|
|
9
|
+
return collection.filter((p) => p.locale && p.locale.translationKey === page.locale.translationKey);
|
|
10
|
+
}
|
|
@@ -1,35 +1,101 @@
|
|
|
1
|
-
import { I18nPlugin } from
|
|
1
|
+
import { I18nPlugin } from '@11ty/eleventy';
|
|
2
|
+
import { DeepCopy } from '@11ty/eleventy-utils';
|
|
3
|
+
import i18nTranslationsFor from '../filters/i18n-translations-for.js';
|
|
4
|
+
import i18nTranslationIn from '../filters/i18n-translation-in.js';
|
|
5
|
+
import i18nDefaultTranslation from '../filters/i18n-default-translation.js';
|
|
2
6
|
|
|
3
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Baseline – multilang-core
|
|
9
|
+
*
|
|
10
|
+
* Responsibilities:
|
|
11
|
+
* - Normalize language metadata
|
|
12
|
+
* - Annotate translatable pages
|
|
13
|
+
* - Expose relational helpers for translations
|
|
14
|
+
*
|
|
15
|
+
* @param { import("@11ty/eleventy/src/UserConfig.js").default } eleventyConfig
|
|
16
|
+
*/
|
|
4
17
|
export default function multilangCore(eleventyConfig, options = {}) {
|
|
5
18
|
const userOptions = {
|
|
6
|
-
defaultLanguage:
|
|
19
|
+
defaultLanguage: 'en',
|
|
7
20
|
languages: [],
|
|
21
|
+
verbose: false,
|
|
8
22
|
...options
|
|
9
|
-
}
|
|
23
|
+
};
|
|
10
24
|
|
|
11
25
|
eleventyConfig.addPlugin(I18nPlugin, {
|
|
12
26
|
defaultLanguage: userOptions.defaultLanguage,
|
|
13
|
-
errorMode:
|
|
27
|
+
errorMode: 'allow-fallback'
|
|
14
28
|
});
|
|
15
29
|
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
30
|
+
// Normalize allowed languages (optionally lower/trim)
|
|
31
|
+
const normalizeLang = (lang) => (lang || '').toLowerCase().trim();
|
|
32
|
+
const allowedLanguages = new Set(
|
|
33
|
+
Array.isArray(userOptions.languages)
|
|
34
|
+
? userOptions.languages.map(normalizeLang)
|
|
35
|
+
: Object.keys(userOptions.languages || {}).map(normalizeLang)
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
eleventyConfig.addGlobalData('eleventyComputed.page.locale', () => {
|
|
39
|
+
return (data) => {
|
|
40
|
+
const lang = normalizeLang(data.lang || data.language || userOptions.defaultLanguage);
|
|
41
|
+
const translationKey = data.translationKey;
|
|
42
|
+
const isDefaultLang = lang === normalizeLang(userOptions.defaultLanguage);
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
translationKey,
|
|
46
|
+
lang,
|
|
47
|
+
isDefaultLang
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const buildTranslations = (collection) => {
|
|
53
|
+
const map = {};
|
|
54
|
+
const list = [];
|
|
55
|
+
|
|
19
56
|
for (const page of collection.getAll()) {
|
|
20
57
|
const translationKey = page.data.translationKey;
|
|
21
58
|
if (!translationKey) continue;
|
|
59
|
+
|
|
22
60
|
const lang = page.data.lang || page.data.language || userOptions.defaultLanguage;
|
|
23
61
|
if (!lang) continue;
|
|
24
|
-
|
|
25
|
-
|
|
62
|
+
|
|
63
|
+
if (allowedLanguages.size && !allowedLanguages.has(lang)) {
|
|
64
|
+
if (userOptions.verbose) {
|
|
65
|
+
console.warn(`[baseline:multilang-core] Unknown lang "${lang}" in ${page.inputPath}`);
|
|
66
|
+
}
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const locale = { locale: { translationKey, lang, isDefaultLang: lang === userOptions.defaultLanguage } };
|
|
71
|
+
const safeCopy = DeepCopy(page, locale);
|
|
72
|
+
list.push(safeCopy);
|
|
73
|
+
|
|
74
|
+
if (!map[translationKey]) map[translationKey] = {};
|
|
75
|
+
map[translationKey][lang] = {
|
|
26
76
|
title: page.data.title,
|
|
27
77
|
url: page.url,
|
|
28
78
|
lang,
|
|
29
|
-
|
|
79
|
+
isDefaultLang: lang === userOptions.defaultLanguage,
|
|
30
80
|
data: page.data
|
|
31
81
|
};
|
|
32
82
|
}
|
|
33
|
-
|
|
83
|
+
|
|
84
|
+
return { map, list };
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// Map form for direct lookups
|
|
88
|
+
eleventyConfig.addCollection('translationsMap', (collection) => {
|
|
89
|
+
return buildTranslations(collection).map;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Canonical translations collection
|
|
93
|
+
eleventyConfig.addCollection('translations', (collection) => {
|
|
94
|
+
return buildTranslations(collection).list;
|
|
34
95
|
});
|
|
96
|
+
|
|
97
|
+
// Filters – relational helpers
|
|
98
|
+
eleventyConfig.addFilter('i18nTranslationsFor', i18nTranslationsFor);
|
|
99
|
+
eleventyConfig.addFilter('i18nTranslationIn', i18nTranslationIn);
|
|
100
|
+
eleventyConfig.addFilter('i18nDefaultTranslation', i18nDefaultTranslation);
|
|
35
101
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import path from
|
|
3
|
-
import { fileURLToPath } from
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
4
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
@@ -8,9 +8,7 @@ const __dirname = path.dirname(__filename);
|
|
|
8
8
|
/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */
|
|
9
9
|
export default function navigatorCore(eleventyConfig, options = {}) {
|
|
10
10
|
const raw = options.enableNavigatorTemplate;
|
|
11
|
-
const [enableNavigatorTemplate, inspectorDepth] = Array.isArray(raw)
|
|
12
|
-
? [raw[0], raw[1]]
|
|
13
|
-
: [raw, undefined];
|
|
11
|
+
const [enableNavigatorTemplate, inspectorDepth] = Array.isArray(raw) ? [raw[0], raw[1]] : [raw, undefined];
|
|
14
12
|
|
|
15
13
|
const userOptions = {
|
|
16
14
|
...options,
|
|
@@ -18,17 +16,21 @@ export default function navigatorCore(eleventyConfig, options = {}) {
|
|
|
18
16
|
inspectorDepth: inspectorDepth ?? 2
|
|
19
17
|
};
|
|
20
18
|
|
|
21
|
-
eleventyConfig.addNunjucksGlobal(
|
|
22
|
-
|
|
19
|
+
eleventyConfig.addNunjucksGlobal('_navigator', function () {
|
|
20
|
+
return this;
|
|
21
|
+
});
|
|
22
|
+
eleventyConfig.addNunjucksGlobal('_context', function () {
|
|
23
|
+
return this.ctx;
|
|
24
|
+
});
|
|
23
25
|
|
|
24
26
|
if (userOptions.enableNavigatorTemplate) {
|
|
25
27
|
// Read virtual template synchronously; Nunjucks pipeline here is sync-only.
|
|
26
|
-
const templatePath = path.join(__dirname,
|
|
27
|
-
const virtualTemplateContent = fs.readFileSync(templatePath,
|
|
28
|
-
eleventyConfig.addTemplate(
|
|
29
|
-
permalink:
|
|
30
|
-
title:
|
|
31
|
-
description:
|
|
28
|
+
const templatePath = path.join(__dirname, '../templates/navigator-core.html');
|
|
29
|
+
const virtualTemplateContent = fs.readFileSync(templatePath, 'utf-8');
|
|
30
|
+
eleventyConfig.addTemplate('navigator-core.html', virtualTemplateContent, {
|
|
31
|
+
permalink: '/navigator-core.html',
|
|
32
|
+
title: 'Navigator Core',
|
|
33
|
+
description: '',
|
|
32
34
|
layout: null,
|
|
33
35
|
eleventyExcludeFromCollections: true,
|
|
34
36
|
inspectorDepth: userOptions.inspectorDepth
|
|
@@ -4,10 +4,22 @@ permalink: /navigator-core.html
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<!DOCTYPE html>
|
|
7
|
-
<html lang="{{ site.defaultLanguage }}">
|
|
7
|
+
<html lang="{{ lang | default(site.defaultLanguage) }}">
|
|
8
8
|
|
|
9
9
|
<head>
|
|
10
10
|
<baseline-head></baseline-head>
|
|
11
|
+
<style>
|
|
12
|
+
._navigator__wrapper:not(#\#):not(#\#) {
|
|
13
|
+
box-sizing: content-box;
|
|
14
|
+
max-width: 60rem;
|
|
15
|
+
padding-inline: clamp(1rem, 0.2083rem + 3.5185vw, 3.375rem);
|
|
16
|
+
margin-inline: auto;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
._navigator__wrapper:not(#\#):not(#\#) > * + * {
|
|
20
|
+
margin-block-start: 1.25rem;
|
|
21
|
+
}
|
|
22
|
+
</style>
|
|
11
23
|
</head>
|
|
12
24
|
|
|
13
25
|
<body>
|
|
@@ -15,24 +27,28 @@ permalink: /navigator-core.html
|
|
|
15
27
|
Skip to main content
|
|
16
28
|
</a>
|
|
17
29
|
<header>
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
<
|
|
30
|
+
<div class="_navigator__wrapper">
|
|
31
|
+
<h1>{{ site.title }} Navigator</h1>
|
|
32
|
+
<div>
|
|
33
|
+
<p>{{ site.tagline }}</p>
|
|
34
|
+
</div>
|
|
21
35
|
</div>
|
|
22
36
|
</header>
|
|
23
37
|
<main id="main" tabindex="-1">
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
<div class="_navigator__wrapper">
|
|
39
|
+
<p><a id="go-back" href=""><span style="vertical-align: text-bottom;">←</span> Go back</a></p>
|
|
40
|
+
<h2><u>Navigator</u></h2>
|
|
41
|
+
{% for key, value in _navigator() %}
|
|
42
|
+
<details>
|
|
43
|
+
<summary><strong>{{ key }}</strong></summary>
|
|
44
|
+
{% if value | isString %}
|
|
45
|
+
<pre>{{ value | safe }}</pre>
|
|
46
|
+
{% else %}
|
|
47
|
+
<pre>{{ value | _inspect({ depth: inspectorDepth }) }}</pre>
|
|
48
|
+
{% endif %}
|
|
49
|
+
</details>
|
|
50
|
+
{% endfor %}
|
|
51
|
+
</div>
|
|
36
52
|
</main>
|
|
37
53
|
<script>
|
|
38
54
|
document.getElementById("go-back").addEventListener("click", (event) => {
|
|
@@ -42,7 +58,7 @@ permalink: /navigator-core.html
|
|
|
42
58
|
</script>
|
|
43
59
|
</body>
|
|
44
60
|
<footer>
|
|
45
|
-
<small>Navigator Core — Eleventy Plugin Baseline</small>
|
|
61
|
+
<div class="_navigator__wrapper"><small>Navigator Core — Eleventy Plugin Baseline</small></div>
|
|
46
62
|
</footer>
|
|
47
63
|
|
|
48
64
|
</html>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
import path from
|
|
3
|
-
import { fileURLToPath } from
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
4
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
@@ -13,30 +13,30 @@ export default function sitemapCore(eleventyConfig, options = {}) {
|
|
|
13
13
|
languages: options.languages
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
eleventyConfig.addGlobalData(
|
|
16
|
+
eleventyConfig.addGlobalData('eleventyComputed.page.sitemap', () => {
|
|
17
17
|
return (data) => ({
|
|
18
|
-
ignore: data.site?.noindex ?? false,
|
|
19
|
-
changefreq:
|
|
18
|
+
ignore: data.noindex ?? data.page?.noindex ?? data.site?.noindex ?? false,
|
|
19
|
+
changefreq: '',
|
|
20
20
|
priority: -1
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
if (userOptions.enableSitemapTemplate) {
|
|
25
|
-
const templatePath = path.join(__dirname,
|
|
26
|
-
const indexTemplatePath = path.join(__dirname,
|
|
27
|
-
const baseContent = fs.readFileSync(templatePath,
|
|
28
|
-
const indexContent = fs.readFileSync(indexTemplatePath,
|
|
25
|
+
const templatePath = path.join(__dirname, '../templates/sitemap-core.html');
|
|
26
|
+
const indexTemplatePath = path.join(__dirname, '../templates/sitemap-index.html');
|
|
27
|
+
const baseContent = fs.readFileSync(templatePath, 'utf-8');
|
|
28
|
+
const indexContent = fs.readFileSync(indexTemplatePath, 'utf-8');
|
|
29
29
|
|
|
30
30
|
const languages = userOptions.languages || {};
|
|
31
31
|
const langKeys = Array.isArray(languages) ? languages : Object.keys(languages);
|
|
32
|
-
const multilingual = typeof userOptions.multilingual ===
|
|
32
|
+
const multilingual = typeof userOptions.multilingual === 'boolean' ? userOptions.multilingual : langKeys.length > 1;
|
|
33
33
|
|
|
34
34
|
if (multilingual && langKeys.length > 1) {
|
|
35
35
|
for (const lang of langKeys) {
|
|
36
36
|
eleventyConfig.addTemplate(`_baseline/sitemap-core-${lang}.html`, baseContent, {
|
|
37
37
|
permalink: `${lang}/sitemap.xml`,
|
|
38
|
-
title:
|
|
39
|
-
description:
|
|
38
|
+
title: '',
|
|
39
|
+
description: '',
|
|
40
40
|
layout: null,
|
|
41
41
|
eleventyExcludeFromCollections: true,
|
|
42
42
|
isMultilingual: multilingual,
|
|
@@ -44,19 +44,19 @@ export default function sitemapCore(eleventyConfig, options = {}) {
|
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
eleventyConfig.addTemplate(
|
|
48
|
-
permalink:
|
|
49
|
-
title:
|
|
50
|
-
description:
|
|
47
|
+
eleventyConfig.addTemplate('_baseline/sitemap-index.html', indexContent, {
|
|
48
|
+
permalink: '/sitemap.xml',
|
|
49
|
+
title: '',
|
|
50
|
+
description: '',
|
|
51
51
|
layout: null,
|
|
52
52
|
eleventyExcludeFromCollections: true,
|
|
53
53
|
isMultilingual: multilingual
|
|
54
54
|
});
|
|
55
55
|
} else {
|
|
56
|
-
eleventyConfig.addTemplate(
|
|
57
|
-
permalink:
|
|
58
|
-
title:
|
|
59
|
-
description:
|
|
56
|
+
eleventyConfig.addTemplate('_baseline/sitemap-core.html', baseContent, {
|
|
57
|
+
permalink: '/sitemap.xml',
|
|
58
|
+
title: '',
|
|
59
|
+
description: '',
|
|
60
60
|
layout: null,
|
|
61
61
|
eleventyExcludeFromCollections: true
|
|
62
62
|
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
|
3
3
|
{%- if not site.noindex -%}
|
|
4
4
|
{%- for item in collections.all -%}
|
|
5
|
-
{%- if not item.data.eleventyExcludeFromCollections and (not item.data.sitemap or item.data.sitemap.ignore != true) -%}
|
|
5
|
+
{%- if not item.data.eleventyExcludeFromCollections and (not item.data.sitemap or item.data.sitemap.ignore != true) and item.data.noindex != true -%}
|
|
6
6
|
{%- set pageLang = item.data.lang or site.defaultLanguage -%}
|
|
7
7
|
{%- if (not isMultilingual) or (not sitemapLang) or (pageLang == sitemapLang) -%}
|
|
8
8
|
{%- set absoluteUrl = item.url | htmlBaseUrl -%}
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
{%- if lastmod -%}<lastmod>{{ date.toUTCISO(lastmod) }}</lastmod>{%- endif -%}
|
|
13
13
|
{%- if item.data.sitemap and item.data.sitemap.changefreq -%}<changefreq>{{ item.data.sitemap.changefreq }}</changefreq>{%- endif -%}
|
|
14
14
|
{%- if item.data.sitemap and item.data.sitemap.priority is defined -%}<priority>{{ item.data.sitemap.priority }}</priority>{%- endif -%}
|
|
15
|
-
{%- if item.data.translationKey and collections.
|
|
16
|
-
{%- for language,
|
|
17
|
-
<xhtml:link rel="alternate" hreflang="{{
|
|
15
|
+
{%- if item.data.translationKey and collections.translationsMap and collections.translationsMap[item.data.translationKey] -%}
|
|
16
|
+
{%- for language, entry in collections.translationsMap[item.data.translationKey] -%}
|
|
17
|
+
<xhtml:link rel="alternate" hreflang="{{ entry.lang }}" href="{{ entry.url | htmlBaseUrl }}" />
|
|
18
18
|
{%- endfor -%}
|
|
19
19
|
{%- endif -%}
|
|
20
20
|
</url>
|
package/package.json
CHANGED