Archive — page 5


New site part 4 - images

Part of a series about setting up the new 11ty version of this site

One of the things that I like about WordPress is how it deals with images for you — so I want to leverage eleventy-img to make using images as simple and repeatable as possible.

Starting generically

I'm going to start out by writing an 11ty shortcode to produce an image based on arbitrary inputs. As I've previously set out I'll keep the detailed code in a separate JS file and import the function into my eleventy config.

// going to need Image from eleventy-img, and path

const Image = require("@11ty/eleventy-img");
const path = require("path");

const generateImageTags = async (data) => {

    // allow for arbitrary:
    // - src (file-path)
    // - alt text
    // - image widths, provided as an array in pixels
    // - div_width, the 'ideal' width of the image in points
    // - loading, text, either eager or lazy, defaults to lazy
    // - caption, text to be displayed under the image
    const { src, alt, widths, div_width, sizes, loading, caption } = JSON.parse(data);

    // set the urlPath based on the actual image path
    const urlPath = path.dirname(src).replace("./src/images", "/img") + "/";

    // generate the images and get metadata for them; generating webp and jpeg fallback,
    // with custom filename based on the original filename plus the width
    const metadata = await Image(src, {
        widths: widths,
        formats: ["webp", "jpeg"],
        outputDir: `./_site${urlPath}`,
        urlPath: urlPath,
        filenameFormat: function (id, src, width, format, options) {
            const extension = path.extname(src);
            const name = path.basename(src, extension);
            return `${name}-${width}w.${format}`;
        }
    });

    // attributes from arbitrary inputs; the image will be included within a separate
    // containing div of defined width (and max-width) so the style attribute will let
    // the image be laid out properly before it's finished loading
    const attributes = {
        alt: alt,
        loading: loading || 'lazy',
        decoding: "async",
        sizes: sizes,
        style: "width: 100%; height: auto;"
    }

    // generate the HTML for the image
    const imageHTML = Image.generateHTML(metadata, attributes);

    // generate a containing div for the image HTML generated, plus a styled
    // caption if provided
    let output = `
<div style="width: ${div_width}; max-width: 100%; margin: 0 auto;">
    ${imageHTML}
</div>`

    if (caption && caption != '') {
        output = output + `        
<p class="caption" style="width: ${div_width}; max-width: 100%;">
<i>${caption}</i>
</p>`
    }
                    
    return output;
}

Concrete uses

Having made a generic (abstract) shortcode, I now want some specific codes based on typical image widths. My main content div is going to be a maximum 900 pixels wide, and I know I'll have some images that should be narrower on a large screen, so have written concrete versions for 300, 600 and 900-wide images.

... more

New site part 3 - individual posts

Part of a series about setting up the new 11ty version of this site

I'm going to do some (slightly) clever things with my collection of posts later, but first I need to work out how I'm going to write an individual page.

Collecting posts

I'll organise individual posts within my src/posts/ folder by year and month, but I want the permalink for each to only be based on the title of the post. I also want there to be "next post" / "last post" links for each individual post, so I need a unique layout.

So first thing to do is add a file posts.11tydata.js in my src/posts/ folder, which means I can set common front matter for all my posts:

... more

New site part 2 - styling

Part of a series about setting up the new 11ty version of this site

Having got the project structure sorted, we need to get a basic page layout sorted. But to do that we first need some more config and a starter layout that deals with the 'cookie-cutter' stuff.

Style and Sass

I prefer to write my styling in Sass (SCSS) rather than raw CSS. Unfortunately, 11ty doesn’t work with Sass out-of-the-tin (although there’s some example implementations in the docs).

I used to have a simple process, using a Nunjucks file to consolidate all my SCSS and then running it through a conversion filter in the build stage, but recently came across an article by Stephanie Eckles that removes the interim step.

... more

New site part 1 - basic setup

Part of a series about setting up the new 11ty version of this site

To get things started, a short post on how I set up my folder structure (and a little config to make it work properly).

(I'll build on the config file in later posts!)

Folder structure

My personal preference is to order things as follows:

... more