Pages
The pages module allows the server to generate HTML pages (e.g. error messages or the directory listing) and can be used to render custom pages from a template, using Pebble as a rendering engine. Support for rendering websites in genhttp-kt is minimalistic, so you should not use this for a website project.
GenHTTP renders templates with Cottle, which does not exist on the JVM, so genhttp-kt uses Pebble instead. Pebble is configured to behave like Cottle: values are not escaped automatically, variables that are not part of the model render as empty text, and white space is kept as it is.
Page Rendering
The following example will show you how to use a Pebble template file to generate a web page with dynamic content via genhttp-kt.
Source
import org.genhttp.api.content.io.Resource
import org.genhttp.api.protocol.Request
import org.genhttp.engine.internal.Host
import org.genhttp.modules.functional.*
import org.genhttp.modules.io.*
import org.genhttp.modules.pages.Renderer
import org.genhttp.modules.pages.getPage
import org.genhttp.modules.practices.defaults
suspend fun main() {
val template = Renderer.from(Resource.fromClasspath("Template.html").build())
val app = Inline.create()
.get { request: Request ->
val data = mapOf("users" to getUsers())
request.getPage(template.render(data))
}
Host.create()
.handler(app)
.defaults()
.development()
.run()
}
data class User(val id: Int, val name: String)
fun getUsers(): List<User> = listOf(User(1, "Some User"))Template.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Users</title>
</head>
<body>
<table>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name | escape }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>The template is read from the classpath (src/main/resources/Template.html) and compiled once; if the
resource changes, it is compiled again on the next rendering. The model is a Map<String, Any?>: Pebble
reads the properties of the objects in it, such as user.name of a data class, through their getters.
As the output is not escaped automatically, apply the escape filter to values that may contain HTML,
such as the name of a user.
Server-Styled Pages
Renderer.server is a built-in renderer using the same theme as the server’s own error pages and
directory listings, so you can render a simple page without shipping a template of your own:
val app = Inline.create()
.get { request: Request ->
val page = Renderer.server.render("Maintenance", "<p>We'll be back shortly.</p>")
request.getPage(page)
}Neither the title nor the content are escaped by the renderer; escaped() escapes a string for HTML
if it contains user input (name.escaped()).