6

Can someone explain why this does not work ?

StringTemplate query = new StringTemplate("hello " +  
                "$if(param==\"val1\")$" +  
                " it works! " +  
                "$endif$ " +  
                "world");  
        query.setAttribute("param", "val1");  
        System.out.println("result: "+query.toString());  

It throws

eval tree parse error :0:0: unexpected end of subtree at org.antlr.stringtemplate.language.ActionEvaluator.ifCondition(ActionEvaluator.java:815) at org.antlr.stringtemplate.language.ConditionalExpr.write(ConditionalExpr.java:99)

kemiller2002
  • 113,795
  • 27
  • 197
  • 251
Alexey
  • 517
  • 2
  • 10
  • 21

2 Answers2

12

ST doesn't allow computation in the templates. That would make it part of the model.

Terence Parr
  • 5,912
  • 26
  • 32
  • 2
    It seriously boggles my mind how people can find StringTemplate, read enough about it to create a sample example, yet not grasp its single most important strength. – I82Much Nov 17 '10 at 18:47
  • 6
    It's hard to say whether it's really strength or weakness. It's easy to see why this isn't so obvious though: other templating engines have it. And check for equality isn't much of a "computation", plus there are conditionals in string template anyway. – mvmn Jul 04 '12 at 11:43
  • 1
    conditionals only test presence or absence, not value. huge diff in terms of model-view separation. – Terence Parr Jul 04 '12 at 18:50
  • "conditionals only test presence or absence, not value" Wrong - they do test boolean conditions for value, not just presence of any boolean value. – mvmn Dec 05 '16 at 12:15
  • doesn't iterating over a list or map do calculations on the template ( like size) ? – Viraj May 01 '18 at 11:22
  • The key difference is there is no user-defined computations allowed :) – Terence Parr May 01 '18 at 23:29
5

You can't compare strings inside stringtemplate, unfortunately, but you can send a result of such a comparison into template as a parameter:

StringTemplate query = new StringTemplate("hello " +  
                "$if(paramEquals)$" +  
                " it works! " +  
                "$endif$ " +  
                "world");  
        query.setAttribute("paramEquals", param.equals("val1"));  
        System.out.println("result: "+query.toString());

It might not be what you're looking for, since every time you need to add a comparison you have to pass an extra parameter, and for loops it's even worse. But this is one workaround that may work for simple cases.

mvmn
  • 3,717
  • 27
  • 30