@apleasantview/eleventy-plugin-baseline 0.1.0-next.29 → 0.1.0-next.32
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
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
# Eleventy
|
|
1
|
+
# Eleventy Baseline
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
_An experimental Swiss army knife for Eleventy._
|
|
4
|
+
|
|
5
|
+
Eleventy Baseline is a lightweight toolkit built around a simple question:
|
|
6
|
+
|
|
7
|
+
> What if Eleventy had a minimal, optional layer of conventions — just enough to eliminate repetition, but not enough to feel restrictive?
|
|
8
|
+
|
|
9
|
+
It explores what a "core" for Eleventy could look like without becoming a framework or theme — small, practical tools rather than sweeping abstractions. If you've ever started a new Eleventy project and found yourself copy-pasting the same asset pipeline, the same head template, the same image shortcode for the third time, this is for you.
|
|
10
|
+
|
|
11
|
+
This is a practical, evolving baseline. Things might shift, break, or get renamed as the project evolves.
|
|
4
12
|
|
|
5
13
|
## Install
|
|
6
14
|
|
|
@@ -16,6 +24,8 @@ For a fresh project (install Eleventy and eleventy-img too):
|
|
|
16
24
|
npm install @11ty/eleventy @11ty/eleventy-img @apleasantview/eleventy-plugin-baseline
|
|
17
25
|
```
|
|
18
26
|
|
|
27
|
+
Requires Eleventy 3.x and Node >=20.
|
|
28
|
+
|
|
19
29
|
## Usage
|
|
20
30
|
|
|
21
31
|
In your Eleventy config (ESM):
|
|
@@ -34,13 +44,32 @@ export default function (eleventyConfig) {
|
|
|
34
44
|
export const config = baselineConfig;
|
|
35
45
|
```
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
## What's included
|
|
48
|
+
|
|
49
|
+
When the plugin loads, you get core filters, Nunjucks globals, debugging utilities, and an image shortcode (via eleventy-img) out of the box. On top of that, the plugin is organized into opt-in modules — take what you need:
|
|
50
|
+
|
|
51
|
+
| Module | What it does |
|
|
52
|
+
|---|---|
|
|
53
|
+
| `assets-core` | Shared foundation for the asset pipeline |
|
|
54
|
+
| `assets-esbuild` | JS bundling via esbuild, with an inline injection filter for critical scripts |
|
|
55
|
+
| `assets-postcss` | CSS processing via PostCSS + cssnano, with an inline injection filter for critical styles |
|
|
56
|
+
| `head-core` | Drop `<baseline-head>` into your template and get sensible meta, canonical, og:image, and basic SEO defaults — processed by PostHTML at build time |
|
|
57
|
+
| `multilang-core` | Directory-based multilingual support: per-language collections, hreflang, sitemaps, and language normalization |
|
|
58
|
+
| `navigator-core` | Navigation tree helpers and a `_navigator` Nunjucks global |
|
|
59
|
+
| `sitemap-core` | XML sitemap generation with draft-page support |
|
|
38
60
|
|
|
39
61
|
## Docs
|
|
40
62
|
|
|
41
|
-
|
|
63
|
+
Full documentation — tutorials, how-to guides, and reference — lives at:
|
|
42
64
|
[https://eleventy-plugin-baseline.netlify.app/](https://eleventy-plugin-baseline.netlify.app/)
|
|
43
65
|
|
|
66
|
+
## Contributing
|
|
67
|
+
|
|
68
|
+
Opinions, issues, and pull requests are welcome. If something doesn't work as documented, or
|
|
69
|
+
you've found a pattern that fits the spirit of the project,
|
|
70
|
+
[open an issue](https://github.com/apleasantview/eleventy-plugin-baseline/issues) and let's talk.
|
|
71
|
+
You can also find me on [Mastodon](https://mastodon.social/@crisverstraeten).
|
|
72
|
+
|
|
44
73
|
## License
|
|
45
74
|
|
|
46
75
|
MIT. See `LICENSE`.
|
package/core/shortcodes/image.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import Image from '@11ty/eleventy-img';
|
|
3
3
|
|
|
4
|
-
const DEFAULT_WIDTHS = [320, 640, 960, 1280];
|
|
5
|
-
const DEFAULT_FORMATS = ['avif', 'webp'
|
|
4
|
+
const DEFAULT_WIDTHS = [320, 640, 960, 1280, 1920, 'auto'];
|
|
5
|
+
const DEFAULT_FORMATS = ['avif', 'webp'];
|
|
6
6
|
const DEFAULT_SIZES = '(max-width: 768px) 100vw, 768px';
|
|
7
7
|
|
|
8
8
|
function pickRenditions(metadata) {
|
|
@@ -26,7 +26,7 @@ function pickRenditions(metadata) {
|
|
|
26
26
|
* @param {Array<number|string>} [options.widths=DEFAULT_WIDTHS] Widths passed to eleventy-img.
|
|
27
27
|
* @param {string} [options.sizes=DEFAULT_SIZES] Sizes attribute used on sources.
|
|
28
28
|
* @param {string[]} [options.formats=DEFAULT_FORMATS] Output formats (order matters).
|
|
29
|
-
* @param {string} [options.outputDir] Output directory for generated assets
|
|
29
|
+
* @param {string} [options.outputDir] Output directory for generated assets.
|
|
30
30
|
* @param {string} [options.urlPath="/media/"] Public URL base for generated assets.
|
|
31
31
|
* @param {Object} [options.attrs={}] Extra attributes applied to <img>; `class` merges with imageClass.
|
|
32
32
|
* @param {string} [options.style] Inline style applied to <img> (alias for attrs.style).
|
|
@@ -66,18 +66,34 @@ export async function imageShortcode(options = {}) {
|
|
|
66
66
|
const isRemote = /^https?:\/\//i.test(src);
|
|
67
67
|
const resolvedSrc = !isRemote && inputDir ? path.join(inputDir, src.replace(/^\//, '')) : src;
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
69
|
+
let metadata;
|
|
70
|
+
try {
|
|
71
|
+
metadata = await Image(resolvedSrc, {
|
|
72
|
+
transformOnRequest: process.env.ELEVENTY_RUN_MODE === 'serve',
|
|
73
|
+
widths: [...widths],
|
|
74
|
+
formats: [...formats],
|
|
75
|
+
outputDir,
|
|
76
|
+
urlPath,
|
|
77
|
+
filenameFormat(id, srcPath, width, format) {
|
|
78
|
+
const extension = path.extname(srcPath);
|
|
79
|
+
const name = path.basename(srcPath, extension);
|
|
80
|
+
return `${name}-${width}w.${format}`;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.warn(`imageShortcode: transformOnRequest failed for ${src}.\n > ${error?.message || error}`);
|
|
85
|
+
metadata = await Image(resolvedSrc, {
|
|
86
|
+
widths: [...widths],
|
|
87
|
+
formats: [...formats],
|
|
88
|
+
outputDir,
|
|
89
|
+
urlPath,
|
|
90
|
+
filenameFormat(id, srcPath, width, format) {
|
|
91
|
+
const extension = path.extname(srcPath);
|
|
92
|
+
const name = path.basename(srcPath, extension);
|
|
93
|
+
return `${name}-${width}w.${format}`;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
81
97
|
|
|
82
98
|
const { lowsrc, highsrc } = pickRenditions(metadata);
|
|
83
99
|
if (!lowsrc || !highsrc) {
|
package/package.json
CHANGED