handlebars.java icon indicating copy to clipboard operation
handlebars.java copied to clipboard

Incorrect context for "this" when using named parameter

Open gjgarryuan opened this issue 5 years ago • 1 comments

handlebars.java version: 4.2.0

For the following template:

{{#each items as |item i|}}{{this.i}}: {{this.j}}\n{{/each}}

with context:

{
  "items": [
    {
      "i": "a",
      "j": "b"
    },
    {
      "i": "1",
      "j": "2"
    }
  ]
}

Expected:

a: b\n1: 2\n

You can try it with official handlebar.js 's online evaluator: https://handlebarsjs.com/playground.html#format=1&currentExample=%7B%22template%22%3A%22%7B%7B%23each%20items%20as%20%7Citem%20i%7C%7D%7D%7B%7Bthis.i%7D%7D%3A%20%7B%7Bthis.j%7D%7D%5C%5Cn%7B%7B%2Feach%7D%7D%22%2C%22partials%22%3A%5B%5D%2C%22input%22%3A%22%7B%5Cn%20%20items%3A%20%5B%5Cn%20%20%20%20%7B%5Cn%20%20%20%20%20%20i%3A%20%5C%22a%5C%22%2C%5Cn%20%20%20%20%20%20j%3A%20%5C%22b%5C%22%5Cn%20%20%20%20%7D%2C%20%5Cn%20%20%20%20%7B%5Cn%20%20%20%20%20%20i%3A%20%5C%221%5C%22%2C%5Cn%20%20%20%20%20%20j%3A%20%5C%222%5C%22%5Cn%20%20%20%20%7D%5Cn%20%20%5D%5Cn%7D%5Cn%22%2C%22output%22%3A%22a%3A%20b%5C%5Cn1%3A%202%5C%5Cn%22%2C%22preparationScript%22%3A%22%5Cn%22%2C%22handlebarsVersion%22%3A%224.7.6%22%7D

Actual:

0: \n1: \n

Observation:

It is clear that the usage of this in the template is wrongly interpreted. It is expected that the use of both this and item in the above template should refer to the same context of each item in items.

gjgarryuan avatar May 28 '20 17:05 gjgarryuan

Suggested fix:

diff --git a/handlebars/src/main/java/com/github/jknack/handlebars/Context.java b/handlebars/src/main/java/com/github/jknack/handlebars/Context.java
index bfd16be3..290d2b4c 100644
--- a/handlebars/src/main/java/com/github/jknack/handlebars/Context.java
+++ b/handlebars/src/main/java/com/github/jknack/handlebars/Context.java

@@ -83,8 +83,8 @@ public class Context {
     public Object get(final List<PathExpression> path) {
       String key = path.get(0).toString();
       // we must resolve this to parent context on block contexts (so tricky)
-      if (path.size() == 1 && key.equals("this")) {
-        return parent.model;
+      if (key.equals("this")) {
+        return parent.get(path);
       }
       // path variable should resolve from parent :S
       if (key.startsWith(".") && path.size() > 1) {

martin-sladecek avatar Jun 27 '22 12:06 martin-sladecek