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

no index.html is generated at _site #2928

Closed
bsastregx opened this issue May 9, 2023 · 13 comments
Closed

no index.html is generated at _site #2928

bsastregx opened this issue May 9, 2023 · 13 comments

Comments

@bsastregx
Copy link

bsastregx commented May 9, 2023

Operating system

Windows 10

Eleventy

2.0.1

Describe the bug

Not sure if this is a bug.
I have the following index.njk at the root of my project:
(the nunjuck logic it doesn't really matter, I think, so don't waste time paying attention to it. Keep reading..)

---
pagination:
  data: collections.posts
  size: 3
  alias: posts
  reverse: true
---

<h1>Welcome!</h1>
<div class="card-grid">
  {%for post in posts%}
  <div class="card">
    <h3 class="card-title">
      <a href="{{ post.url | url }}">
        {{ post.data.title }}
      </a>
    </h3>
  </div>
  {%endfor%}
</div>

<div class="pagination">
  {% if pagination.previous %}
  <span>
    <a href="{{ pagination.href.previous | url }}" class="pagination__prev">
      &larr; Older Articles
    </a>
  </span>
  {%else %}
  <span class="pagination__item"> &larr; Older Articles </span>
  {%endif%} {% if pagination.next %}
  <span>
    <a href="{{ pagination.href.next | url }}" class="pagination__next">
      Newer Articles &larr;
    </a>
  </span>
  {%else %}
  <span class="pagination__item"> Newer Articles &larr;</span>
  {%endif%}
</div>

Then, I have four posts, at /posts:

  • post1.md
  • post2.md
  • post3.md
  • post4.md

They are all the same in structure, prety simple:

---
title: This is my first post
tags: posts
---

Hello, this is my first post.

When I build, _site/index.html displays the posts, everything working fine.
BUT, If I remove "posts" from "tags" in the front matter of every post (the four of them), and build, no index.html is generated under _site, and I have no errors. The end result is that when I go to the homepage, I get Cannot GET /

I think having no errors at all at the console, is PRETTY dangerous. Imagine that there is only one post left with "posts" tag in it, and I remove it, or change the tag for another one... then I will get an inexsitent index.html with no warning at all from eleventy.

Reproduction steps

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See an error

Expected behavior

I guess to have some kind of error in the console, since I am trying to do a loop of posts, and I have none.

Reproduction URL

No response

Screenshots

image
image
image

@bobmonsour
Copy link

I would suggest that it is not a bug, but is expected behavior. It appears that you're asking Eleventy to paginate a collection that is empty. As you note, the result is no output of the index.html file. Two things come to mind:

  1. It is something that you should idenfity in your testing of the site and then work to determine what is incorrect with the assumptions you're making about your code...or...

  2. Better yet, you could add some code to check that the collection is not empty and, if so, output an error message of your choosing. The place to do this would be in the "before" callback which is available as a feature of pagination. It allows the paginated data to be processed in whatever manner you choose prior to the pagination taking place. In your case, you could simply test the length of the collection being zero. If so, you could output an error to the console as the callback would in in javascript. Here's a link to the docs on the callback.

I hope this helps.

https://www.11ty.dev/docs/pagination/#the-before-callback

@pdehaan
Copy link
Contributor

pdehaan commented May 9, 2023

I agree that it's not a bug, but this is probably what you're looking for: https://www.11ty.dev/docs/pagination/#generating-an-empty-results-page

@bsastregx
Copy link
Author

bsastregx commented May 14, 2023

@bobmonsour Thanks for your reply.
I can agree with you that this is not strictly a bug, and I understand why the result is no output of the index.html file.
But consider this scenario:

  • I have a link on my global menu, that points to a page that displays paginated content from the collection "food". There are only 3 posts left with that tag.
  • Someone working on the team gets asked to remove the tag "food" from those three posts.
  • Now, because there is no collection, there is no page that displays "food" posts. No one knows.
  • We deploy _site to production, and the menu link that points to the page that previously displayed the collection of food posts, is inexistent. The user will get "Cannot GET". No hint in the terminal about this. Not good if you ask me.

Don't you think it would be better to have some kind of warning at least?

**Warning:** A collection for "food" was intended to be created at 'index.njk' but the length of the collection is 0. No pages were created.

I understand your suggestion about adding code to check that the collection is not empty and, if so, output an error message, and appreciate it. But to me, this behaivor should be included by default, without me having to add anything.

I appreacite if you can share and discuss my concern with the group on eleventy. I think my suggestion is pretty reasonable.
Thank you.

@pdehaan thank you. Having a 404 page is better that what I have right now, but anyway, links could be pointing to that page, that will end on a 404. Not good.

@pdehaan
Copy link
Contributor

pdehaan commented May 14, 2023

I agree that it's not a bug, but this is probably what you're looking for: 11ty.dev/docs/pagination/#generating-an-empty-results-page

Having a 404 page is better that what I have right now, but anyway, links could be pointing to that page, that will end on a 404. Not good.

