darksoulsong
darksoulsong

Reputation: 15319

Groovy TemplateEngine - function for markup creation

I'm a JS programmer trying to write some Groovy code (with no Java background at all). I need to write some templates using Groovy, so I created a function in order to avoid repetition. My goal is to be able to pass html objects to the function (for example: p(), div(), span() and so on), but is isn't working as I expected:

The function

void addon ( addonType, mainHolder, content ) {
  div( class: "addon " + addonType ) {
    div( class: "addon-main" ) {
      div( class: "addon-main-holder" ) {
        yieldUnescaped mainHolder
      }
    }

    div( class: "addon-content" ) {
        yieldUnescaped content
    }
  }
}

Doesn't works:

[...]
  body {
    addon( 'addon-warning', p('Lorem Ipsum'), p('Dolor sit amet consectetur') )
  }
[...]

Works:

[...]
  body {
    addon( 'addon-warning', '<p>Lorem Ipsum</p>', '<p>Dolor sit amet consectetur</p>') )
  }
[...]

I tried some variations, using yield rather than yieldUnescaped, but no success. Is it possible? Any help would be much appreciated.

Upvotes: 0

Views: 672

Answers (1)

cfrick
cfrick

Reputation: 37043

Assuming you want to pass in further DSL-based tags into your addon function, I'd pass closure to that function instead. This is an simplified, self containing version (which makes it bit harder to read, as the template is in a string; take a look at the XXX comments):

import groovy.text.markup.*

def config = new TemplateConfiguration()
def engine = new MarkupTemplateEngine(config)
def template = engine.createTemplate('''
html {
    body {
        addon("Hello World", { // XXX: pass a closure
            p("Lorem Ipsum")
            p("Lorem Ipsum")
            p("Lorem Ipsum")
        })
    }
}

void addon(title, content) {
    h1(title)
    div {
        content() // XXX call the closure
    }
}
''')
Writable output = template.make([:])
println output
// => <html><body><h1>Hello World</h1><div><p>Lorem Ipsum</p><p>Lorem Ipsum</p><p>Lorem Ipsum</p></div></body></html>

Upvotes: 2

Related Questions