Skip to main content

Views

Invirt's view layer is a thin convention over http4k templating. A response that renders a Pebble template is either produced from an InvirtView instance, or directly via renderTemplate(request, "template").

InvirtView​

InvirtView is the base class for view models. It associates a model class with a template name so the handler doesn't have to repeat the template path each time.

open class InvirtView(val template: String)

The .peb extension is optional in the template name. Both InvirtView("users/list") and InvirtView("users/list.peb") resolve to the same template.

data class ListUsersResponse(
val users: List<User>
) : InvirtView("users/list") // Points to webapp/views/users/list.peb

val handler = routes(
"/users/list" GET { request ->
ListUsersResponse(users).ok(request)
},
"/users/create" POST { request ->
CreateUserResponse(user).status(request, Status.ACCEPTED)
}
)

The request argument is required because Invirt makes the current Request available to the template (see Current request).

Response helpers​

FunctionDescription
InvirtView.ok(request)Renders the view with HTTP 200
InvirtView.status(request, status)Renders the view with the given status
renderTemplate(request, template, model?)Renders an arbitrary template without an InvirtView
"/" GET { request ->
renderTemplate(request, "index")
}

"/profile" GET { request ->
renderTemplate(request, "profile", mapOf("name" to "John"))
}

Error responses​

Validation errors are returned as a special kind of view response that exposes the failed model and the ValidationErrors to the Pebble template (see Form validation).

fun errorResponse(
request: Request,
errors: ValidationErrors,
template: String,
model: Any? = null,
status: Status = Status.UNPROCESSABLE_ENTITY
): Response
"/signup" POST { request ->
request.toForm<SignupForm>()
.validate()
.map {
success { form -> httpSeeOther("/signup/success") }
error { form, errors -> errorResponse(request, errors, "signup", form) }
}
}

For convenience, an InvirtView can also be rendered as an error response directly:

SignupView().asErrorResponse(request, errors)

A short-form overload is available for one-off field errors without a backing model:

errorResponse(request, "signup", "email" to "Email already in use")