Closed GideonBrimleaf closed 2 years ago
Thank you for the compliment :)
Would you mind elaborating on this use-case, perhaps giving a specific example of what you'd like to do?
It may be relevant to note that Kweb is built on Ktor and so it inherits all of that functionality.
Hello!
I've got a link to a sample Ktor Project here which illustrates what I am trying to achieve.
In src/main/kotlin/Application.kt
I have the following routes defined which both try to achieve the same thing - they immediately send back some HTML with an H1 header (with the placeholder value "Loading"). An asynchronous coroutine then spins off which arbitrarily waits 3 seconds before updating the text to "Han Solo".
routing {
get("/kweb-async-response") {
call.respondKweb {
doc.body {
val name = KVar("Loading")
GlobalScope.launch {
delay(3000L)
name.value = "Han Solo"
}
h1().text(name.map{ "The name is $it" })
}
}
}
get("/freemarker-async-response") {
val name = KVar("Loading")
GlobalScope.launch {
delay(3000L)
name.value = "Han Solo"
}
call.respond(FreeMarkerContent("index.ftl", mapOf("name" to name.map { "The name is $it" })))
}
}
In the /kweb-async-response
route the call.respondKweb()
method works the way I'd like. Navigating in the browser you see the value "Loading" then after 3 seconds this updates to "Han Solo". Really powerful stuff.
I was hoping to imitate this behaviour in the /freemarker-async-response
by sending the same data to the following freemarker template in resources/templates/index.ftl
<#-- @ftlvariable name="name" -->
<html>
<body>
<h1>${name}<h1>
</body>
</html>
However this only renders "KVal(The name is Loading)" in the browser. I am unsure how to achieve the same result as with the first route? I really like the dynamic linking of the view and server layer in KWeb through KVars but would be great to harness them in other templating engines outside of the KWeb DSL if possible?
Thanks for your help!
Sorry about the delay in responding.
Unfortunately I don't think this will be easy as the binding mechanism depends on knowing the element ids, which it will only know if the elements are created using Kweb's own DSL.
To do it you'd need to specify the element id in the FreeMarker template, and then create an Element with a jsExpression
that points to that element - you could then use this Element to bind your KVars.
Another possibility would be to write some code to translate your FreeMarker templates into the KWeb DSL and then just use those from there.
Hi, thanks for getting back in touch. Do you have an example of how to build an Element with a jsExpression
for KVar binding? Happy to create ids inside the templates as required.
Hi, yes - you can see an example here:
jsExpression = """document.getElementById("$id")"""
It's a Javascript expression that returns the element in JavaScript on the browser.
Hi - I had a look through but I'm a but stuck. The Freemarker template now has the following header with an id:
<#-- @ftlvariable name="name" -->
<html>
<body>
<h1 id="header-name">${name}<h1>
</body>
</html>
Additionally I've begun creating the Element
in /freemarker-async-response
as follows:
get("/freemarker-async-response") {
val name = KVar("Loading")
GlobalScope.launch {
delay(3000L)
name.value = "Han Solo"
}
val element = Element(jsExpression = """document.getElementById("header-name")""") // Added
call.respond(FreeMarkerContent("index.ftl", mapOf("name" to name.map { "The name is $it" })))
}
I noticed however that the Element
requires other arguments like browser
, creator
, tag
and id
and I'm unsure how to get these in a Ktor project? Also how would I get the KVar data to bind to this and then pass through to the Element
to the template?
Thanks for your help!
use
doc.getElementById("header-name")
for retrieving element by id
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
Love KWeb - was wanting to know if there is any way to inject KVar data into an existing templating engine such as Freemarker, Pebble or Thymeleaf when using KWeb with other frameworks such as Ktor rather than using the KWeb DSL/server.