The generatePageOnEmptyData: true will create a page so you don't get a 404.

---
# src/index.njk
title: Available Products
pagination:
  data: collections.posts
  size: 3
  alias: posts
  reverse: true
  generatePageOnEmptyData: true
---

{% if posts.length == 0 %}
  <h1>NO POSTS FOUND</h1>
{% else %}
  <div class="card-grid">
    {% for post in posts %}
      <div class="card">
        <header>
          <h1>{{ post.data.title}}</h1>
        </header>
      </div>
    {% endfor %}
  </div>
{% endif %}
// eleventy.config.js

/**
 * @param {import("@11ty/eleventy/src/UserConfig")} eleventyConfig
 * @returns {ReturnType<import("@11ty/eleventy/src/defaultConfig")>}
 */
module.exports = function (eleventyConfig) {
  // Create an empty collection.
  eleventyConfig.addCollection("posts", collectionApi => []);

  return {
    dir: {
      input: "src",
      output: "www",
    }
  };
};

OUTPUT

> eleventy

[11ty] Writing www/index.html from ./src/index.njk
[11ty] Wrote 1 file in 0.03 seconds (v2.0.1)
  <!-- www/index.html -->
  <h1>NO POSTS FOUND</h1>

If I comment out generatePageOnEmptyData: true in the YAML and rebuild, I get zero files written.

> eleventy

[11ty] Wrote 0 files in 0.02 seconds (v2.0.1)

Relevant PRs with more discussion/context are #2208 and #1698.

@bsastregx
Copy link
Author

@pdehaan Thank you very much. Really appreaciate your suggestion. I like that solution.
How did you manage to insert stylized colored code here?

@bobmonsour
Copy link

bobmonsour commented May 14, 2023 via email

@pdehaan
Copy link
Contributor

pdehaan commented May 14, 2023

@bobmonsour It's a very new API and actually the first time I've used it.

And your solution is still excellent and valid, and I 💯 dig the idea of using the before() callback to throw hard build errors on unexpected/invalid data. 😍

@uncenter
Copy link
Contributor

@pdehaan Thank you very much. Really appreaciate your suggestion. I like that solution. How did you manage to insert stylized colored code here?

You can just add a language after the three backticks like so:

```<language>
// your code here...
```

If you write this:

```js
console.log("Hello, world!")
```

It will look like this:

console.log("Hello, world!")

@bsastregx
Copy link
Author

@uncenter

console.log('Thank you!');

@bsastregx
Copy link
Author

bsastregx commented May 18, 2023

I would suggest that it is not a bug, but is expected behavior. It appears that you're asking Eleventy to paginate a collection that is empty. As you note, the result is no output of the index.html file. Two things come to mind:

  1. It is something that you should idenfity in your testing of the site and then work to determine what is incorrect with the assumptions you're making about your code...or...
  2. Better yet, you could add some code to check that the collection is not empty and, if so, output an error message of your choosing. The place to do this would be in the "before" callback which is available as a feature of pagination. It allows the paginated data to be processed in whatever manner you choose prior to the pagination taking place. In your case, you could simply test the length of the collection being zero. If so, you could output an error to the console as the callback would in in javascript. Here's a link to the docs on the callback.

I hope this helps.

https://www.11ty.dev/docs/pagination/#the-before-callback

@bobmonsour I also like your solution about outputing an error message if the collection is empty. However, I would like to make this a global rule/check, that would work for every collection that I currently have, or may have later. For that purpose, I think the place for verification would be eleventy.config.js. Is it possible to get access to the length of all collections items?

as an example:

foodCollection: ['food-1', 'food-2', 'food-3'];
catsCollection: ['cat-1', 'cat-2'];

collections.all.items.length => 5

@bsastregx bsastregx reopened this May 18, 2023
@pdehaan
Copy link
Contributor

pdehaan commented May 18, 2023

@bsastregx You could try overriding collections.all in your Eleventy config file and just assert a specific collection length, if you want.

+const assert = require("node:assert/strict");

/**
 * @param {import("@11ty/eleventy/src/UserConfig")} eleventyConfig
 * @returns {ReturnType<import("@11ty/eleventy/src/defaultConfig")>}
 */
module.exports = function (eleventyConfig) {
+  eleventyConfig.addCollection("all", function (collectionApi) {
+    const posts = collectionApi.getAllSorted();
+    assert.equal(posts.length, 5, "Unexpected number of pages");
+    return posts;
+  });

  return {
    dir: {
      input: "src",
      output: "www",
    }
  };
};

@bsastregx
Copy link
Author

@pdehaan Thank you! I will try that out later. I'm at the office right now.

@zachleat
Copy link
Member

This is an automated message to let you know that a helpful response was posted to your issue and for the health of the repository issue tracker the issue will be closed. This is to help alleviate issues hanging open waiting for a response from the original poster.

If the response works to solve your problem—great! But if you’re still having problems, do not let the issue’s closing deter you if you have additional questions! Post another comment and we will reopen the issue. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants