2

I'm trying to render a map that has keys containing minus signs (e.g. first-name). Here is an exemplary template I'm trying to render:

String text = "Dear \"$first-name $lastname\",\nSo nice to meet you";

When I render it with Groovy template engine (can be either SimpleTemplateEngine or MarkupTemplateEngine) it complains and throws an exception. When I remove the '-' from the variable name, it works OK.

Is there anyway to escape these variables in the Groovy template text?

BTW - the reason I'm doing it this way is to render a JSON blob from a 3rd party API.

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131

1 Answers1

1

There is at least one way to do it. It doesn't work in your case for the same reasons you can't use - character in variable name. When you define an expression like:

${first-name}

Groovy sees it as:

${first.minus(name)}

and that is why it throws exception like:

Caught: groovy.lang.MissingPropertyException: No such property: first for class: SimpleTemplateScript1
groovy.lang.MissingPropertyException: No such property: first for class: SimpleTemplateScript1
    at SimpleTemplateScript1.run(SimpleTemplateScript1.groovy:1)

You can keep keys like first-name in your bindings, but you would have to put them in a map, so you can access first-name value using Map.get(key) function. Consider following example:

import groovy.text.SimpleTemplateEngine

def engine = new SimpleTemplateEngine()
def bindings = [
        'first-name': 'Test',
        'lastname': 'qwe'
]

String text = 'Dear "${map["first-name"]} ${map["lastname"]}",\nSo nice to meet you'

println engine.createTemplate(text).make([map: bindings])

In this example I put bindings into a map with a key map. When I do so I can access my bindings as map['first-name'] and map['lastname']. Running this example produces expected output:

Dear "Test qwe",
So nice to meet you

Hope it helps.

Szymon Stepniak
  • 40,216
  • 10
  • 104
  • 131
  • This is awesome! It works :) One more follow-up question. I'm trying to get above done with the MarkupTemplateEngine, with external files, but doesn't seem to like it. e.g.: title("Fitbit User Profile - ${map[user].fullName}") – Justin Lawler Apr 07 '18 at 11:39