Templates
com.soywiz.korge:korge-core:5.1.0
artifact from maven central.
All the functionality yields in the
korlibs.template
package
.
KorTE is a asynchronous template engine for Multiplatform Kotlin.
It is a non-strict super set of twig / django / atpl.js / jinjava template engines and can support liquid template engine too with frontmatter.
It has out of the box support for ktor and vert.x.
It works on JVM and JS out of the box.
But can also work on Native when using untyped model data or making models to implement the DynamicType
interface.
It allows to call suspend methods from within templates.
Live demo (editable) [source code]:
Pages
{% include toc.html context=”/korte/” %}
Usage
Raw Usage
Manual usage:
import com.soywiz.korte.Template
val template = Template("hello {{ who }}")
val rendered = template(mapOf("who" to "world"))
assertEquals("hello world", rendered)
Managed with KorIO’s Vfs and optional cache:
import com.soywiz.korte.Templates
//val myvfs = resourcesVfs["templates"] // To read templates from a 'templates' folder in the application resources
val myvfs = MemoryVfsMix(
"index.html" to "hello {{ who }}"
)
val templates = Templates(myvfs, cache = true)
val rendered = templates.render("index.html", mapOf("who" to "world"))
assertEquals("hello world", rendered)
Ktor
dependencies {
jvmMainApi "com.soywiz:korte-ktor-jvm:$korteVersion"
}
fun Application.module() {
install(Korte) {
cache(true)
root(
// resourcesVfs
MemoryVfsMix(
"demo.tpl" to "Hello {{ hello }}"
)
)
}
routing {
get("/") {
call.respondKorte("demo.tpl", MyModel(hello = "world"))
}
}
assertEquals("Hello world", handleRequest(HttpMethod.Get, "/") { }.response.content)
}
Vert.x
dependencies {
jvmMainApi "com.soywiz:korte-vertx-jvm:$korteVersion"
}
val port = 0
val host = "127.0.0.1"
val vertx = Vertx.vertx()
val router = Router.router(vertx)
val template = TemplateHandler.create(
KorteVertxTemplateEngine(
coroutineContext, Templates(
MemoryVfsMix(
"index.html" to "hello world {{ 1 + 2 }}!",
"hello.html" to "Nice :)!"
)
)
)
)
router.get("/*").handler(template)
val server: HttpServer = run {
val server = vertx.createHttpServer()
server.requestHandler(router)
vx { server.listen(port, host, it) }
}
val actualPort = server.actualPort()
try {
val client = vertx.createHttpClient()
assertEquals("hello world 3!", client.get(actualPort, "127.0.0.1", "/").readString())
assertEquals("Nice :)!", client.get(actualPort, "127.0.0.1", "/hello").readString())
} finally {
server.close()
}
Native
Since Kotlin/Native doesn’t provide any kind of reflective functionality yet (and kotlinx.serialization don’t allow to call methods), you have to help it a bit to understand your typed models to be able to call them.
data class Person(val name: String, val surname: String) :
DynamicType<Person> by DynamicType({ register(Person::name, Person::surname) })
class TestMethods : DynamicType<TestMethods> by DynamicType({
register("mytest123") { mytest123() }
register("sum") { sum(it[0].toDynamicInt(), it[1].toDynamicInt()) }
}), DynamicContext {
var field = 1
suspend fun mytest123(): Int {
var r = withContext(Dispatchers.Unconfined) { field }
return r + 7
}
@JsName("sum")
suspend fun sum(a: Int, b: Int): Int {
return a + b
}
}