Re: Defining functions in text processed by the StreamingTemplateEngine

Paul King <[email protected]>
Newsgroups gmane.comp.lang.groovy.user
Message-ID <CAMbkE7RvD-WmgXeF4TbQ19twzrc-+i1L4LT-FTMi-SuU9Y-gaw@mail.gmail.com>
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 <[email protected]> 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
>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.