The SimpleTemplateEngine supports methods (and imports and even local class definitions):
def text = """\ <% import java.time.LocalDate import java.time.format.TextStyle def now = LocalDate.now() def dayName(theDate) { theDate.dayOfWeek.getDisplayName(TextStyle.FULL, Locale.default) } class Const { static days = 3 } %> # Hello Today (<%= dayName(now) %>) is <%= now %>. The weather in next <%= Const.days %> days will be: <% def weather = [ "Sunny", "Rainy", "Cloudy", "Windy" ] Const.days.times { out.println "- " + dayName(now + it) + ": " + weather.shuffled()[0] } %> """.stripIndent() def engine = new groovy.text.SimpleTemplateEngine() def template = engine.createTemplate(text) println template.make() Cheers, Paul. On Sun, Jul 24, 2022 at 6:35 AM Per Nyfelt <p...@alipsa.se> wrote: > I figured it out. although functions (methods) cannot be defined, a > closure works fine: > > def text = """\<% def now = java.time.LocalDate.now() def dayName = { theDate > -> return > theDate.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, > java.util.Locale.getDefault())}%># HelloToday (<%= dayName(now) %>) is <%= > now %>.The weather in next 3 days will be:<% def weather = [ "Sunny", > "Rainy", "Cloudy", "Windy" ] for (i = 1; i < 4; i++) { def day = > now.plusDays(i) Collections.shuffle weather out.println "- " + > dayName(day) + ": " + weather.first() }%>""".stripIndent()def engine = new > StreamingTemplateEngine()def template = engine.createTemplate(text)println > template.make() > > > On 7/23/22 19:59, Per Nyfelt wrote: > > Hi, > > I am trying to use the StreamingTemplateEngine to create dynamic markdown > (similarly to the rmd (r markdown, > https://rmarkdown.rstudio.com/authoring_quick_tour.html) but I've > encountered a snag: > > Simple usage such as the following works fine using the > StreamingTemplateEngine: > > def text = """\ <% def now = java.time.LocalDate.now() %> # Hello > Today (<%= now.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, > java.util.Locale.getDefault()) %>) is <%= java.time.LocalDate.now() %>. The > weather in next 3 days will be: <% def weather = [ "Sunny", "Rainy", > "Cloudy", "Windy" ] for (i = 1; i < 4; i++) { def day = > now.plusDays(i) def dayName = > day.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, > java.util.Locale.getDefault()) Collections.shuffle weather > out.println "- " + dayName + ": " + weather.first() } > %>""".stripIndent()def engine = new StreamingTemplateEngine()def template = > engine.createTemplate(text)println template.make() > > But if if want to define a function to simplify the code e.g. > > def text = """\ <% def now = java.time.LocalDate.now() def > dayName(java.time.LocalDate theDate) { return > theDate.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, > java.util.Locale.getDefault()) } %> # Hello Today (<%= dayName(now) %>) > is <%= now %>. The weather in next 3 days will be: <% def weather = [ > "Sunny", "Rainy", "Cloudy", "Windy" ] for (i = 1; i < 4; i++) { def > day = now.plusDays(i) Collections.shuffle weather out.println "- " > + dayName(day) + ": " + weather.first() } %>""".stripIndent()def engine = > new StreamingTemplateEngine()def template = > engine.createTemplate(text)println template.make() > > ...the StreamingTemplateEngine does not accept the function definition: > > > Template parse error 'Unexpected input: '(' ' at line 4, column 12 > 3: > --> 4: def dayName(java.time.LocalDate theDate) { > 5: return > theDate.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, > java.util.Locale.getDefault()) > > groovy.text.TemplateParseException: Template parse error 'Unexpected > input: '(' ' at line 4, column 12 > 3: > --> 4: def dayName(java.time.LocalDate theDate) { > 5: return > theDate.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, > java.util.Locale.getDefault()) > > > If there a way to define function in the text processed that would work > with the StreamingTemplateEngine? > > > The code works fine "the other way around" i.e from Groovy code: > > def now = java.time.LocalDate.now() > > def dayName(java.time.LocalDate theDate) { > return > theDate.getDayOfWeek().getDisplayName(java.time.format.TextStyle.FULL, > java.util.Locale.getDefault()) > } > > println "# Hello" > > println "Today ${dayName(now)}) is ${now}." > > println "The weather in next 3 days will be:" > > def weather = [ "Sunny", "Rainy", "Cloudy", "Windy" ] > for (i = 1; i < 4; i++) { > def day = now.plusDays(i) > Collections.shuffle weather > println "- " + dayName(day) + ": " + weather.first() > } > > But I would like a "Markdown first" kind of experience rather than a > "Groovy first" since in the "normal" case, the amount of text vastly > outnumbers the amount of code. > > > Best regards, > > Per > > >