From cd3fbc144fa123047095e4dd7df67010675a9827 Mon Sep 17 00:00:00 2001 From: Stephen Donahue Date: Sat, 28 Mar 2026 04:55:20 +0000 Subject: [PATCH] add image support: eleventy-img plugin, hero images, responsive picture elements --- .eleventy.js | 55 +++++++++++++++++++++++++++++++ _includes/column.njk | 5 +++ columns/2026-03-28-hello-world.md | 2 +- css/style.css | 21 ++++++++++++ img/.gitkeep | 0 index.njk | 5 +++ package.json | 3 +- 7 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 img/.gitkeep diff --git a/.eleventy.js b/.eleventy.js index 41c9b82..192b97f 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -1,5 +1,60 @@ +const Image = require("@11ty/eleventy-img"); +const path = require("path"); + +function imageShortcode(src, alt, sizes = "100vw") { + const inputPath = path.join("img", src); + const options = { + widths: [480, 800, 1200], + formats: ["avif", "webp", "jpeg"], + outputDir: "_site/img", + urlPath: "/img/", + filenameFormat: function (id, src, width, format) { + const name = path.basename(src, path.extname(src)); + return `${name}-${width}.${format}`; + }, + }; + + Image(inputPath, options); + const metadata = Image.statsSync(inputPath, options); + + return Image.generateHTML(metadata, { + alt, + sizes, + loading: "lazy", + decoding: "async", + }); +} + +function heroImageShortcode(src, alt) { + const inputPath = path.join("img", src); + const options = { + widths: [800, 1200, 1600], + formats: ["avif", "webp", "jpeg"], + outputDir: "_site/img", + urlPath: "/img/", + filenameFormat: function (id, src, width, format) { + const name = path.basename(src, path.extname(src)); + return `${name}-${width}.${format}`; + }, + }; + + Image(inputPath, options); + const metadata = Image.statsSync(inputPath, options); + + return Image.generateHTML(metadata, { + alt, + sizes: "(max-width: 960px) 100vw, 960px", + loading: "eager", + decoding: "async", + }); +} + module.exports = function (eleventyConfig) { eleventyConfig.addPassthroughCopy("css"); + eleventyConfig.addPassthroughCopy("img"); + + eleventyConfig.addShortcode("image", imageShortcode); + eleventyConfig.addShortcode("heroImage", heroImageShortcode); eleventyConfig.addCollection("columns", function (collectionApi) { return collectionApi diff --git a/_includes/column.njk b/_includes/column.njk index cb1c611..b46b171 100644 --- a/_includes/column.njk +++ b/_includes/column.njk @@ -14,6 +14,11 @@
+ {% if hero %} +
+ {% heroImage hero, heroAlt or title %} +
+ {% endif %}

{{ title }}

diff --git a/columns/2026-03-28-hello-world.md b/columns/2026-03-28-hello-world.md index cace7a9..18c9890 100644 --- a/columns/2026-03-28-hello-world.md +++ b/columns/2026-03-28-hello-world.md @@ -6,4 +6,4 @@ tags: column permalink: /columns/2026/hello-world/ --- -This is the first entry. +This is the first entry. With an edit. diff --git a/css/style.css b/css/style.css index abf212d..6bfb13d 100644 --- a/css/style.css +++ b/css/style.css @@ -80,6 +80,27 @@ a:hover { color: var(--color-muted); } +/* images */ + +.column-hero { + margin-bottom: 1.5rem; +} + +.column-hero picture, +.column-hero img { + display: block; + width: 100%; + height: auto; +} + +.column-body picture, +.column-body img { + display: block; + max-width: 100%; + height: auto; + margin: 1.5rem 0; +} + .column-body { margin-top: 1.5rem; } diff --git a/img/.gitkeep b/img/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/index.njk b/index.njk index b3e610e..a8caf72 100644 --- a/index.njk +++ b/index.njk @@ -5,6 +5,11 @@ layout: base.njk {%- set latest = collections.columns | first -%} {%- if latest %}
+ {% if latest.data.hero %} +
+ {% heroImage latest.data.hero, latest.data.heroAlt or latest.data.title %} +
+ {% endif %}

{{ latest.data.title }}

diff --git a/package.json b/package.json index a7688d4..a1ed43f 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dev": "eleventy --serve --watch" }, "dependencies": { - "@11ty/eleventy": "^3.0.0" + "@11ty/eleventy": "^3.0.0", + "@11ty/eleventy-img": "^5.0.0" } }