BorisMoore / jsrender

A lightweight, powerful and highly extensible templating engine. In the browser or on Node.js, with or without jQuery.
http://www.jsviews.com
MIT License
2.68k stars 340 forks source link

missing {{/props}} error #252

Closed ittayd closed 9 years ago

ittayd commented 9 years ago
Uncaught JsRender Error: Syntax error
Unmatched or missing tag: "{{/props}}" in template:

   <ul>
   {{props categories}}
      <li>{{key}}

      </li>
   {{/props}}
   </ul>
jsrender.js:1031 
errorjsrender.js:1037 
syntaxErrorjsrender.js:1053 
blockTagCheckjsrender.js:1143 
parseTagjsrender.js:1173 
tmplFnjsrender.js:761 
compileTmpljsrender.js:711 
tmplOrMarkupFromStrjsrender.js:724 
compileTmpljsrender.js:861 
theStoreuserCodeAppPanel:10 
 (anonymous function)
BorisMoore commented 9 years ago

I think you meant to write

   <ul>
   {{props categories}}
      <li>{{:key}}

      </li>
   {{/props}}
   </ul>

Using {{:key}} or {{>key}} should work, but writing {{key}} makes it into a custom tag. Custom tags need to be written {{mytag/}} or {{mytag}}...{{/mytag}}. So here the parser is expecting to continue and find more content within the {{key}} block, followed by the closing tag for {{/key}} and then for {{/props}}. Instead it finds what it thinks is an isolated unmatched {{/props}}.

Of course it could have said: "Missing closing tag or closing slash for {{key}}{{/key}} or {{key/}}". But there are different possible interpretations of what was intended when there is a syntax error, so the message is just a hint as to where/what the issue is.

ittayd commented 9 years ago

Well, it is an unmatched {{/props}}, not a missing one and indeed, it would have been easier to spot the problem (missing :) if the message said 'no closing {{/key}}. That is, when seeing a closing tag, search if the stack of tags contains it and then error on the ones on top of it

BorisMoore commented 9 years ago

It is one pass parsing, so is too soon to know if the parent {{key}} is missing its closing tag. It just hasn't been encountered yet. (Indeed, looking up the stack of parent tags, they at that point will all be missing their closing tags!)

If your code was

   <ul>
   {{props categories}}
        {{key}}
              {{/props}}
        {{/key}}
    {{/props}}
   </ul>

then on reaching the {{/props}} it would be wrong to say "no closing {{/key}}". (And if it did, a user would complain :) )

As I said, in a one pass situation, without creating additional two-pass analysis (with perf and file size implications), there is more than one possible interpretation, so the message indicates the location of the issue (the {{/props}}) and the fact that (given the nested {{key}} tag), it doesn't match an opening {{props}}. From there it is for the user to check their syntax around that area and find their error.

ittayd commented 9 years ago

The best message would have been '{{/params}} encountered in {{key}} block with no open {{params}}'

BorisMoore commented 9 years ago

@ittayd - I did manage to improve the detection and error message associated with this scenario. (Similar to you suggestion). Fixed in commit 64.