simplify image shortcode, split class in container and img

This commit is contained in:
madrilene 2025-01-09 14:04:50 +01:00
parent ce5326dfe8
commit 4a23681839

View file

@ -1,12 +1,6 @@
import Image from '@11ty/eleventy-img';
import path from 'node:path';
import htmlmin from 'html-minifier-terser';
/**
* Converts an attribute map object to a string of HTML attributes.
* @param {Object} attributeMap - The attribute map object.
* @returns {string} - The string of HTML attributes.
*/
const stringifyAttributes = attributeMap => {
return Object.entries(attributeMap)
.map(([attribute, value]) => {
@ -16,26 +10,15 @@ const stringifyAttributes = attributeMap => {
.join(' ');
};
/**
* Generates an HTML image element with responsive images and optional caption.
* @param {string} src - The path to the image source file.
* @param {string} [alt=''] - The alternative text for the image.
* @param {string} [caption=''] - The caption for the image.
* @param {string} [loading='lazy'] - The loading attribute for the image.
* @param {string} [className] - The CSS class name for the image element.
* @param {string} [sizes='90vw'] - The sizes attribute for the image.
* @param {number[]} [widths=[440, 650, 960, 1200]] - The widths for generating responsive images.
* @param {string[]} [formats=['avif', 'webp', 'jpeg']] - The formats for generating responsive images.
* @returns {string} - The HTML image element.
*/
export const imageShortcode = async (
src,
alt = '',
caption = '',
loading = 'lazy',
className,
sizes = '90vw',
widths = [440, 650, 960, 1200],
containerClass,
imageClass,
sizes = '100vw',
widths = [650, 960, 1200],
formats = ['avif', 'webp', 'jpeg']
) => {
const metadata = await Image(src, {
@ -52,15 +35,6 @@ export const imageShortcode = async (
const lowsrc = metadata.jpeg[metadata.jpeg.length - 1];
// Getting the URL to use
let imgSrc = src;
if (!imgSrc.startsWith('.')) {
const inputPath = this.page.inputPath;
const pathParts = inputPath.split('/');
pathParts.pop();
imgSrc = `${pathParts.join('/')}/${src}`;
}
const imageSources = Object.values(metadata)
.map(imageFormat => {
return ` <source type="${imageFormat[0].sourceType}" srcset="${imageFormat
@ -69,29 +43,20 @@ export const imageShortcode = async (
})
.join('\n');
const imgageAttributes = stringifyAttributes({
src: lowsrc.url,
width: lowsrc.width,
height: lowsrc.height,
const imageAttributes = stringifyAttributes({
'src': lowsrc.url,
'width': lowsrc.width,
'height': lowsrc.height,
alt,
loading,
decoding: loading === 'eager' ? 'sync' : 'async'
'decoding': loading === 'eager' ? 'sync' : 'async',
...(imageClass && {class: imageClass}),
'eleventy:ignore': ''
});
const imageElement = caption
? `<figure slot="image" class="flow ${className ? `${className}` : ''}">
<picture>
${imageSources}
<img
${imgageAttributes}>
</picture>
<figcaption>${caption}</figcaption>
</figure>`
: `<picture slot="image" class="flow ${className ? `${className}` : ''}">
${imageSources}
<img
${imgageAttributes}>
</picture>`;
const pictureElement = `<picture> ${imageSources}<img ${imageAttributes}></picture>`;
return htmlmin.minify(imageElement, {collapseWhitespace: true});
return caption
? `<figure slot="image"${containerClass ? ` class="${containerClass}"` : ''}>${pictureElement}<figcaption>${caption}</figcaption></figure>`
: `<picture slot="image"${containerClass ? ` class="${containerClass}"` : ''}>${imageSources}<img ${imageAttributes}></picture>`;
};