@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
package/README.md
CHANGED
|
@@ -5,11 +5,13 @@ An experimental Swiss army knife toolkit for Eleventy. Bundles handy helpers for
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
If you already have Eleventy and eleventy-img installed:
|
|
8
|
+
|
|
8
9
|
```bash
|
|
9
10
|
npm install @apleasantview/eleventy-plugin-baseline
|
|
10
11
|
```
|
|
11
12
|
|
|
12
13
|
For a fresh project (install Eleventy and eleventy-img too):
|
|
14
|
+
|
|
13
15
|
```bash
|
|
14
16
|
npm install @11ty/eleventy @11ty/eleventy-img @apleasantview/eleventy-plugin-baseline
|
|
15
17
|
```
|
|
@@ -19,7 +21,7 @@ npm install @11ty/eleventy @11ty/eleventy-img @apleasantview/eleventy-plugin-bas
|
|
|
19
21
|
In your Eleventy config (ESM):
|
|
20
22
|
|
|
21
23
|
```js
|
|
22
|
-
import baseline, { config as baselineConfig } from
|
|
24
|
+
import baseline, { config as baselineConfig } from '@apleasantview/eleventy-plugin-baseline';
|
|
23
25
|
|
|
24
26
|
export default function (eleventyConfig) {
|
|
25
27
|
eleventyConfig.addPlugin(baseline, {
|
package/core/debug.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { inspect as utilInspect } from
|
|
1
|
+
import { inspect as utilInspect } from 'node:util';
|
|
2
2
|
|
|
3
3
|
// Adapted from pdehaan - https://github.com/pdehaan/eleventy-plugin-debug
|
|
4
4
|
const debugOptions = Object.assign({
|
|
5
|
-
|
|
5
|
+
space: 0
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
function inspect(obj, options = {}) {
|
|
9
|
-
|
|
9
|
+
return utilInspect(obj, options);
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function json(obj, space = debugOptions.space) {
|
|
13
|
-
|
|
13
|
+
return JSON.stringify(obj, null, space);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function keys(obj) {
|
|
17
|
-
|
|
17
|
+
return Object.keys(obj).sort();
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export default { inspect, json, keys };
|
package/core/filters/isString.js
CHANGED
package/core/filters/markdown.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
//
|
|
1
|
+
// See https://jeremias.codes/2025/02/markdown-filters-eleventy/
|
|
2
2
|
import markdownit from 'markdown-it';
|
|
3
3
|
|
|
4
|
-
const md = markdownit(
|
|
5
|
-
html: true
|
|
6
|
-
});
|
|
4
|
+
const md = markdownit();
|
|
7
5
|
|
|
8
6
|
export const markdownFilter = (string) => {
|
|
9
|
-
|
|
7
|
+
return md.renderInline(string);
|
|
10
8
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export default function relatedPostsFilter(collection = []) {
|
|
2
|
-
const page = this
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
2
|
+
const page = this?.ctx?.page;
|
|
3
|
+
if (!page?.url) return collection;
|
|
4
|
+
return collection.filter((post) => post.url !== page.url);
|
|
5
|
+
}
|
package/core/filters.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { markdownFilter } from
|
|
2
|
-
import relatedPostsFilter from
|
|
3
|
-
import isStringFilter from
|
|
1
|
+
import { markdownFilter } from './filters/markdown.js';
|
|
2
|
+
import relatedPostsFilter from './filters/related-posts.js';
|
|
3
|
+
import isStringFilter from './filters/isString.js';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
markdownFilter,
|
|
7
7
|
relatedPostsFilter,
|
|
8
8
|
isStringFilter
|
|
9
|
-
}
|
|
9
|
+
};
|
package/core/globals/date.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DateTime } from
|
|
1
|
+
import { DateTime } from 'luxon';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Register Nunjucks global "date" with helper methods.
|
|
@@ -7,11 +7,11 @@ import { DateTime } from "luxon";
|
|
|
7
7
|
* @param {import("@11ty/eleventy").UserConfig} eleventyConfig
|
|
8
8
|
*/
|
|
9
9
|
export function registerDateGlobal(eleventyConfig) {
|
|
10
|
-
eleventyConfig.addNunjucksGlobal(
|
|
10
|
+
eleventyConfig.addNunjucksGlobal('date', {
|
|
11
11
|
toUTCISO(value) {
|
|
12
|
-
if (!value) return
|
|
12
|
+
if (!value) return '';
|
|
13
13
|
const jsDate = value instanceof Date ? value : new Date(value);
|
|
14
|
-
if (Number.isNaN(jsDate.getTime())) return
|
|
14
|
+
if (Number.isNaN(jsDate.getTime())) return '';
|
|
15
15
|
return DateTime.fromJSDate(jsDate).toUTC().toISO({ suppressMilliseconds: true });
|
|
16
16
|
}
|
|
17
17
|
});
|
package/core/globals.js
CHANGED
package/core/helpers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import { TemplatePath } from
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { TemplatePath } from '@11ty/eleventy-utils';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Helper function to add trailing slash to a path
|
|
@@ -7,10 +7,10 @@ import { TemplatePath } from "@11ty/eleventy-utils";
|
|
|
7
7
|
* @returns {string}
|
|
8
8
|
*/
|
|
9
9
|
export function addTrailingSlash(path) {
|
|
10
|
-
if (path.slice(-1) ===
|
|
10
|
+
if (path.slice(-1) === '/') {
|
|
11
11
|
return path;
|
|
12
12
|
}
|
|
13
|
-
return path +
|
|
13
|
+
return path + '/';
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -22,15 +22,15 @@ export function addTrailingSlash(path) {
|
|
|
22
22
|
*/
|
|
23
23
|
export function resolveAssetsDir(inputDir, outputDir, rawDir) {
|
|
24
24
|
// Join input/output with assets subdir and normalize
|
|
25
|
-
const joinedInput = TemplatePath.join(inputDir, rawDir ||
|
|
26
|
-
const joinedOutput = TemplatePath.join(outputDir, rawDir ||
|
|
25
|
+
const joinedInput = TemplatePath.join(inputDir, rawDir || '');
|
|
26
|
+
const joinedOutput = TemplatePath.join(outputDir, rawDir || '');
|
|
27
27
|
|
|
28
28
|
const assetsDir = addTrailingSlash(TemplatePath.standardizeFilePath(joinedInput));
|
|
29
29
|
const assetsOutputDir = addTrailingSlash(TemplatePath.standardizeFilePath(joinedOutput));
|
|
30
30
|
|
|
31
31
|
return {
|
|
32
32
|
assetsDir,
|
|
33
|
-
assetsOutputDir
|
|
33
|
+
assetsOutputDir
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -41,13 +41,11 @@ export function resolveAssetsDir(inputDir, outputDir, rawDir) {
|
|
|
41
41
|
* @returns {string[]} Absolute glob patterns
|
|
42
42
|
*/
|
|
43
43
|
export function buildGlobPatterns(patterns, assetsDir) {
|
|
44
|
-
const assetsDirAbsolute = TemplatePath.absolutePath(
|
|
45
|
-
|
|
46
|
-
);
|
|
47
|
-
|
|
44
|
+
const assetsDirAbsolute = TemplatePath.absolutePath(TemplatePath.stripLeadingDotSlash(assetsDir));
|
|
45
|
+
|
|
48
46
|
return patterns.map((pattern) => {
|
|
49
47
|
const normalized = TemplatePath.standardizeFilePath(pattern);
|
|
50
|
-
return normalized.startsWith(
|
|
48
|
+
return normalized.startsWith('/') || path.isAbsolute(normalized)
|
|
51
49
|
? normalized
|
|
52
50
|
: TemplatePath.join(assetsDirAbsolute, normalized);
|
|
53
51
|
});
|
|
@@ -60,7 +58,7 @@ export function buildGlobPatterns(patterns, assetsDir) {
|
|
|
60
58
|
*/
|
|
61
59
|
export function extractFileMetadata(filePath) {
|
|
62
60
|
const ext = path.extname(filePath); // Returns extension with dot (e.g., ".css") or ""
|
|
63
|
-
const inputFileExtension = ext && ext.length > 0 ? ext.slice(1) :
|
|
61
|
+
const inputFileExtension = ext && ext.length > 0 ? ext.slice(1) : '';
|
|
64
62
|
const basename = TemplatePath.getLastPathSegment(filePath, false);
|
|
65
63
|
const fileSlug = ext ? basename.slice(0, -ext.length) : basename;
|
|
66
64
|
|
|
@@ -90,41 +88,31 @@ export function createCollectionItem(
|
|
|
90
88
|
// Get path relative to input directory
|
|
91
89
|
// e.g., inputPath = "./src/assets/css/index.css", inputDir = "./src/"
|
|
92
90
|
// relToInput = "assets/css/index.css"
|
|
93
|
-
const relToInput = TemplatePath.stripLeadingSubPath(
|
|
94
|
-
inputPath,
|
|
95
|
-
TemplatePath.addLeadingDotSlash(inputDir)
|
|
96
|
-
);
|
|
91
|
+
const relToInput = TemplatePath.stripLeadingSubPath(inputPath, TemplatePath.addLeadingDotSlash(inputDir));
|
|
97
92
|
|
|
98
93
|
// outputPath: prepend output directory (with leading ./)
|
|
99
94
|
// e.g., relToInput = "assets/css/index.css", outputDir = "./dist/"
|
|
100
95
|
// outputPath = "./dist/assets/css/index.css"
|
|
101
96
|
const outputPath = TemplatePath.addLeadingDotSlash(
|
|
102
|
-
TemplatePath.normalize(
|
|
103
|
-
TemplatePath.join(
|
|
104
|
-
TemplatePath.addLeadingDotSlash(outputDir),
|
|
105
|
-
relToInput
|
|
106
|
-
)
|
|
107
|
-
)
|
|
97
|
+
TemplatePath.normalize(TemplatePath.join(TemplatePath.addLeadingDotSlash(outputDir), relToInput))
|
|
108
98
|
);
|
|
109
99
|
|
|
110
100
|
// relToAssets: path relative to assets directory for URL generation
|
|
111
101
|
// e.g., inputPath = "./src/assets/css/index.css", assetsDirRelative = "assets"
|
|
112
102
|
// relToAssets = "css/index.css"
|
|
113
|
-
const assetsDirPath = TemplatePath.addLeadingDotSlash(
|
|
114
|
-
TemplatePath.join(inputDir, assetsDirRelative)
|
|
115
|
-
);
|
|
103
|
+
const assetsDirPath = TemplatePath.addLeadingDotSlash(TemplatePath.join(inputDir, assetsDirRelative));
|
|
116
104
|
const relToAssets = TemplatePath.stripLeadingSubPath(inputPath, assetsDirPath);
|
|
117
105
|
|
|
118
|
-
const url = passthrough
|
|
119
|
-
? TemplatePath.join(passthroughOutput, relToAssets).replace(/\/$/, "")
|
|
120
|
-
: undefined;
|
|
106
|
+
const url = passthrough ? TemplatePath.join(passthroughOutput, relToAssets).replace(/\/$/, '') : undefined;
|
|
121
107
|
|
|
122
108
|
// filePathStem: path relative to input without extension, with leading slash
|
|
123
109
|
// e.g., relToInput = "assets/css/index.css"
|
|
124
110
|
// filePathStem = "/assets/css/index"
|
|
125
|
-
const filePathStem =
|
|
126
|
-
|
|
127
|
-
|
|
111
|
+
const filePathStem =
|
|
112
|
+
'/' +
|
|
113
|
+
(inputFileExtension
|
|
114
|
+
? relToInput.slice(0, -inputFileExtension.length - 1) // Remove extension and dot
|
|
115
|
+
: relToInput);
|
|
128
116
|
|
|
129
117
|
return {
|
|
130
118
|
inputPath,
|
|
@@ -134,6 +122,6 @@ export function createCollectionItem(
|
|
|
134
122
|
inputFileExtension,
|
|
135
123
|
filePathStem,
|
|
136
124
|
dir: TemplatePath.getDirFromFilePath(inputPath),
|
|
137
|
-
url
|
|
125
|
+
url
|
|
138
126
|
};
|
|
139
127
|
}
|
package/core/modules.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// Eleventy plugins
|
|
2
|
-
import { EleventyHtmlBasePlugin } from
|
|
2
|
+
import { EleventyHtmlBasePlugin } from '@11ty/eleventy';
|
|
3
3
|
|
|
4
4
|
// Custom plugins
|
|
5
|
-
import multilangCore from
|
|
6
|
-
import navigatorCore from
|
|
7
|
-
import assetsCore from
|
|
8
|
-
import assetsPostCSS from
|
|
9
|
-
import assetsESBuild from
|
|
10
|
-
import headCore from
|
|
11
|
-
import sitemapCore from
|
|
5
|
+
import multilangCore from '../modules/multilang-core/plugins/multilang-core.js';
|
|
6
|
+
import navigatorCore from '../modules/navigator-core/plugins/navigator-core.js';
|
|
7
|
+
import assetsCore from '../modules/assets-core/plugins/assets-core.js';
|
|
8
|
+
import assetsPostCSS from '../modules/assets-postcss/plugins/assets-postcss.js';
|
|
9
|
+
import assetsESBuild from '../modules/assets-esbuild/plugins/assets-esbuild.js';
|
|
10
|
+
import headCore from '../modules/head-core/plugins/head-core.js';
|
|
11
|
+
import sitemapCore from '../modules/sitemap-core/plugins/sitemap-core.js';
|
|
12
12
|
|
|
13
13
|
export default {
|
|
14
14
|
EleventyHtmlBasePlugin,
|
package/core/shortcodes/image.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import Image from
|
|
3
|
-
import { eleventyImageOnRequestDuringServePlugin } from "@11ty/eleventy-img";
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import Image from '@11ty/eleventy-img';
|
|
4
3
|
|
|
5
4
|
const DEFAULT_WIDTHS = [320, 640, 960, 1280];
|
|
6
|
-
const DEFAULT_FORMATS = [
|
|
7
|
-
const DEFAULT_SIZES =
|
|
8
|
-
const DEFAULT_OUTPUT = {
|
|
9
|
-
outputDir: "./dist/media/",
|
|
10
|
-
urlPath: "/media/",
|
|
11
|
-
};
|
|
5
|
+
const DEFAULT_FORMATS = ['avif', 'webp', 'jpeg'];
|
|
6
|
+
const DEFAULT_SIZES = '(max-width: 768px) 100vw, 768px';
|
|
12
7
|
|
|
13
8
|
function pickRenditions(metadata) {
|
|
14
9
|
// Use the first available format; first entry is smallest, last is largest.
|
|
@@ -31,52 +26,48 @@ function pickRenditions(metadata) {
|
|
|
31
26
|
* @param {Array<number|string>} [options.widths=DEFAULT_WIDTHS] Widths passed to eleventy-img.
|
|
32
27
|
* @param {string} [options.sizes=DEFAULT_SIZES] Sizes attribute used on sources.
|
|
33
28
|
* @param {string[]} [options.formats=DEFAULT_FORMATS] Output formats (order matters).
|
|
34
|
-
* @param {string} [options.outputDir
|
|
35
|
-
* @param {string} [options.urlPath=
|
|
29
|
+
* @param {string} [options.outputDir] Output directory for generated assets (defaults to `./dist/media/` or `./<dir.output>/media/` when set).
|
|
30
|
+
* @param {string} [options.urlPath="/media/"] Public URL base for generated assets.
|
|
36
31
|
* @param {Object} [options.attrs={}] Extra attributes applied to <img>; `class` merges with imageClass.
|
|
37
32
|
* @param {string} [options.style] Inline style applied to <img> (alias for attrs.style).
|
|
38
33
|
* @param {boolean} [options.figure=true] Wrap in <figure> when caption is provided.
|
|
39
34
|
* @param {boolean} [options.setDimensions=true] When false, omit width/height on <img>.
|
|
40
35
|
*/
|
|
41
36
|
export async function imageShortcode(options = {}) {
|
|
37
|
+
const outputBase = this?.eleventy?.directories?.output || 'dist';
|
|
42
38
|
const {
|
|
43
39
|
src,
|
|
44
40
|
alt,
|
|
45
|
-
caption =
|
|
46
|
-
loading =
|
|
47
|
-
containerClass =
|
|
48
|
-
imageClass =
|
|
41
|
+
caption = '',
|
|
42
|
+
loading = 'lazy',
|
|
43
|
+
containerClass = '',
|
|
44
|
+
imageClass = '',
|
|
49
45
|
style,
|
|
50
46
|
widths = DEFAULT_WIDTHS,
|
|
51
47
|
sizes = DEFAULT_SIZES,
|
|
52
48
|
formats = DEFAULT_FORMATS,
|
|
53
|
-
outputDir =
|
|
54
|
-
urlPath =
|
|
49
|
+
outputDir = path.join('.', outputBase, 'media'),
|
|
50
|
+
urlPath = '/media/',
|
|
55
51
|
attrs = {},
|
|
56
52
|
figure = true,
|
|
57
|
-
setDimensions = true
|
|
53
|
+
setDimensions = true
|
|
58
54
|
} = options;
|
|
59
|
-
|
|
60
55
|
const hasImageTransformPlugin = this.ctx._baseline.hasImageTransformPlugin;
|
|
61
56
|
|
|
62
|
-
if (!src) throw new Error(
|
|
57
|
+
if (!src) throw new Error('imageShortcode: src is required');
|
|
63
58
|
if (alt === undefined) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
"imageShortcode: alt is required (use empty string for decorative images)",
|
|
66
|
-
);
|
|
59
|
+
throw new Error('imageShortcode: alt is required (use empty string for decorative images)');
|
|
67
60
|
}
|
|
68
61
|
|
|
69
|
-
const normalizedCaption = caption == null ?
|
|
70
|
-
const normalizedAlt = alt == null ?
|
|
62
|
+
const normalizedCaption = caption == null ? '' : String(caption);
|
|
63
|
+
const normalizedAlt = alt == null ? '' : String(alt);
|
|
71
64
|
|
|
72
65
|
const inputDir = this?.eleventy?.directories?.input;
|
|
73
66
|
const isRemote = /^https?:\/\//i.test(src);
|
|
74
|
-
const resolvedSrc = !isRemote && inputDir
|
|
75
|
-
? path.join(inputDir, src.replace(/^\//, ""))
|
|
76
|
-
: src;
|
|
67
|
+
const resolvedSrc = !isRemote && inputDir ? path.join(inputDir, src.replace(/^\//, '')) : src;
|
|
77
68
|
|
|
78
69
|
const metadata = await Image(resolvedSrc, {
|
|
79
|
-
transformOnRequest: process.env.ELEVENTY_RUN_MODE ===
|
|
70
|
+
transformOnRequest: process.env.ELEVENTY_RUN_MODE === 'serve',
|
|
80
71
|
widths: [...widths],
|
|
81
72
|
formats: [...formats],
|
|
82
73
|
outputDir,
|
|
@@ -85,7 +76,7 @@ export async function imageShortcode(options = {}) {
|
|
|
85
76
|
const extension = path.extname(srcPath);
|
|
86
77
|
const name = path.basename(srcPath, extension);
|
|
87
78
|
return `${name}-${width}w.${format}`;
|
|
88
|
-
}
|
|
79
|
+
}
|
|
89
80
|
});
|
|
90
81
|
|
|
91
82
|
const { lowsrc, highsrc } = pickRenditions(metadata);
|
|
@@ -96,32 +87,32 @@ export async function imageShortcode(options = {}) {
|
|
|
96
87
|
const sourceTags = Object.values(metadata)
|
|
97
88
|
.map((formatEntries) => {
|
|
98
89
|
const type = formatEntries[0].sourceType;
|
|
99
|
-
const srcset = formatEntries.map((entry) => entry.srcset).join(
|
|
90
|
+
const srcset = formatEntries.map((entry) => entry.srcset).join(', ');
|
|
100
91
|
return `<source type="${type}" srcset="${srcset}" sizes="${sizes}">`;
|
|
101
92
|
})
|
|
102
|
-
.join(
|
|
93
|
+
.join('\n');
|
|
103
94
|
|
|
104
95
|
const { class: attrClass, ...restAttrs } = attrs;
|
|
105
|
-
const combinedClass = [imageClass, attrClass].filter(Boolean).join(
|
|
96
|
+
const combinedClass = [imageClass, attrClass].filter(Boolean).join(' ').trim() || undefined;
|
|
106
97
|
|
|
107
98
|
const imageAttributes = {
|
|
108
99
|
src: lowsrc.url,
|
|
109
100
|
alt: normalizedAlt,
|
|
110
101
|
loading,
|
|
111
|
-
decoding: loading ===
|
|
102
|
+
decoding: loading === 'eager' ? 'sync' : 'async',
|
|
112
103
|
class: combinedClass,
|
|
113
104
|
style,
|
|
114
105
|
...(setDimensions ? { width: highsrc.width, height: highsrc.height } : {}),
|
|
115
106
|
...restAttrs,
|
|
116
|
-
...(hasImageTransformPlugin ? {
|
|
107
|
+
...(hasImageTransformPlugin ? { 'eleventy:ignore': true } : {})
|
|
117
108
|
};
|
|
118
109
|
|
|
119
110
|
const imgAttrString = Object.entries(imageAttributes)
|
|
120
|
-
.filter(([, value]) => value !== undefined && value !== null && value !==
|
|
121
|
-
.map(([key, value]) => value === true ? key : `${key}="${value}"`)
|
|
122
|
-
.join(
|
|
111
|
+
.filter(([, value]) => value !== undefined && value !== null && value !== '')
|
|
112
|
+
.map(([key, value]) => (value === true ? key : `${key}="${value}"`))
|
|
113
|
+
.join(' ');
|
|
123
114
|
|
|
124
|
-
const pictureClass = containerClass && containerClass.trim() ? ` class="${containerClass.trim()}"` :
|
|
115
|
+
const pictureClass = containerClass && containerClass.trim() ? ` class="${containerClass.trim()}"` : '';
|
|
125
116
|
|
|
126
117
|
const picture = `<picture${pictureClass}>
|
|
127
118
|
${sourceTags}
|
package/core/shortcodes.js
CHANGED
package/eleventy.config.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import globals from
|
|
3
|
-
import debug from
|
|
4
|
-
import filters from
|
|
5
|
-
import modules from
|
|
6
|
-
import shortcodes from
|
|
7
|
-
import { eleventyImageOnRequestDuringServePlugin } from
|
|
8
|
-
|
|
9
|
-
import { createRequire } from
|
|
1
|
+
import 'dotenv/config';
|
|
2
|
+
import globals from './core/globals.js';
|
|
3
|
+
import debug from './core/debug.js';
|
|
4
|
+
import filters from './core/filters.js';
|
|
5
|
+
import modules from './core/modules.js';
|
|
6
|
+
import shortcodes from './core/shortcodes.js';
|
|
7
|
+
import { eleventyImageOnRequestDuringServePlugin } from '@11ty/eleventy-img';
|
|
8
|
+
|
|
9
|
+
import { createRequire } from 'node:module';
|
|
10
10
|
const __require = createRequire(import.meta.url);
|
|
11
11
|
|
|
12
|
-
const { name, version } = __require(
|
|
12
|
+
const { name, version } = __require('./package.json');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Eleventy Plugin Baseline.
|
|
@@ -31,12 +31,12 @@ export default function baseline(options = {}) {
|
|
|
31
31
|
const plugin = async function (eleventyConfig) {
|
|
32
32
|
try {
|
|
33
33
|
// Emit a warning message if the application is not using Eleventy 3.0 or newer (including prereleases).
|
|
34
|
-
eleventyConfig.versionCheck(
|
|
34
|
+
eleventyConfig.versionCheck('>=3.0');
|
|
35
35
|
} catch (e) {
|
|
36
36
|
console.log(`[eleventy-plugin-baseline] WARN Eleventy plugin compatibility: ${e.message}`);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const hasImageTransformPlugin = eleventyConfig.hasPlugin(
|
|
39
|
+
const hasImageTransformPlugin = eleventyConfig.hasPlugin('eleventyImageTransformPlugin');
|
|
40
40
|
|
|
41
41
|
const userOptions = {
|
|
42
42
|
version,
|
|
@@ -45,28 +45,47 @@ export default function baseline(options = {}) {
|
|
|
45
45
|
hasImageTransformPlugin,
|
|
46
46
|
enableNavigatorTemplate: options.enableNavigatorTemplate ?? false,
|
|
47
47
|
enableSitemapTemplate: options.enableSitemapTemplate ?? true,
|
|
48
|
+
filterAllCollection: options.filterAllCollection ?? true,
|
|
48
49
|
assets: {
|
|
49
|
-
esbuild: options.assetsESBuild ?? { minify: true, target:
|
|
50
|
+
esbuild: options.assetsESBuild ?? { minify: true, target: 'es2020' }
|
|
50
51
|
},
|
|
51
52
|
multilingual: options.multilingual ?? false,
|
|
52
53
|
...options
|
|
53
54
|
};
|
|
54
55
|
|
|
55
56
|
// Core functions.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
|
|
58
|
+
// Normalize languages to an object map; if missing or invalid, use null.
|
|
59
|
+
const normalizedLanguages = Array.isArray(userOptions.languages)
|
|
60
|
+
? Object.fromEntries(
|
|
61
|
+
userOptions.languages
|
|
62
|
+
.filter((lang) => typeof lang === 'string' && lang.trim())
|
|
63
|
+
.map((lang) => [lang.trim(), {}])
|
|
64
|
+
)
|
|
65
|
+
: userOptions.languages && typeof userOptions.languages === 'object'
|
|
66
|
+
? userOptions.languages
|
|
67
|
+
: null;
|
|
68
|
+
|
|
69
|
+
if (userOptions.verbose && Array.isArray(userOptions.languages)) {
|
|
70
|
+
const normalizedCount = normalizedLanguages ? Object.keys(normalizedLanguages).length : 0;
|
|
71
|
+
if (normalizedCount !== userOptions.languages.length) {
|
|
72
|
+
console.warn('[baseline] Some languages entries were invalid and were dropped.');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
userOptions.languages = normalizedLanguages;
|
|
77
|
+
const languages = normalizedLanguages;
|
|
59
78
|
const hasLanguages = languages && Object.keys(languages).length > 0;
|
|
60
79
|
const isMultilingual = userOptions.multilingual === true && userOptions.defaultLanguage && hasLanguages;
|
|
61
80
|
|
|
62
|
-
eleventyConfig.addGlobalData(
|
|
81
|
+
eleventyConfig.addGlobalData('_baseline', userOptions);
|
|
63
82
|
globals(eleventyConfig);
|
|
64
|
-
eleventyConfig.addPassthroughCopy({
|
|
83
|
+
eleventyConfig.addPassthroughCopy({ './src/static': '/' });
|
|
65
84
|
|
|
66
85
|
// Prevents double-registering the preprocessor, user config wins.
|
|
67
86
|
if (!eleventyConfig.preprocessors.drafts) {
|
|
68
|
-
eleventyConfig.addPreprocessor(
|
|
69
|
-
if (data.draft && process.env.ELEVENTY_RUN_MODE ===
|
|
87
|
+
eleventyConfig.addPreprocessor('drafts', '*', (data) => {
|
|
88
|
+
if (data.draft && process.env.ELEVENTY_RUN_MODE === 'build') {
|
|
70
89
|
return false;
|
|
71
90
|
}
|
|
72
91
|
});
|
|
@@ -80,45 +99,59 @@ export default function baseline(options = {}) {
|
|
|
80
99
|
}
|
|
81
100
|
|
|
82
101
|
// Modules.
|
|
83
|
-
eleventyConfig.addPlugin(modules.EleventyHtmlBasePlugin, {
|
|
102
|
+
eleventyConfig.addPlugin(modules.EleventyHtmlBasePlugin, {
|
|
103
|
+
baseHref: process.env.URL || eleventyConfig.pathPrefix
|
|
104
|
+
});
|
|
84
105
|
eleventyConfig.addPlugin(modules.assetsCore);
|
|
85
106
|
eleventyConfig.addPlugin(modules.assetsPostCSS);
|
|
86
107
|
eleventyConfig.addPlugin(modules.assetsESBuild, userOptions.assets.esbuild);
|
|
108
|
+
|
|
109
|
+
if (userOptions.filterAllCollection) {
|
|
110
|
+
// Override the default collection behavior. Adding js as template format collects 11tydata.js files.
|
|
111
|
+
eleventyConfig.addCollection('all', (collectionApi) =>
|
|
112
|
+
collectionApi.getAll().filter((item) => !item.inputPath.endsWith('11tydata.js'))
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
87
116
|
eleventyConfig.addPlugin(modules.headCore);
|
|
88
|
-
eleventyConfig.addPlugin(modules.sitemapCore, {
|
|
117
|
+
eleventyConfig.addPlugin(modules.sitemapCore, {
|
|
118
|
+
enableSitemapTemplate: userOptions.enableSitemapTemplate,
|
|
119
|
+
multilingual: isMultilingual,
|
|
120
|
+
languages
|
|
121
|
+
});
|
|
89
122
|
|
|
90
123
|
// Filters — Module filters might move to their respective module.
|
|
91
|
-
eleventyConfig.addFilter(
|
|
92
|
-
eleventyConfig.addFilter(
|
|
93
|
-
eleventyConfig.addFilter(
|
|
124
|
+
eleventyConfig.addFilter('markdownify', filters.markdownFilter);
|
|
125
|
+
eleventyConfig.addFilter('relatedPosts', filters.relatedPostsFilter);
|
|
126
|
+
eleventyConfig.addFilter('isString', filters.isStringFilter);
|
|
94
127
|
|
|
95
128
|
// Shortcodes.
|
|
96
|
-
eleventyConfig.addShortcode(
|
|
129
|
+
eleventyConfig.addShortcode('image', shortcodes.imageShortcode);
|
|
97
130
|
|
|
98
131
|
// Add the dev server middleware for images.
|
|
99
132
|
eleventyConfig.addPlugin(eleventyImageOnRequestDuringServePlugin);
|
|
100
133
|
|
|
101
134
|
// Debug filters and navigators.
|
|
102
|
-
eleventyConfig.addFilter(
|
|
103
|
-
eleventyConfig.addFilter(
|
|
104
|
-
eleventyConfig.addFilter(
|
|
135
|
+
eleventyConfig.addFilter('_inspect', debug.inspect);
|
|
136
|
+
eleventyConfig.addFilter('_json', debug.json);
|
|
137
|
+
eleventyConfig.addFilter('_keys', debug.keys);
|
|
105
138
|
eleventyConfig.addPlugin(modules.navigatorCore, { enableNavigatorTemplate: userOptions.enableNavigatorTemplate });
|
|
106
139
|
};
|
|
107
140
|
|
|
108
141
|
// Set plugin name so `eleventyConfig.hasPlugin()` can detect it.
|
|
109
|
-
Object.defineProperty(plugin,
|
|
142
|
+
Object.defineProperty(plugin, 'name', { value: `${name}` });
|
|
110
143
|
return plugin;
|
|
111
144
|
}
|
|
112
145
|
|
|
113
146
|
export const config = {
|
|
114
147
|
dir: {
|
|
115
|
-
input:
|
|
116
|
-
output:
|
|
117
|
-
data:
|
|
118
|
-
includes:
|
|
119
|
-
assets:
|
|
148
|
+
input: 'src',
|
|
149
|
+
output: 'dist',
|
|
150
|
+
data: '_data',
|
|
151
|
+
includes: '_includes',
|
|
152
|
+
assets: 'assets'
|
|
120
153
|
},
|
|
121
|
-
htmlTemplateEngine:
|
|
122
|
-
markdownTemplateEngine:
|
|
123
|
-
templateFormats: [
|
|
154
|
+
htmlTemplateEngine: 'njk',
|
|
155
|
+
markdownTemplateEngine: 'njk',
|
|
156
|
+
templateFormats: ['html', 'njk', 'md']
|
|
124
157
|
};
|