Snippetory

how to craft your texts

According to wikipedia a template engine "...". This is not exactly what Snippetory does. As well the term 'engine' refers to providing activity to the templates. This is not true for Snippetory as well, as it features passive templates. This is why I prefer the term templating platform. However, the point of this little introduction is: Snippetory is different from what most people know in templating. It rather models a paper form, where data is filled in by 'someone' else. Of course this form can have repetitive, optional and alternative parts. However, the communication always happens on a pretty fine-grained level. This is a pattern many templating facilities are build on. In consequence, to replace a script based template one needs a passive template and 'someone', the renderer.

As obvious from that model it makes great sense to build the template first, before the renderer is built. However, before jumping into the template we need to define the task.

A calendar page

I think a presentation of single month is a nice little example, and we can even get localisation for free. Now let's jump into it. As always with Snippetory I start with a template. This is obviously a good choice, as to fill data into the form one needs a form.

Now, how should it look like? We have a heading consisting of month and year.

With a pretty clear picture of the requirements, and we can start to write the template down.

<table > <caption>{v:month date="MMMM yyyy"}</caption> <tr> <t:caption> <th>{v:week-day date="EEEE"}</th> </t:caption> </tr> <t:week> <tr> {v:target} <t:day-in> <td style="text-align:right;"> {v:day date="d"} </td> </t:day-in> <t:day-out> <td style="color:grey; text-align:right;"> {v:day date="d"} </td> </t:day-out> </tr> </t:week> </table>

Now we have a template, and we can start to fill it with data. We can use it in the calendar object, which will be responsible for rendering the calendar page. It needs the locale to be able to render the month and week day names.

public class Calendar { private final TemporalField weekField; private final Template calendar; public Calendar(Locale l) { this.weekField = WeekFields.of(l).dayOfWeek(); this.calendar = Repo.readResource("calendar.html") .encoding(Encodings.html).locale(l).parse(); } public Template render(YearMonth month) { LocalDate dayCounter = month.atDay(1).with(weekField, 1); LocalDate end = month.atEndOfMonth().with(weekField, 7).plusDays(1); calendar.set("month", month); for (long i = 1; i <= 7; i++) { calendar .get("caption") .set("week-day", dayCounter.with(weekField, i)) .render(); } while (dayCounter.isBefore(end)) { Template weekTpl = calendar.get("week"); for (int i = 1; i <= 7; i++) { String dayStyle = isOfMonth(dayCounter, month) ? "day-in" : "day-out"; weekTpl .get(dayStyle) .set("day", dayCounter.atStartOfDay()) .render("target"); dayCounter = dayCounter.plusDays(1); } weekTpl.render(); } return calendar; } private boolean isOfMonth(LocalDate day, YearMonth month) { return YearMonth.from(day).equals(month); } }

The calendar class is pretty straightforward. It creates a calendar template and fills it with data. The month is set to the month variable, and the week day names are rendered in the caption. Then we loop through the days of the month, and for each week we render a week template. Inside the week template we check if the day belongs to the month, and render either a day-in or day-out template.

Bernd Ebertz Head, Founder and chief technology evangelist of
jproggy.org