Eleventy: Help: struggling to get Eleventy to work with my folder structure

Created on 15 Apr 2019  路  6Comments  路  Source: 11ty/eleventy

I want a folder structure like this:

.eleventy.js
_site
-- images
-- fonts
-- favicon.ico
-- index.html
src
-- assets
---- images
---- fonts
---- favicon.ico
-- content
---- index.md
  1. I want content to be the input directory.
  2. I want to pass through all the _contents_ of assets to _site/.

I鈥檝e got number 1, but I can鈥檛 figure out number 2.

Given my current configuration:

module.exports = eleventyConfig => {

    // Pass through static assets
    eleventyConfig.addPassthroughCopy('src/assets');

    return {
        // Input directory
        dir: {
            input: 'src/content'
        },
        passthroughFileCopy: true
    };

};

I get this:

.eleventy.js
_site
-- src
---- assets
------ images
------ fonts
------ favicon.ico
-- index.html
src
-- assets
---- images
---- fonts
---- favicon.ico
-- content
---- index.md

What can I do to get src/assets/* to copy to _site/*?

duplicate

Most helpful comment

I'd write it like this:

const files = [
  'src/fonts',
  'src/img',
  'src/favicon.ico',
  'src/apple-touch-1.png',
  'src/apple-touch-2.png',
  'src/apple-touch-3.png'
];
files.forEach((file) => eleventyConfig.addPassthroughCopy(file));

this way, you can apply some logic (e.g. fs.listdir) to assemble the files variable (perhaps in another file which gets imported here).

All 6 comments

@Ryuno-Ki That鈥檚 what I was thinking but @eleven_ty on Twitter suggested it was achievable with currently available features. So I鈥檓 wondering how. I've been perusing the docs but maybe I missed something.

https://twitter.com/eleven_ty/status/1117771160601669632

@zachleat anything I missed?

@blakewatson

Currently you can't map that folder's contents to the compiled _site/ root. (It'll always copy to _site/assets/ instead of copying its contents to _site/.)

Hopefully we'll be able to do this with #214 (and gain even more control over passthroughs). It would sure come in handy in many cases.

I'd suggest considering: (maybe these will spark some other ideas, too)

A. Use an npm package script to copy assets after build

Probably the quickest given your existing structure.

Something like:

// package.json
{
  "scripts": {
    "build": "npx eleventy && npm run assets:copy",
    "assets:copy": "cp -R src/assets/* _site/"
  }
}

Or use gulp or grunt to handle this, if you've already got them running for some other use.

B. Flatten the structure

This is what I do now, at least until passthrough supports globs.

config.dir = {
  input: 'src'
}

src
-- images
-- fonts
-- favicon.ico
-- index.md

BA. Then use addPassthroughCopy() explicity

Yeah, it's cumbersome. But it's also very explicit, which is good for figuring it out again in the future.

(I know you wanna keep it all nicely organized, but it's probably not worth the effort until passthroughs do support globs.)

eleventyConfig.addPassthroughCopy('src/fonts');
eleventyConfig.addPassthroughCopy('src/img');
eleventyConfig.addPassthroughCopy('src/favicon.ico');
eleventyConfig.addPassthroughCopy('src/apple-touch-1.png');
eleventyConfig.addPassthroughCopy('src/apple-touch-2.png');
eleventyConfig.addPassthroughCopy('src/apple-touch-3.png');

BB. Or configure templateFormats and passthroughFileCopy: true

You could try using templateFormats to add your assets' file extensions so you don't have to manually call addPassthroughCopy() for each one.

I tend to avoid this, since an image file really isn't a template IMHO. And I'd rather avoid unintentional side-effects in the future, especially months from now when I'm trying to figure out whatever magic I may have created.

BC. Or try using --passthroughall

You could bravely try the --passthroughall CLI flag. Note the potential security risks in the docs.

I'd write it like this:

const files = [
  'src/fonts',
  'src/img',
  'src/favicon.ico',
  'src/apple-touch-1.png',
  'src/apple-touch-2.png',
  'src/apple-touch-3.png'
];
files.forEach((file) => eleventyConfig.addPassthroughCopy(file));

this way, you can apply some logic (e.g. fs.listdir) to assemble the files variable (perhaps in another file which gets imported here).

Hey @blakewatson your second requirement there will be possible when @MadeByMike鈥檚 PR at #452 lands.

I鈥檓 going to close this as a duplicate of #214 (which is the root issue that #452 solves). Please follow along and upvote there!

Also thanks to everyone else for helping out here!

Was this page helpful?
0 / 5 - 0 ratings