eleventy icon indicating copy to clipboard operation
eleventy copied to clipboard

Allow plugins to transform frontmatter & pre-rendering content

Open surma opened this issue 5 years ago • 5 comments

Is your feature request related to a problem? Please describe. What prompted me to open this issue is the following scenario: I want to write a simple, Instagram-like gallery. I have a bunch of images and a .md file for each. The front matter only contains a path to the image and a description:

---
image: picture01.jpg
---
This image was taken with a camera.

I'd like to extract additional data from the JPG (like EXIF data for focal length, ISO, aperture etc) and put it in the front matter so the underlying layout can use that data.

Describe the solution you'd like Currently, addTransform adds a function that gets called after templating and everything is done. I think another hook before templating with access to both markup and parsed front matter would be helpful to implement this and many other features. Not sure what a good name for this hook is, though.

Describe alternatives you've considered I am currently doing it as a build script that runs before 11ty and augments the front matter. This is not very watch-able and doesn't scale well.

surma avatar Aug 07 '19 14:08 surma

Why not couple each .md file with a .js data file (using the same file name for the sake of convenience) and populate that data file with the properties you need using JavaScript function(s) -- which can require all Node modules you want? You can then access the data properties as usual in your template file.

octoxalis avatar Aug 09 '19 08:08 octoxalis

I ended up here, investigating an somewhat overlapping use case. Since there I see no other way I am wondering whether it is possible to write a plugin that transforms the frontmatter. I would read the content of a file specified in the frontmatter, which then would allow that information to trickle up the chain as part of the frontmatter into my base layout. See https://github.com/11ty/eleventy/issues/1112

tcurdt avatar Apr 25 '20 13:04 tcurdt

Look there to see what I can do inside any template processing, either before starting processing, or in the middle, or at the end.

octoxalis avatar Apr 27 '20 14:04 octoxalis

Not content related but this has some overlap with Eleventy’s new Computed Data feature. https://www.11ty.dev/docs/data-computed/

zachleat avatar Jul 07 '20 04:07 zachleat

Added a few examples to the docs for this use case, specifically using the data cascade to feed EXIF image data into it directly.

  • https://www.11ty.dev/docs/data-custom/#feed-exif-image-data-into-the-data-cascade
  • https://www.11ty.dev/docs/plugins/image/#process-images-as-data-files

Requires 2.0.0-canary.10

zachleat avatar May 11 '22 20:05 zachleat

Though I do think the https://www.11ty.dev/docs/data-custom/#feed-exif-image-data-into-the-data-cascade it doesn’t really solve the problem of having one markdown file that has multiple images as input.

It does make me wonder if we should extend the data cascade to data folders, similar to how global data operates but for specific directories or templates. Filed this at #2698

All that said, this is solvable pretty nicely mixing Computed Data with the Data Cascade:

image

Specifically this directory data file will apply to any template files in src/

const exifr = require("exifr");
const path = require("path");

module.exports = {
	eleventyComputed: {
		imageData: async function(data) {
			if(data.page.inputPath && data.image) {
				let {dir} = path.parse(data.page.inputPath);
				return exifr.parse(path.join(dir, data.image));
			}
			return {};
		}
	}
}

And feeds off of the image file name set in front matter.

This is working in 1.0 stable.

zachleat avatar Dec 16 '22 16:12 zachleat