Eleventy: Preprocessing Callback - Ignore Files? Ability to do "Draft" builds?

Created on 3 Aug 2018  路  17Comments  路  Source: 11ty/eleventy

Trying to identify if in .eleventy.js if there is a way to determine if I want to process a file or not.

I would love it if I can do the following for example -

Frontmatter

---
status: draft
---

# Test

.eleventy.js

module.exports = function(eleventyConfig) {
  eleventyConfig.ignoreFiles(function(file) {
    return (process.env.DRAFT === 'true') ? false : file.data.status === 'draft';
  });
};

NPM Scripts

"scripts": {
  "build": "DRAFT='true' eleventy --input=src --output=dist",
  "dev": "DRAFT='true' eleventy --input=src --output=dist --serve",
  "publish": "eleventy --input=src --output=dist"
}

This would allow the ability to not only setup draft or other conditions for publications, but even future date publications (check timestamp), ignore files to specific output targets - Example - api docs & frontend component docs could share a repo, but have two different build targets? Maybe they end up on different domains.

I tried looking through the code to see if I could add support for this, but I am a little unclear what determine what should render outside of the ignoreFiles which takes a full file path. So you would need to scan all files in a prestep to add it too that list running the function passed into the config.

enhancement favorite needs-votes

Most helpful comment

@edwardhorsford It isn't a JavaScript solution, but to achieve something similar I added this line to my .eleventyignore file:

**/_*.md

Now all drafts or templates prepended with an underscore (_e.g._ articles/_template.md) are ignored. To publish (or preview) them, remove the underscore.

EDIT: I ended up moving templates to _includes/templates/. The underscore still works well for drafts.

All 17 comments

Oh, I do like this. The ability to run a filter callback on the found files array before processing would have a lot of utility, I think.

Can you upvote your original post? This is going into the new feature queue

This repository is now using lodash style issue management for enhancements. This means enhancement issues will now be closed instead of leaving them open.

The enhancement backlog can be found here: https://github.com/11ty/eleventy/issues?utf8=%E2%9C%93&q=label%3Aneeds-votes+sort%3Areactions-%2B1-desc+

Don鈥檛 forget to upvote the top comment with 馃憤!

@zachleat - love that you adopted the lodash format. First time I am seeing the explanation. Makes perfect sense.

Sort of feel like this should be a GitHub plugin that handles this. Can't wait to see someone monetize the concept.

Really happy you like the concept. Is there anything short term that would make sense to do besides having a custom collection to build links that are not in draft, and crawling the output and remove pages that were listed in draft? Seems like more work than adding the initial feature, but I am struggling to wrap my head around how the code is organized, no offense.

I have a related need that this would help with...

I'd like to be able to have 'template' files in each of my directories that I can duplicate when I want to create a new post. They'd have standard front-matter applied so my posts are more consistent.

My current strategy is just to give them an extension eleventy doesn't recognise. But being able to mark them as drafts would be nicer.

@zachleat - what is the target vote count. We are currently sitting at 12...

Would love to see this feature make it into the next branch. For production we are currently taking the output, and then removing the files individually, and ensuring draft files are not listed as part of a collection to not show in the menu. Not ideal. =)

This is also high on my wish list. I've currently got a load of files sat uncommitted because I don't want them to get processed on production.

I've got a secondary use for this - I've made a stats page that lists every page that eleventy is processing and links to it. Also gives summaries of how many pages, how many tags, etc. Already it's helped me catch Eleventy outputting a load of files I wasn't expecting.

This is useful for dev, but obviously I don't want it rendered in prod.

@edwardhorsford - Stats page sounds really cool, would that be a good feature to "bake" into Eleventy? Would be nice to see a visual output for sure.

Patience, @khrome83 馃榾 It鈥檚 coming. Until then you can use permalink: false #61 in 0.5.4

Very excited for this feature.

@edwardhorsford It isn't a JavaScript solution, but to achieve something similar I added this line to my .eleventyignore file:

**/_*.md

Now all drafts or templates prepended with an underscore (_e.g._ articles/_template.md) are ignored. To publish (or preview) them, remove the underscore.

EDIT: I ended up moving templates to _includes/templates/. The underscore still works well for drafts.

@SeanMcP - I just manually added tags of the existing status. Draft, Staged, Relesed. Then I setup custom collections to pull the right data depending on the enviroment.

@khrome83 That's definitely a more powerful solution to the problem. Can you share those custom collections in a gist or something?

Since I'm doing something similiar with the toolbox on my website...

// .eleventy.js
function toolbox (collection) {
  const toolPages = collection.getFilteredByTag('tool');
  toolPages.sort((a, b) => {
    const titleA = a.data.title.toLowerCase();
    const titleB = b.data.title.toLowerCase();
    if (titleA < titleB) {
      return -1;
    }

    if (titleA > titleB) {
      return 1;
    }

    return 0;
  });
  return toolPages.filter((item) => item.data.tags.filter((tag) => tag !== 'tool').length > 0);
}

and on /public/projects/toolbox/tenon.md:

---
tags:
  - tool
  - accessibility
  - a11y
  - validator
  - service
layout: tool
title: 'tenon.io'
---
[Tenon.io](https://tenon.io/)

Finally, the template:

---
layout: h1
title: 'Toolbox'
---
<p>
Over the time, different handy websites and programs crossed my way.
</p>
<p>
In order to not to have to look them up again and again, I'm listing them here.
</p>
<div data-js="tag-filter"></div>
<ul class="toolbox">
  {% for tool in collections.toolbox %}
    <li class="tool" data-tags="{{ tool.data.tags | excludeItem('tool') | join(' ') }}">
      <p>
        <a href="{{ tool.url }}">
          {{ tool.data.title }}
        </a>
      </p>
      <p>
        Tagged with {{ tool.data.tags | excludeItem('tool') | sort | join(', ') }}
      </p>
    </li>
  {% endfor %}
</ul>

<script type="text/javascript" src="/js/toolbox.js"></script>

Is there any progress on this?

I'd really like to be able to tell Eleventy not to process a file on the basis of frontmatter and maybe a callback / function. If it's possible, please let me know how.

I've just discovered this is a significant cause in build times for my site.

A file that I thought I was ignoring because of permalink:false was in fact still getting processed, even if it didn't output anything.

Temporarily deleting the file just now, my build time went from 15 seconds all the way down to 8 seconds

Yep, similar.

I am investigating building a fairly chunky site (with a variety of collections) with Eleventy. Given there are two modes of use: writing content + checking it, vs production build - I've used an environment variable to determine whether to do a "full" or "light" build. That works well for most of my custom collections - I can shave nearly 90s off the build time if I don't even generate those collections.

However, I can't shave down the 'default' collection, nor the 'all tags' collection. Actually deleting my "all posts with a tag" paginated template, tag.njk, knocks 9s off my build time, down from 29 to 20; at this point, the only thing left being built is ~3000 individual pages. Of course, ideally, being able to programmatically ignore certain files - say, everything but the last year of content - would bring that up a _lot_, which is really handy for a) development and b) content-writing.

It looks like the bottleneck is at the point of the 'default' collections, and what gets passed into them; a code-based way of throttling that would be useful.

Was this page helpful?
0 / 5 - 0 ratings