11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
17.21k stars 493 forks source link

Pagination doesn't see eleventyComputed value #2365

Open cawa-93 opened 2 years ago

cawa-93 commented 2 years ago

I'm trying to create a few pages that will display posts filtered by some tag. To do this, I created a shared layout that accepts an array of records. For example, the home page should display all posts with the tag "post".

index.njk

---js
{
  layout: "layouts/post-feed.njk",
  postTag: 'posts',
  eleventyComputed: {
    postCollection: (data) => data.collections.posts,
  }
}
---

However, I can not transfer data to pagination layouts/post-feed.njk

---
layout: layouts/base.njk
pagination:
  data: postCollection {# or "postCollection" or collections[postTag] or "collections[postTag]" #}
  alias: posts
  size: 2
  reverse: true
---
[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] Could not find pagination data, went looking for: postCollection (via Error)
[11ty]
[11ty] Original error stack trace: Error: Could not find pagination data, went looking for: postCollection
[11ty]     at Pagination._get (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\Plugins\Pagination.js:150:13)
[11ty]     at Pagination.setData (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\Plugins\Pagination.js:71:29)
[11ty]     at new Pagination (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\Plugins\Pagination.js:19:10)
[11ty]     at Template.getTemplates (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\Template.js:724:21)
[11ty]     at TemplateMap.initDependencyMap (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\TemplateMap.js:288:41)
[11ty]     at async TemplateMap.cache (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\TemplateMap.js:333:5)
[11ty]     at async TemplateWriter._createTemplateMap (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\TemplateWriter.js:244:5)
[11ty]     at async TemplateWriter.generateTemplates (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\TemplateWriter.js:277:5)
[11ty]     at async TemplateWriter.write (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\TemplateWriter.js:323:23)
[11ty]     at async Eleventy.executeBuild (C:\Users\kozac\Dev\it-ua-hub\node_modules\@11ty\eleventy\src\Eleventy.js:1003:13)
[11ty] Wrote 0 files in 0.24 seconds (v1.0.1)
pdehaan commented 2 years ago

Interesting, it seems to work if I hardcode the pagination.data to collections.posts in the layout file, but it really doesn't seem to like using eleventyComputed data for pagination.

---
layout: layouts/base.njk
pagination:
  data: collections.posts
  alias: posts
  size: 2
  reverse: true
coll:
    - data:
        title: one
    - data:
        title: TWo
    - data:
        title: three
eleventyComputed:
  coll2:
    - data:
        title: FOur
    - data:
        title: FIve
    - data:
        title: SIx
---

postTag={{ postTag }}
postCollection={{ postCollection }}
posts={{ posts }}

{% for post in posts %}
  <h2>{{ post.data.title | inspect | safe }}</h2>
{% endfor %}

Both data: collections.posts and data: coll seem to work fine. But as soon as I try using data: coll2 I get the following error:

[11ty] Could not find pagination data, went looking for: coll2 (via Error)
pdehaan commented 2 years ago

OK, I think I found a workaround (for Eleventy 1.0.1+). Looks like 1.0.1 added a second parameter to the before() callback, so now we can access both the paginationData and fullData cascade.

layouts/post-feed.njk

---js
{
  layout: "layouts/base.njk",
  pagination: {
    data: "collections.all",
    alias: "posts",
    size: 2,
    reverse: true,
    before(paginationData, fullData) {
      // Ignore the original pagination data set (`collections.all`) and
      // return the specified `collections[postTag]` items.
      return fullData.collections[fullData.postTag];
    }
  }
}
---

<h1>{{ postTag }} Archive</h1>

{% for post in posts %}
  <h2>{{ post.data.title }} -- {{ post.url }}</h2>
{% endfor %}

Now my /index.njk looks like this, which will paginate over all the collections.posts items:

---
layout: layouts/post-feed.njk
postTag: posts
---

And I can create a /blog.njk file which sets the postTag to "blog" and will paginate over all the collections.blog items:

---
layout: layouts/post-feed.njk
postTag: blog
---
zachleat commented 2 years ago

I think this is one of those pitfalls documented at the very top of the Computed Data feature: https://www.11ty.dev/docs/data-computed/

Computed Data happens after pagination.

However! I do think this is fixable for this specific use case! We could look at the pagination data property and see if it’s being set by computed data? So the options right now are either to use the workaround @pdehaan posted and/or put it into the enhancement queue for later.

alistairtweedie commented 2 years ago

I'm finding that from v2.0.0-canary.9 my Computed Data in paginated items are breaking. I wonder if this is connected? No errors in the console. Just not outputting in the html.

pagination: {
    data: "companies",
    size: 1,
    alias: "company"
},
eleventyComputed: {
    title: "{{ company.name | safe }}"
}

no title in the html.

v2.0.0-canary.8 is fine 👍

TigersWay commented 2 years ago

However! I do think this is fixable for this specific use case! We could look at the pagination data property and see if it’s being set by computed data? So the options right now are either to use the workaround @pdehaan posted and/or put it into the enhancement queue for later.

@zachleat, could you add this one to the 2.0.0 milestone? Or where could any vote for it? 😄