Repository: 11ty/eleventy (js)

Issue:
eleventyComputed not working after 2.0.0-canary.8 
I've just upgraded to 2.0.0-canary.14 from 1.0.1. Almost everything worked great except my tag page.

```
---
pagination:
  data: collections
  size: 1
  alias: tag
permalink: /tag/{{ tag | slug }}/index.html
eleventyComputed:
  title: "{{ tag | title }}"
---
<header class="tag">
  <h1>{{ title }}</h1>
</header>
```
I use `eleventyComputed` and a filter to recondition the lowercase tags into something more readable. I do it here so I can use it in the `<title>` tag and OG metadata, as well as on the page.

After upgrading, this doesn't work. `title` is just empty. I've seen [a post on another bug](https://github.com/11ty/eleventy/issues/2365#issuecomment-1127682094) suggesting this crept in 2.0.0-canary.9 but I can't see anybody else having this problem.

Pull request:
Fix pagination and eleventy computed for `.njk` engine
closes #2512, #2837, #3013

## Introduction

Hi, I hope you are well.

There is a problem where if you use a Nunjucks and a template file like

```njk
---
layout: base
pagination:
  data: books
  size: 1
  alias: book
permalink: /{{ book.shortname }}/
eleventyComputed:
  title: "{{ book.name }}"
---
{{ title }}
```

All `eleventyComputed` variables are blank. See #2512, #2837, #3013 for discussion.

This problem was introduced by https://github.com/11ty/eleventy/commit/c6158b0fc3f3bd675adf6b8bec1be89828120bfb, a commit between `2.0.0-canary.8` and `2.0.0-canary.9`.

## New test

I have added a test which fails:

https://github.com/alifeee/eleventy/blob/301d2c09d76a6bc717a0a8ceda37a1bdb7cdbb42/test/PaginationTest.js#L833-L863

here is a simplification (in the actual test, it tests all templating languages)

```jsonc
// ./_data/books.json
[
    {
        "id": 1,
        "name": "The Effervescent adventures of Paul Mescal",
        "shortname": "paul-mescal"
    }
]
```

```njk
{{! ./_includes/base.njk }}
---
title: Books
---
<title>{{ title }}</title>
```

```njk
{{! ./book.njk }}
---
layout: base
pagination:
  data: books
  size: 1
  alias: book
eleventyComputed:
  title: "{{ book.name }}"
---
```

```js
// PaginationTest.js
test("Pagination and eleventyComputed data, issues #2512, #2837, #3013", async (t) => {
  let elev = new Eleventy(`./test/stubs-3013/njk/`, `./test/stubs-3013/njk/_site`, {
      source: "cli",
      runMode: "build",
    });
    await elev.init();
    let written = await elev.toJSON();

    t.is(written[0].content, "<title>The Effervescent adventures of Paul Mescal</title>");
});
```

### Result

This test [failed](https://github.com/alifeee/eleventy/actions/runs/7159002915)

![image](https://github.com/11ty/eleventy/assets/13833017/325141ca-000b-4b47-b75c-5be790002a3d)

## The fix

I spent some time commiting https://github.com/11ty/eleventy/commit/c6158b0fc3f3bd675adf6b8bec1be89828120bfb bit-by-bit and the fix i discovered was [this](https://github.com/alifeee/eleventy/commit/301d2c09d76a6bc717a0a8ceda37a1bdb7cdbb42):

```diff
- // set(target, prop, value) {
- //  return Reflect.set(target, prop, value);
- // }
+ set(target, prop, value) {
+   return Reflect.set(target, prop, value);
+  }
```

I am not fully sure why this is the fix, but I think it is to do with being able to set the `data.eleventyComputed` on a Proxy object.

If you re-add [this removed code](https://github.com/11ty/eleventy/commit/c6158b0fc3f3bd675adf6b8bec1be89828120bfb#diff-3474a01da03b1df2f715477d31a8f3a01abcd3abe630a6b961e914999a04d8e2L677-L680) from https://github.com/11ty/eleventy/commit/c6158b0fc3f3bd675adf6b8bec1be89828120bfb, then, compiling a template complains as the object cannot be assigned unless `set` exists as a property above. Thus, this is the fix I implemented with https://github.com/alifeee/eleventy/commit/301d2c09d76a6bc717a0a8ceda37a1bdb7cdbb42

And now the test [passes](https://github.com/alifeee/eleventy/actions/runs/7159023981)

Thank you for your time. I hope this is the correct branch to target with this change.

Patch:
diff --git a/src/Util/ProxyWrap.js b/src/Util/ProxyWrap.js
index 66c9a283..5ea9b562 100644
--- a/src/Util/ProxyWrap.js
+++ b/src/Util/ProxyWrap.js
@@ -19,10 +19,7 @@ function wrapObject(target, fallback) {
     // Nunjucks needs this
     ownKeys(target) {
       // unique
-      let keys = new Set([
-        ...Reflect.ownKeys(target),
-        ...Reflect.ownKeys(fallback),
-      ]);
+      let keys = new Set([...Reflect.ownKeys(target), ...Reflect.ownKeys(fallback)]);
       // console.log( "handler:ownKeys", keys );
       return Array.from(keys);
     },
@@ -38,18 +35,16 @@ function wrapObject(target, fallback) {
 
       return fallback[prop];
     },
-    // set(target, prop, value) {
-    //   console.log( "handler:set", prop, value );
-    //   return Reflect.set(target, prop, value);
-    // }
+    set(target, prop, value) {
+      // console.log( "handler:set", prop, value );
+      return Reflect.set(target, prop, value);
+    },
   });
 }
 
 function ProxyWrap(target, fallback) {
   if (!isPlainObject(target) || !isPlainObject(fallback)) {
-    throw new Error(
-      "ProxyWrap expects objects for both the target and fallback"
-    );
+    throw new Error("ProxyWrap expects objects for both the target and fallback");
   }
   let wrapped = wrapObject(target, fallback);
   return wrapped;


Test patch:
diff --git a/test/PaginationTest.js b/test/PaginationTest.js
index c5b29750..082feb9e 100644
--- a/test/PaginationTest.js
+++ b/test/PaginationTest.js
@@ -3,6 +3,7 @@ const TemplateData = require("../src/TemplateData");
 const Pagination = require("../src/Plugins/Pagination");
 const TemplateConfig = require("../src/TemplateConfig");
 const FileSystemSearch = require("../src/FileSystemSearch");
+const Eleventy = require("../src/Eleventy");
 
 const getNewTemplate = require("./_getNewTemplateForTests");
 const getRenderedTmpls = require("./_getRenderedTemplates");
@@ -828,3 +829,35 @@ test("Pagination and eleventyComputed permalink, issue #1555 and #1865", async (
   t.is(templates[1].data.page.url, "/venues/second/");
   t.is(templates[2].data.page.url, "/venues/third/");
 });
+
+test("Pagination and eleventyComputed data, issues #2512, #2837, #3013", async (t) => {
+  let templateLangs = ["liquid", "html", "md", "hbs", "mustache", "njk"];
+  let apostrophe = {
+    liquid: "'",
+    html: "'",
+    md: "'",
+    hbs: "&amp;#x27;",
+    mustache: "&amp;#39;",
+    njk: "&amp;#39;",
+  };
+  for (let lang of templateLangs) {
+    let msg = `lang: ${lang}`;
+    let le = lang === "md" ? "\n" : "";
+
+    let elev = new Eleventy(`./test/stubs-3013/${lang}/`, `./test/stubs-3013/${lang}/_site`, {
+      source: "cli",
+      runMode: "build",
+    });
+    await elev.init();
+    let written = await elev.toJSON();
+
+    t.is(written[0].url, "/paul-mescal/", msg);
+    t.is(written[0].content, `<title>The Effervescent adventures of Paul Mescal</title>${le}`, msg);
+    t.is(written[1].url, "/populace-and-power/", msg);
+    t.is(
+      written[1].content,
+      `<title>Populace and Power: A user${apostrophe[lang]}s guide</title>${le}`,
+      msg
+    );
+  }
+});
diff --git a/test/stubs-3013/hbs/_data/books.json b/test/stubs-3013/hbs/_data/books.json
new file mode 100644
index 00000000..16599da7
--- /dev/null
+++ b/test/stubs-3013/hbs/_data/books.json
@@ -0,0 +1,12 @@
+[
+    {
+        "id": 1,
+        "name": "The Effervescent adventures of Paul Mescal",
+        "shortname": "paul-mescal"
+    },
+    {
+        "id": 2,
+        "name": "Populace and Power: A user's guide",
+        "shortname": "populace-and-power"
+    }
+]
\ No newline at end of file
diff --git a/test/stubs-3013/hbs/_includes/base.hbs b/test/stubs-3013/hbs/_includes/base.hbs
new file mode 100644
index 00000000..4d87311e
--- /dev/null
+++ b/test/stubs-3013/hbs/_includes/base.hbs
@@ -0,0 +1,4 @@
+---
+title: Books
+---
+<title>{{ title }}</title>
\ No newline at end of file
diff --git a/test/stubs-3013/hbs/book.hbs b/test/stubs-3013/hbs/book.hbs
new file mode 100644
index 00000000..18804ac7
--- /dev/null
+++ b/test/stubs-3013/hbs/book.hbs
@@ -0,0 +1,11 @@
+---
+layout: base
+pagination:
+  data: books
+  size: 1
+  alias: book
+permalink: /{{ book.shortname }}/
+eleventyComputed:
+  title: "{{ book.name }}"
+---
+{{ title }}
\ No newline at end of file
diff --git a/test/stubs-3013/html/_data/books.json b/test/stubs-3013/html/_data/books.json
new file mode 100644
index 00000000..16599da7
--- /dev/null
+++ b/test/stubs-3013/html/_data/books.json
@@ -0,0 +1,12 @@
+[
+    {
+        "id": 1,
+        "name": "The Effervescent adventures of Paul Mescal",
+        "shortname": "paul-mescal"
+    },
+    {
+        "id": 2,
+        "name": "Populace and Power: A user's guide",
+        "shortname": "populace-and-power"
+    }
+]
\ No newline at end of file
diff --git a/test/stubs-3013/html/_includes/base.html b/test/stubs-3013/html/_includes/base.html
new file mode 100644
index 00000000..4d87311e
--- /dev/null
+++ b/test/stubs-3013/html/_includes/base.html
@@ -0,0 +1,4 @@
+---
+title: Books
+---
+<title>{{ title }}</title>
\ No newline at end of file
diff --git a/test/stubs-3013/html/book.html b/test/stubs-3013/html/book.html
new file mode 100644
index 00000000..18804ac7
--- /dev/null
+++ b/test/stubs-3013/html/book.html
@@ -0,0 +1,11 @@
+---
+layout: base
+pagination:
+  data: books
+  size: 1
+  alias: book
+permalink: /{{ book.shortname }}/
+eleventyComputed:
+  title: "{{ book.name }}"
+---
+{{ title }}
\ No newline at end of file
diff --git a/test/stubs-3013/liquid/_data/books.json b/test/stubs-3013/liquid/_data/books.json
new file mode 100644
index 00000000..16599da7
--- /dev/null
+++ b/test/stubs-3013/liquid/_data/books.json
@@ -0,0 +1,12 @@
+[
+    {
+        "id": 1,
+        "name": "The Effervescent adventures of Paul Mescal",
+        "shortname": "paul-mescal"
+    },
+    {
+        "id": 2,
+        "name": "Populace and Power: A user's guide",
+        "shortname": "populace-and-power"
+    }
+]
\ No newline at end of file
diff --git a/test/stubs-3013/liquid/_includes/base.liquid b/test/stubs-3013/liquid/_includes/base.liquid
new file mode 100644
index 00000000..4d87311e
--- /dev/null
+++ b/test/stubs-3013/liquid/_includes/base.liquid
@@ -0,0 +1,4 @@
+---
+title: Books
+---
+<title>{{ title }}</title>
\ No newline at end of file
diff --git a/test/stubs-3013/liquid/book.liquid b/test/stubs-3013/liquid/book.liquid
new file mode 100644
index 00000000..18804ac7
--- /dev/null
+++ b/test/stubs-3013/liquid/book.liquid
@@ -0,0 +1,11 @@
+---
+layout: base
+pagination:
+  data: books
+  size: 1
+  alias: book
+permalink: /{{ book.shortname }}/
+eleventyComputed:
+  title: "{{ book.name }}"
+---
+{{ title }}
\ No newline at end of file
diff --git a/test/stubs-3013/md/_data/books.json b/test/stubs-3013/md/_data/books.json
new file mode 100644
index 00000000..16599da7
--- /dev/null
+++ b/test/stubs-3013/md/_data/books.json
@@ -0,0 +1,12 @@
+[
+    {
+        "id": 1,
+        "name": "The Effervescent adventures of Paul Mescal",
+        "shortname": "paul-mescal"
+    },
+    {
+        "id": 2,
+        "name": "Populace and Power: A user's guide",
+        "shortname": "populace-and-power"
+    }
+]
\ No newline at end of file
diff --git a/test/stubs-3013/md/_includes/base.md b/test/stubs-3013/md/_includes/base.md
new file mode 100644
index 00000000..894be630
--- /dev/null
+++ b/test/stubs-3013/md/_includes/base.md
@@ -0,0 +1,5 @@
+---
+title: Books
+---
+
+<title>{{ title }}</title>
diff --git a/test/stubs-3013/md/book.md b/test/stubs-3013/md/book.md
new file mode 100644
index 00000000..b59ca102
--- /dev/null
+++ b/test/stubs-3013/md/book.md
@@ -0,0 +1,12 @@
+---
+layout: base
+pagination:
+  data: books
+  size: 1
+  alias: book
+permalink: /{{ book.shortname }}/
+eleventyComputed:
+  title: "{{ book.name }}"
+---
+
+{{ title }}
diff --git a/test/stubs-3013/mustache/_data/books.json b/test/stubs-3013/mustache/_data/books.json
new file mode 100644
index 00000000..16599da7
--- /dev/null
+++ b/test/stubs-3013/mustache/_data/books.json
@@ -0,0 +1,12 @@
+[
+    {
+        "id": 1,
+        "name": "The Effervescent adventures of Paul Mescal",
+        "shortname": "paul-mescal"
+    },
+    {
+        "id": 2,
+        "name": "Populace and Power: A user's guide",
+        "shortname": "populace-and-power"
+    }
+]
\ No newline at end of file
diff --git a/test/stubs-3013/mustache/_includes/base.mustache b/test/stubs-3013/mustache/_includes/base.mustache
new file mode 100644
index 00000000..4d87311e
--- /dev/null
+++ b/test/stubs-3013/mustache/_includes/base.mustache
@@ -0,0 +1,4 @@
+---
+title: Books
+---
+<title>{{ title }}</title>
\ No newline at end of file
diff --git a/test/stubs-3013/mustache/book.mustache b/test/stubs-3013/mustache/book.mustache
new file mode 100644
index 00000000..18804ac7
--- /dev/null
+++ b/test/stubs-3013/mustache/book.mustache
@@ -0,0 +1,11 @@
+---
+layout: base
+pagination:
+  data: books
+  size: 1
+  alias: book
+permalink: /{{ book.shortname }}/
+eleventyComputed:
+  title: "{{ book.name }}"
+---
+{{ title }}
\ No newline at end of file
diff --git a/test/stubs-3013/njk/_data/books.json b/test/stubs-3013/njk/_data/books.json
new file mode 100644
index 00000000..16599da7
--- /dev/null
+++ b/test/stubs-3013/njk/_data/books.json
@@ -0,0 +1,12 @@
+[
+    {
+        "id": 1,
+        "name": "The Effervescent adventures of Paul Mescal",
+        "shortname": "paul-mescal"
+    },
+    {
+        "id": 2,
+        "name": "Populace and Power: A user's guide",
+        "shortname": "populace-and-power"
+    }
+]
\ No newline at end of file
diff --git a/test/stubs-3013/njk/_includes/base.njk b/test/stubs-3013/njk/_includes/base.njk
new file mode 100644
index 00000000..4d87311e
--- /dev/null
+++ b/test/stubs-3013/njk/_includes/base.njk
@@ -0,0 +1,4 @@
+---
+title: Books
+---
+<title>{{ title }}</title>
\ No newline at end of file
diff --git a/test/stubs-3013/njk/book.njk b/test/stubs-3013/njk/book.njk
new file mode 100644
index 00000000..18804ac7
--- /dev/null
+++ b/test/stubs-3013/njk/book.njk
@@ -0,0 +1,11 @@
+---
+layout: base
+pagination:
+  data: books
+  size: 1
+  alias: book
+permalink: /{{ book.shortname }}/
+eleventyComputed:
+  title: "{{ book.name }}"
+---
+{{ title }}
\ No newline at end of file
diff --git a/test/stubs/pagination-eleventycomputed-title.liquid b/test/stubs/pagination-eleventycomputed-title.liquid
new file mode 100644
index 00000000..4608a9ad
--- /dev/null
+++ b/test/stubs/pagination-eleventycomputed-title.liquid
@@ -0,0 +1,20 @@
+---
+venues:
+  - id: 1
+    name: first
+  - id: 2
+    name: second
+  - id: 3
+    name: third
+randommetadata: "woopers"
+pagination:
+  data: venues
+  size: 1
+  alias: venue
+eleventyComputed:
+  title: "website - {{ venue.name }}"
+---
+
+{{ venue.name }}
+
+{{ randommetadata }}