Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds html-relative Passthrough Copy mode for relative asset references in HTML #3552 #3573

Merged
merged 12 commits into from
Dec 11, 2024

Conversation

zachleat
Copy link
Member

@zachleat zachleat commented Dec 6, 2024

export default async function(eleventyConfig) {
	// glob here is relative to project root
	eleventyConfig.addPassthroughCopy("content/**/*.mp4", {
		mode: "html-relative"
	});
}

Works great with emulated passthrough copy, too: https://www.11ty.dev/docs/copy/#emulate-passthrough-copy-during-serve

Why (and why not) use this?

Compared with using eleventyConfig.addPassthroughCopy('content/**/*.mp4'),

HtmlRelativeCopy is better because:

  1. it handles relative URLs (and any customizations to permalink) seamlessly without requiring any changes to source content.
    • e.g. <video src="video.mp4"> on template.njk will copy to _site/template/video.mp4 alongside _site/template/index.html
    • e.g. <video src="assets/video.mp4"> on subdir/template.njk will copy to _site/subdir/template/assets/video.mp4 alongside _site/subdir/template/index.html
  2. only copies files that are used by templates.

HtmlRelativeCopy may be worse when:

  1. you aren’t using HTML if your template is not writing an HTML file in output
  2. the reference in your HTML is not found by @11ty/posthtml-urls: https://github.com/11ty/eleventy-posthtml-urls/blob/d3097f44868737627555ebec622b029d7c0b1ab3/lib/defaultOptions.js#L10-L35
  3. it has some build cost, this uses an opt-in posthtml transform (though you’re already feeling this cost if you use the InputPathToUrl, IdAttribute, or HTMLBase plugins)

Restrictions

Some other differences from the usual eleventyConfig.addPassthroughCopy:

  • dot files are filtered from html-relative copy by default (via the dot: false recursive-copy option)
  • source files must be in the current project directory.
  • URLs and any absolute paths are ignored (we may add support for absolute paths later, if folks want it)

Full options list

export default async function(eleventyConfig) {
	// glob or Array of globs to match for copy
	eleventyConfig.addPassthroughCopy("**/*.png", {
		mode: "auto",
		paths: [], // additional fallback directories to look for source files
		failOnError: true, // throw an error when a path matches (via `match`) but not found on file system
		copyOptions: { dot: false }, // `recursive-copy` copy options
	});
}

@darthmall
Copy link

I have a few questions:

First, in your example with <video src=video.mp4> writing out both _site/template/video.mp4 and _site/template/index.html, where does video.mp4 live? Does it need to live in content/template/video.mp4?

Second, why make this a plugin? I understand wanting to maintain backwards compatibility for the existing passthrough copy function, but couldn't you achieve that by adding options to the passthrough copy function with default values that result in the existing behavior? I feel like having two different ways to copy static assets is going to be a little confusing, especially if the idea is that the built-in one is the one with which people struggle, and the one people probably want because it's more efficient and convenient is a plugin you have to import and add. Personally, I also just find the built-in plugins annoying because it means I have to have extra import statements at the top of my config file for something that is included when I npm install @11ty/eleventy.

Third, when you say "AutoCopy may be worse when you're not using HTML", does that mean when I'm using Markdown?

@Ryuno-Ki
Copy link
Contributor

Ryuno-Ki commented Dec 7, 2024

Third, when you say "AutoCopy may be worse when you're not using HTML", does that mean when I'm using Markdown?

You can write to JSON also.

@zachleat
Copy link
Member Author

zachleat commented Dec 9, 2024

First, in your example with

Yep! Alternatively there is a paths feature to list directories that can be used as fallback search

Second, why make this a plugin?

Fair point! Let me think about it a bit—it might be more ergonomic to extend the eleventyConfig.addPassthroughCopy method instead!

Third, when you say "AutoCopy may be worse when you're not using HTML", does that mean when I'm using Markdown?

Anything that outputs to HTML is handled by this method (Markdown, Nunjucks, Liquid, 11ty.js, etc etc)! Updated the comment above: you aren’t using HTML your template output format is not .html

@zachleat
Copy link
Member Author

zachleat commented Dec 9, 2024

Per @darthmall’s excellent feedback I’ve reworked the API to use eleventyConfig.addPassthroughCopy(glob, { mode: "auto" }) (open to better naming feedback on mode: "auto" not sure if I’m super happy with that). Code samples above have been updated too.

I love this change, thanks for the idea Evan!

(Still open to feedback here!)

A few other naming ideas:

  • mode: "output-relative"
  • mode: "relative"
  • mode: "template-relative"

@wavebeem
Copy link

Per @darthmall’s excellent feedback I’ve reworked the API to use eleventyConfig.addPassthroughCopy(glob, { mode: "auto" }) (open to better naming feedback on mode: "auto" not sure if I’m super happy with that). Code samples above have been updated too.

I love this change, thanks for the idea Evan!

(Still open to feedback here!)

A few other naming ideas:

* `mode: "output-relative"`

* `mode: "relative"`

* `mode: "template-relative"`

I finally got around to testing this and had been banging my head on it for like 30 minutes before I thought to check back on this thread and see you're going in a different direction 😅

Couldn't figure out why AutoCopyPlugin was undefined.

"auto" isn't especially specific, and boxes in the API if you want to make a new style in the future (hopefully not, but you never know). The way I'm seeing this mode is... files are statically analyzed from HTML only, right? It feels like a name that reflects the static analysis of HTML might be good. The only issue I see is if you plan additional scanning features... 🤷🏻‍♀️

@zachleat zachleat changed the title Adds AutoCopy plugin #3552 Adds auto Passthrough Copy mode for relative asset references in HTML #3552 Dec 10, 2024
@zachleat zachleat changed the title Adds auto Passthrough Copy mode for relative asset references in HTML #3552 Adds html-relative Passthrough Copy mode for relative asset references in HTML #3552 Dec 11, 2024
@zachleat
Copy link
Member Author

Renaming this from AutoCopy to HtmlRelativeCopy (via mode: "html-relative"). Earlier comments edited to reflect new changes!

@zachleat
Copy link
Member Author

I finally got around to testing this and had been banging my head on it for like 30 minutes before I thought to check back on this thread and see you're going in a different direction 😅

Couldn't figure out why AutoCopyPlugin was undefined.

Oh no! I’m sorry!

"auto" isn't especially specific, and boxes in the API if you want to make a new style in the future (hopefully not, but you never know). The way I'm seeing this mode is... files are statically analyzed from HTML only, right? It feels like a name that reflects the static analysis of HTML might be good. The only issue I see is if you plan additional scanning features... 🤷🏻‍♀️

I took your suggestion and settled on the html-relative copy name—thanks for the feedback!

@zachleat
Copy link
Member Author

Shipping with v3.0.1-alpha.1

@zachleat zachleat merged commit 8bd3b97 into main Dec 11, 2024
20 checks passed
@zachleat zachleat deleted the auto-copy-plugin branch December 11, 2024 17:43
@zachleat zachleat added the needs-documentation Documentation for this issue/feature is pending! label Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-documentation Documentation for this issue/feature is pending!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants