Skip to content

Commit b1b5e0d

Browse files
authored
✨ image support (#92)
Add 11ty image processing capabilities to the site. Closes #85 * add 11ty image * add outdent package * add plugin code to 11ty config
1 parent da78f48 commit b1b5e0d

2 files changed

Lines changed: 91 additions & 9 deletions

File tree

.eleventy.js

Lines changed: 88 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,101 @@
11
require('dotenv').config();
22
const Webmentions = require("eleventy-plugin-webmentions");
33
const pluginRss = require("@11ty/eleventy-plugin-rss");
4+
const Image = require("@11ty/eleventy-img");
45
const htmlmin = require("html-minifier");
6+
const outdent = require("outdent");
57

6-
module.exports = function(eleventyConfig) {
8+
/** Maps a config of attribute-value pairs to an HTML string
9+
* representing those same attribute-value pairs.
10+
*/
11+
const stringifyAttributes = (attributeMap) => {
12+
return Object.entries(attributeMap)
13+
.map(([attribute, value]) => {
14+
if (typeof value === 'undefined') return '';
15+
return `${attribute}="${value}"`;
16+
})
17+
.join(' ');
18+
};
19+
20+
// shortcode for using 11ty's Image plugin
21+
// from https://www.aleksandrhovhannisyan.com/blog/eleventy-image-plugin/
22+
const imageShortcode = async (
23+
src,
24+
alt,
25+
className = undefined,
26+
widths = [400, 800, 1280],
27+
formats = ['webp', 'jpeg'],
28+
sizes = '100vw'
29+
) => {
30+
const imageMetadata = await Image(src, {
31+
widths: [...widths, null],
32+
formats: [...formats, null],
33+
outputDir: '_site/media/images',
34+
urlPath: '/media/images',
35+
});
36+
const sourceHtmlString = Object.values(imageMetadata)
37+
// Map each format to the source HTML markup
38+
.map((images) => {
39+
// The first entry is representative of all the others
40+
// since they each have the same shape
41+
const { sourceType } = images[0];
42+
43+
// Use our util from earlier to make our lives easier
44+
const sourceAttributes = stringifyAttributes({
45+
type: sourceType,
46+
// srcset needs to be a comma-separated attribute
47+
srcset: images.map((image) => image.srcset).join(', '),
48+
sizes,
49+
});
50+
51+
// Return one <source> per format
52+
return `<source ${sourceAttributes}>`;
53+
})
54+
.join('\n');
55+
56+
const getLargestImage = (format) => {
57+
const images = imageMetadata[format];
58+
return images[images.length - 1];
59+
}
60+
61+
const largestUnoptimizedImg = getLargestImage(formats[0]);
62+
const imgAttributes = stringifyAttributes({
63+
src: largestUnoptimizedImg.url,
64+
width: largestUnoptimizedImg.width,
65+
height: largestUnoptimizedImg.height,
66+
alt,
67+
loading: 'lazy',
68+
decoding: 'async',
69+
});
70+
const imgHtmlString = `<img ${imgAttributes}>`;
71+
72+
const pictureAttributes = stringifyAttributes({
73+
class: className,
74+
});
75+
const picture = `<picture ${pictureAttributes}>
76+
${sourceHtmlString}
77+
${imgHtmlString}
78+
</picture>`;
79+
80+
return outdent`${picture}`;
81+
};
82+
83+
module.exports = function (eleventyConfig) {
784
// 11ty plugins
885
eleventyConfig.addPlugin(pluginRss);
986
eleventyConfig.addPlugin(Webmentions, {
1087
domain: "benkutil.com",
1188
token: process.env.WEBMENTIONS_TOKEN
12-
});
13-
89+
});
90+
91+
// 11ty shortcodes
92+
eleventyConfig.addShortcode('image', imageShortcode);
93+
1494
// run these configs in production only
15-
if (process.env.ELEVENTY_ENV === 'production' ) {
16-
eleventyConfig.addTransform("htmlmin", function(content, outputPath) {
95+
if (process.env.ELEVENTY_ENV === 'production') {
96+
eleventyConfig.addTransform("htmlmin", function (content, outputPath) {
1797
// find html files
18-
if(outputPath && outputPath.endsWith(".html")) {
98+
if (outputPath && outputPath.endsWith(".html")) {
1999
// configure html-minify
20100
let minified = htmlmin.minify(content, {
21101
useShortDoctype: true,
@@ -25,10 +105,10 @@ module.exports = function(eleventyConfig) {
25105
});
26106
return minified;
27107
}
28-
108+
29109
return content;
30110
});
31-
111+
32112
}
33113

34114
// Directory changes

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@
2121
"homepage": "https://github.com/benkutil/benkutil.github.io#readme",
2222
"devDependencies": {
2323
"@11ty/eleventy": "^2.0.0-beta.3",
24+
"@11ty/eleventy-img": "^3.0.0",
2425
"@11ty/eleventy-plugin-rss": "^1.2.0",
2526
"eleventy-plugin-webmentions": "^2.0.0",
26-
"html-minifier": "^4.0.0"
27+
"html-minifier": "^4.0.0",
28+
"outdent": "^0.8.0"
2729
},
2830
"dependencies": {
2931
"@11ty/eleventy-upgrade-help": "^2.0.5",

0 commit comments

Comments
 (0)