Kartikey Joshi
Kartikey Joshi

Reputation: 58

Groovy - Append values to variables in a string

Lets assume I have a domain class called Template that looks somewhat like this:

class Template{
 String subject
 ...
}

I save an instance of this class:

Template t=new Template(subject:'Hello ${name}').save()

Now, I fetch this instance inside a method as follows:

def render(Long id){
  String name='foo'
  Template t= Template.get(id)
  println t.subject
}

I want the "println t.subject" to be printed as "Hello foo". What I get is "Hello ${name}". I want t.subject to dynamically replace the value of variable name - "foo" in place of ${name}.

Can this be achieved in groovy? I cannot find any documentation of how to do this, or why this cannot be done.

Update:

I tried this on my GroovyConsole.

class Entity{
    String name
}

class Template{
    String name
    String subject
}

String renderTemplate(Template template, Entity entity){ 
   return template.subject
}

Entity e = new Entity(name:'product')
Template template=new Template(name:'emailTemplate',subject:'Product ${e.name}')

renderTemplate(template,e)

The Output I got was:

Result: Product product

Upvotes: 0

Views: 5222

Answers (3)

Vladimir
Vladimir

Reputation: 517

class Template {
  String subject
  // ...
}

Template t = new Template(subject: 'Hello, ${name}').save()

Important: Use single quotes in 'Hello, ${name}' or you will get an error.

def render(Long id) {
  String name = "world"
  Template t = Template.get(id)

  ​def engine = new groovy.text.GStringTemplateEngine()

  def subject = engine
    .createTemplate(t.subject)
    .make(name: name)​

  println subject
}

Upvotes: 2

injecteer
injecteer

Reputation: 20707

You can use a transient property to emulate the required behavior:

class Template{
  String subject
  String getSubjectPretty(){ "Hello $subject" }
  static transients = ['subjectPretty']
}

Then you can use:

println Template.get(1).subjectPretty

Upvotes: 0

Jeff Scott Brown
Jeff Scott Brown

Reputation: 27255

There are a couple of things wrong with the code shown. You have this:

class Template{
    String subject
    ...
}

Then you have this:

Template t=new Template(subject:"Hello ${name}").save()

The Groovy String assigned to the subject property will be evaluated as soon as you assign it to subject because subject is a String. The actual value will depend on the value of the name property that is in scope when that code executes.

Later you have this:

def render(Long id){
    String name="foo"
    Template t= Template.get(id)
    println t.subject
}

It looks like you are wanting that local name property to be substituted into a Groovy String that has been assigned to t.subject, but that isn't how Groovy works. t.subject is not a Groovy String. It is a String.

Separate from that you comment that when you println t.subject that the output is "Hello ${name}". I don't think that is possible, but if that is what you are seeing, then I guess it is.

Upvotes: 0

Related Questions