Skip to main content Skip to docs navigation

Document not reviewed yet, might be outdated. Please, let us know if you find something invalid here.
To access this functionality you can include the: com.soywiz.korge:korge-core:5.1.0 artifact from maven central. All the functionality yields in the korlibs.template package .
On this page

KorTE

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
        }
    }
Was this article useful?