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

RFC: Eleventy’s directories should always be root-relative #232

Closed
kleinfreund opened this issue Sep 16, 2018 · 14 comments
Closed

RFC: Eleventy’s directories should always be root-relative #232

kleinfreund opened this issue Sep 16, 2018 · 14 comments
Labels
needs-discussion Please leave your opinion! This request is open for feedback from devs.

Comments

@kleinfreund
Copy link
Contributor

kleinfreund commented Sep 16, 2018

TL;DR: Should Eleventy’s includes and data directories be relative to the input directory (i.e. dir.input) or to the project root?


References:

Background

Currently, the directories dir.includes and dir.data are relative to dir.input.

In my opinion, this overcomplicates matters. I’m not able to include files from arbitrary directories. Examples:

  • Inline CSS (or JS) files in dir.input/css. Currently, this requires either moving /css into dir.input/dir.includes or making the includes directory the same as the input directory by setting dir.includes to "".
  • Include file contents from an independent build step. Currently, one would need to alter that build step to output files to dir.input/dir.includes.

I want to hear some use cases for nesting the directories like this. I’m opinionated towards one side here, obviously, so I’m likely to miss advantages of the current behavior. Please help me gather some advantages and disadvantages.

Compatibility

Changing the current behavior would be a huge breaking change. Simply switching the default behavior is not possible at this point.

If this behavior should ever be changed, the transitioning period could be implemented by assigning priorities to the different evaluation behaviors. An example:

Project file structure:

project-root/
├─ _data/
├─ src/
│  └─ _includes
└─ .eleventy.js

.eleventy.js:

module.exports = function () {
  return {
    dir: {
      input: 'src',
      includes: '_includes',
      data: '_data'
    }
  };
};

Path evaluation algorithm:

  1. Let eleventyDirectoryPath be the directory to evaluate.

  2. Does eleventyDirectoryPath exist in dir.input?

    If yes, append eleventyDirectoryPath to dir.input. Done.

  3. Does eleventyDirectoryPath exist in the project root directory?

    If yes, append eleventyDirectoryPath to the project root directory. Done.

    If no, throw an error. eleventyDirectoryPath is invalid.

Example:

dir.includes:

  • Step 1. eleventyDirectoryPath is set to _includes.
  • Step 2. _includes exists within project-root/src. dir.includes will be computed as project-root/src/_includes. Done.

dir.data:

  • Step 1. eleventyDirectoryPath is set to _data.
  • Step 2. _data does not exist within project-root/src.
  • Step 3. _data exists within project-root. dir.data will be computed as project-root/src/_data. Done.

This would allow users to opt-in to the new behavior without breaking the default behavior for existing users. If the current behavior should ever be deprecated, the priority can be reversed as a second transition step, effectively making the current behavior an opt-in feature.

@edwardhorsford
Copy link
Contributor

edwardhorsford commented Sep 16, 2018

I've struggled with the default setup / directory structure and think the discussion is wider than #67. It might be worth reopening for a general thread on directory structure.

Off hand, it also relates to #229 and #228. Possibly also #214 which confused me.


Edit: Like you, my view is that most things should be repo-root relative. I'd prefer to keep assets, templates, content (posts), data all in their own folders at the same level. At the moment some have to be one level deeper due to what Eleventy considers 'input'. I'd then expect most config things (.gitignore, .eleventyignore) in the project root.

It's a breaking change, but I think the current setup is likely to cause others to trip up in the future.

@zachleat
Copy link
Member

zachleat commented Sep 16, 2018

Hmm, I’m going to reopen this. I think #67 is related but more focused than this. I think it’d be useful to have a wider-scoped discussion here and leave #67 in the new feature queue.

@zachleat zachleat reopened this Sep 16, 2018
@zachleat zachleat added the needs-discussion Please leave your opinion! This request is open for feedback from devs. label Sep 16, 2018
@jevets
Copy link

jevets commented Sep 20, 2018

I agree; would love to be able to (optionally) define all paths explicitly relative to the repo root.

Maybe just check for root-relative paths in dir using a leading slash as demarcator?
Leave the defaults as they currently are to avoid breaking changes, making this behavior opt-in only.

dir: {
  input: '/src',
  data: '/_data',
  includes: '_includes', // no leading slash, assumes `${dir.input}/_includes`
}

Which would work for:

project-root/
├─ _data/
├─ src/
│  └─ _includes
└─ .eleventy.js

Maybe also worth considering: allow multiple _includes paths as an array.

dir: {
  includes: [
    '/some-package/custom-template-overrides',
    '/some-other-arbitrary-directory',
    '/src/_includes',
  ]
}

@kleinfreund
Copy link
Contributor Author

I don’t think a leading slash should be used to stand for Eleventy’s root directory. On an operating system-level, the slash usually represents the root directory of the file system. I don’t think it’s necessary to borrow the slash for a different concept here.

@coolshaurya
Copy link

What about a true/false toggle ?

Something like the following in .eleventy.js -

{
  ...

  dir:{
    ...
    evaluateFromRoot: false //this will be false by default
  }

...
}

@kleinfreund
Copy link
Contributor Author

I don’t want this to be configurable. In my opinion, there should be one clear way how Eleventy handles its special directories eventually.

@edwardhorsford
Copy link
Contributor

I don’t want this to be configurable. In my opinion, there should be one clear way how Eleventy handles its special directories eventually.

Strong agree. If we can avoid adding complexity, we should.

Might be a breaking change, but that's why projects use semver.

@kleinfreund
Copy link
Contributor Author

Might be a breaking change, but that's why projects use semver.

And as shown in the original post, the change can be introduced incrementally to ensure as little breakage as possible.

@paulrobertlloyd
Copy link
Contributor

👍 for having all directories be root-relative. Personally, I wouldn’t be too concerned if this was a breaking change, as long as versioning and documentation sufficiently highlighted that fact. After all, this change should only require updating a few lines in the config file.

@kleinfreund
Copy link
Contributor Author

After all, this change should only require updating a few lines in the config file.

Not quite. In content and/or data files, either the references to layout templates would need to be updated or the location of the layout templates needs to be moved accordingly.

@paulrobertlloyd
Copy link
Contributor

Are references to layout templates not relative to the includes directory? Of course there could be files outside the remit of 11ty that may need updating (styles, scripts etc.), but I thought anything relating to 11ty shouldn’t be effected once paths in the configuration file had been updated.

@kleinfreund
Copy link
Contributor Author

@paulrobertlloyd Indeed, they are. What I wrote above is wrong. Maybe I had something different in mind, but I can’t think of it right now.

@itlackey
Copy link

While trying to configure my folder structure I came across some odd behavior. I can use "../../theme" as my include path but if I use "../../data" as my data path it never loads the data. So it appears that include allows for parent directory paths and the data property does not. This leads me to believe that if both supported "../" then it would be possible to move your data and include folders to the root. Does that sound correct? Also, can anyone explain the different behaviors?

Thanks!

@itlackey
Copy link

Err.. my bad. After further debugging I found that the ../data path works but it assigns it to a different name:

Eleventy:TemplateData Found global data file ./src/data/config.json and adding as: src.data.config +0ms

This makes sense, I just had not thought about it. So for me this solves the problem of folder structure though it is certainly not the cleanest solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-discussion Please leave your opinion! This request is open for feedback from devs.
Projects
None yet
Development

No branches or pull requests

7 participants