package guestbook; import gg.jte.ContentType; import gg.jte.TemplateEngine; import gg.jte.resolve.DirectoryCodeResolver; import io.javalin.Javalin; import io.javalin.http.Context; import io.javalin.rendering.template.JavalinJte; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * No-JS guestbook server. * * One page (rendered by JTE on every request) shows the list of messages * plus a form. The form POSTs to /submit, which appends to the in-memory * list and then re-renders the page directly. */ public class Server { private static final List MESSAGES = new ArrayList<>(); public static void main(String[] args) { // JTE template engine, reading templates from ./templates at runtime // (so edits hot-reload without a rebuild). TemplateEngine engine = TemplateEngine.create( new DirectoryCodeResolver(Path.of("templates")), ContentType.Html); Javalin.create(config -> { config.fileRenderer(new JavalinJte(engine)); config.routes.get("/", Server::handleIndex); config.routes.post("/submit", Server::handleSubmit); }).start(8331); } private static void handleIndex(Context ctx) { ctx.render("index.jte", Map.of("messages", MESSAGES)); } private static void handleSubmit(Context ctx) { String name = ctx.formParam("name"); String message = ctx.formParam("message"); if (name != null && !name.isBlank() && message != null && !message.isBlank()) { MESSAGES.add(new Message(name, message)); } ctx.render("index.jte", Map.of("messages", MESSAGES)); } }