Skip to content

Commit

Permalink
template: attempt to get pebble templates adapted to Undead
Browse files Browse the repository at this point in the history
  • Loading branch information
floodfx committed Nov 5, 2023
1 parent 49e146d commit 9cddc91
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 0 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<dependency>
<groupId>io.pebbletemplates</groupId>
<artifactId>pebble</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>

<distributionManagement>
Expand Down
1 change: 1 addition & 0 deletions src/main/java/run/undead/javalin/example/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static void main(String[] args) {
), undeadConf)
// use the UndeadJavalin instance to register Undead Views to routes
.undead("/count", new UndeadCounter())
.undead("/count/pebble", new UndeadCounterPebble())
.undead("/count/{start}", new UndeadCounter())
.undead("/dashboard", new UndeadSalesDashboard())
.undead("/user/new", new UndeadUserForm())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package run.undead.javalin.example.view;

import io.pebbletemplates.pebble.PebbleEngine;
import run.undead.context.Context;
import run.undead.event.UndeadEvent;
import run.undead.pebble.PebbleTemplateAdaptor;
import run.undead.template.UndeadTemplate;
import run.undead.view.Meta;
import run.undead.view.View;

import java.util.Map;

public class UndeadCounterPebble implements View {
private Integer count;
private PebbleTemplateAdaptor adaptor = new PebbleTemplateAdaptor(new PebbleEngine.Builder()
.build());

public UndeadCounterPebble() {
this.count = 0;
}

@Override
public void mount(Context context, Map sessionData, Map params) {
if (params.get("start") != null) {
this.count = Integer.parseInt((String) params.get("start"));
} else {
this.count = 0;
}
}

@Override
public void handleEvent(Context context, UndeadEvent event) {
if (event.type().equals("inc")) {
this.count++;
} else if (event.type().equals("dec") && this.count > 0) {
this.count--;
}
}

@Override
public UndeadTemplate render(Meta meta) {
try {
return adaptor.render("count.html", Map.of("count", this.count));
} catch (Exception e) {
throw new RuntimeException(e);
}
}

}
72 changes: 72 additions & 0 deletions src/main/java/run/undead/pebble/PebbleTemplateAdaptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package run.undead.pebble;

import io.pebbletemplates.pebble.PebbleEngine;
import io.pebbletemplates.pebble.template.PebbleTemplate;
import run.undead.template.UndeadTemplate;

import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class PebbleTemplateAdaptor {

private final PebbleEngine engine;

public PebbleTemplateAdaptor() {
this(new PebbleEngine.Builder().build());
}
public PebbleTemplateAdaptor(PebbleEngine engine) {
this.engine = engine;
}

public UndeadTemplate render(String template, Map<String, Object> data) throws Exception {
PebbleTemplate compiledTemplate = engine.getTemplate(template);

var writer = new StringTemplateWriter();
compiledTemplate.evaluate(writer, data);
return new UndeadTemplate(writer.toStringTemplate(), false);
}

class StringTemplateWriter extends Writer {
private final List<String> fragments = new ArrayList<>();
private final List<Object> values = new ArrayList<>();
private int writeCounts = 0;

@Override
public void write(char[] cbuf, int off, int len) {
var data = new String(cbuf, off, len);
// System.out.println("write:" + data);
// all we can do is alternate between fragments and values
if(writeCounts % 2 == 0) {
fragments.add(new String(cbuf, off, len));
} else {
values.add(new String(cbuf, off, len));
}
writeCounts++;
}

@Override
public void flush() {
// no-op
}

@Override
public void close() {
// no-op
}

public StringTemplate toStringTemplate() {
if(fragments.size() == values.size()) {
throw new RuntimeException("template part needs default value; likely caused by a control statement like an if statement with zero output. try adding an else statement with a default or empty value");
}
return StringTemplate.of(fragments, values);
}

@Override
public String toString() {
return toStringTemplate().interpolate();
}

}
}
21 changes: 21 additions & 0 deletions src/main/resources/count.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class="flex flex-col space-y-4 mx-4">
<div class="text-2xl">Zombie Count</div>
<div class="flex items-center space-x-4">
<button class="btn btn-primary"
{% if count <= 0 %}
disabled
{% else %}
{% endif %} type="button" ud-click="dec">-</button>
<span class="countdown font-mono text-6xl
{% if count == 0 %}
text-neutral
{% elseif count <= 9 %}
text-warning
{% elseif count > 9 %}
text-error
{% endif %}">
<span style="--value:{{ count }};"></span>
</span>
<button class="btn btn-primary" type="button" ud-click="inc">+</button>
</div>
</div>
7 changes: 7 additions & 0 deletions src/main/resources/sub.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% if sub == "foo" %}
<p>foo</p>
{% elseif sub == "bar" %}
<p>bar</p>
{% else %}
<p>baz</p>
{% endif %}
28 changes: 28 additions & 0 deletions src/main/resources/test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello {{name}}!

{% for article in articles %}
<h3>{{ article.title }}</h3>
<p>{{ article.content }}</p>
{% else %}
<p> There are no articles. </p>
{% endfor %}


{% if category == "news" %}
{{ news }}
{% elseif category == "sports" %}
{{ sports }}
{% else %}
<p>Please select a category</p>
{% endif %}

{% include "sub.html" %}
</body>
</html>
66 changes: 66 additions & 0 deletions src/test/java/run/undead/pebble/PebbleAdaptorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package run.undead.pebble;

import org.junit.jupiter.api.Test;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PebbleAdaptorTest {

@Test
public void testAdaptor() throws Exception {
var adaptor = new PebbleTemplateAdaptor();
var template = adaptor.render("test.html",
Map.of(
"name", "<h1>Undead</h1>",
"articles", List.of(),
"sub", "foo"
)
);

assertEquals(StringTemplate.STR."""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello &lt;h1&gt;Undead&lt;/h1&gt;!
<p> There are no articles. </p>
<p>Please select a category</p>
<p>foo</p>
</body>
</html>""",template.toString());
System.out.println("parts:" + template.toParts());
var parts = new LinkedHashMap<>();
parts.put("0", "&amp;lt;h1&amp;gt;Undead&amp;lt;&#x2F;h1&amp;gt;");
parts.put("1", "&lt;p&gt; There are no articles. &lt;&#x2F;p&gt;\n");
parts.put("2", "&lt;p&gt;Please select a category&lt;&#x2F;p&gt;\n");
parts.put("3", "&lt;p&gt;foo&lt;&#x2F;p&gt;\n");
parts.put("s", List.of(
"<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Title</title>\n" +
"</head>\n" +
"<body>\n" +
"Hello ",
"!\n" +
"\n",
"\n" +
"\n",
"\n",
"</body>\n" +
"</html>"
));
assertEquals(parts, template.toParts());

}
}

0 comments on commit 9cddc91

Please sign in to comment.