Eleventy: Using a parent directory for layouts or includes ignores all templates

Created on 9 Mar 2020  Β·  6Comments  Β·  Source: 11ty/eleventy

Describe the issue
I'm losing my mind trying to figure out why 11ty can't find my template files. I know I did something really stupid and will feel dumb for posting this. But look!

To reproduce:
_.eleventy.js_

module.exports = (eleventyConfig) => {

  eleventyConfig.dir = {
    input: 'src/pages',
    output: 'dist',
    layouts: '..',
  };

  eleventyConfig.templateFormats = [
    'ejs', 'md',
    'jpg', 'png', 'ico', 'svg',
    'css',
    'txt',
  ];

  return eleventyConfig;
};

Debugging output:

$ DEBUG=Eleventy* npx @11ty/eleventy
...
Eleventy:EleventyFiles Searching for: [ './src/pages/**/*.ejs', './src/pages/**/*.md', './src/pages/**/*.jpg', './src/pages/**/*.png', './src
/pages/**/*.ico', './src/pages/**/*.svg', './src/pages/**/*.css', './src/pages/**/*.txt', '!./node_modules/**', '!./dist/**', '!./src/pages/_in
cludes/**', '!./src/**', '!./src/pages/_data/**' ] +30ms
  Eleventy:TemplateWriter Found: [] +0ms
...

Found: [], how dare you?

$ ls ./src/pages/**/*.ejs
./src/pages/index.ejs # It's right there, brah; first place you "looked"

Expected behavior
11ty looks harder for its template, finds it, and then apologizes to me for ever arguing that it wasn't there.

Environment:

  • OS and Version: Linux Ubuntu 18.04.4
  • Eleventy Version: 0.10.0
lite

Most helpful comment

@paulshryock That would work but won't that serve index.html at /pages instead of the doc root?

@keith24, it doesn't need to. You can give your pages a Permalink which determines where they will be built to. A simple way to do this would be with a Directory Data File.

Try adding { "permalink": "./{{ slug }}/index.html" } to pages/pages.json to configure a permalink for all of the templates inside of pages/*. Then each page can have a unique slug in its front matter, which determines where it's built.

For example:

  • src/pages/home.md:

    ---
    slug: .
    ---
    

    This gets output to dist/index.html.

  • src/pages/about.md:

    ---
    slug: about
    ---
    

    This gets output to dist/about/index.html.

Why?

The reason I suggest this approach is so that your Eleventy input directory can be src, which prevents you from being locked in to src/pages.

Maybe later you'll want to have articles in src/articles, or testimonials in src/testimonials. This approach lets you control permalinks with Directory Data Files, (or anywhere in the Data Cascade that makes sense), and then have all your content (of various content types) inside src without needing to escape any directories, or lock everything into a subdirectory like src/pages.

Example directory structure:

./
β”œβ”€β”€ .eleventy.js
β”œβ”€β”€ package.json
β”‚
β”œβ”€β”€ dist/
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ about/index.html
β”‚   β”œβ”€β”€ contact/index.html
β”‚   └── hello-world/index.html
β”‚
└── src/
    β”œβ”€β”€ _includes/
    β”œβ”€β”€ _layouts/
    β”œβ”€β”€ pages/
    β”‚   β”œβ”€β”€ about.md
    β”‚   β”œβ”€β”€ contact.md
    β”‚   └── home.md
    └── articles/
        └── hello-world.md

_(This assumes you've also added { "permalink": "./{{ slug }}/index.html" } to articles/articles.json, and given a slug of hello-world to the article.)_

All 6 comments

I got this to work, but I had to move my layouts into the "src/_layouts" directory, as setting the layout path to ".." wasnt working for me.

https://www.11ty.dev/docs/config/#template-formats

module.exports = (eleventyConfig) => {
  eleventyConfig.setTemplateFormats([
    'ejs', 'md',
    'jpg', 'png', 'ico', 'svg',
    'css',
    'txt',
  ]);

  return {
    dir: {
      input: 'src/pages',
      output: 'dist',
      layouts: '../_layouts',
    }
  };
};

Where my directories look like:

tree ./ -a
./
β”œβ”€β”€ .eleventy.js
β”œβ”€β”€ package-lock.json
β”œβ”€β”€ package.json
β”‚
β”œβ”€β”€ dist/
β”‚Β Β  └── index.html
β”‚
└── src/
    β”œβ”€β”€ _layouts/
    β”‚Β Β  └── base.ejs
    └── pages/
        └── index.ejs

4 directories, 6 files

Yeah we ignore the layouts folder by default. That’s where the '!./src/**', is coming from in @keith24’s original comment. We could probably make this better/smarter/faster

Why not just use src for the input directory? Then you don't need to ../ out of it to find layouts.

eleventyConfig.dir = {
  input: 'src',
  layouts: `_layouts`
  // ...
};

@paulshryock That would work but won't that serve index.html at /pages instead of the doc root?

I'm going with @pdehaan's workaround for now but I agree with @zachleat that putting layouts in .. should probably be possible.

@paulshryock That would work but won't that serve index.html at /pages instead of the doc root?

@keith24, it doesn't need to. You can give your pages a Permalink which determines where they will be built to. A simple way to do this would be with a Directory Data File.

Try adding { "permalink": "./{{ slug }}/index.html" } to pages/pages.json to configure a permalink for all of the templates inside of pages/*. Then each page can have a unique slug in its front matter, which determines where it's built.

For example:

  • src/pages/home.md:

    ---
    slug: .
    ---
    

    This gets output to dist/index.html.

  • src/pages/about.md:

    ---
    slug: about
    ---
    

    This gets output to dist/about/index.html.

Why?

The reason I suggest this approach is so that your Eleventy input directory can be src, which prevents you from being locked in to src/pages.

Maybe later you'll want to have articles in src/articles, or testimonials in src/testimonials. This approach lets you control permalinks with Directory Data Files, (or anywhere in the Data Cascade that makes sense), and then have all your content (of various content types) inside src without needing to escape any directories, or lock everything into a subdirectory like src/pages.

Example directory structure:

./
β”œβ”€β”€ .eleventy.js
β”œβ”€β”€ package.json
β”‚
β”œβ”€β”€ dist/
β”‚   β”œβ”€β”€ index.html
β”‚   β”œβ”€β”€ about/index.html
β”‚   β”œβ”€β”€ contact/index.html
β”‚   └── hello-world/index.html
β”‚
└── src/
    β”œβ”€β”€ _includes/
    β”œβ”€β”€ _layouts/
    β”œβ”€β”€ pages/
    β”‚   β”œβ”€β”€ about.md
    β”‚   β”œβ”€β”€ contact.md
    β”‚   └── home.md
    └── articles/
        └── hello-world.md

_(This assumes you've also added { "permalink": "./{{ slug }}/index.html" } to articles/articles.json, and given a slug of hello-world to the article.)_

Oh yeah, I didn't think of that!

I don't plan on ever having more than a dozen pages, so I'm just throwing permalink:s in the front matter.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

proog picture proog  Β·  3Comments

smaimon picture smaimon  Β·  3Comments

zachleat picture zachleat  Β·  3Comments

jamrelian picture jamrelian  Β·  3Comments

nilsmielke picture nilsmielke  Β·  4Comments