Mark Thomas
12/19/2022, 12:45 PMgeepawhill
01/05/2023, 4:31 AMkotlinx.html.title
puts the title usage in red and suggests the import, which it then does. However, the import does not correct the red unknown mark, and re-suggests the same import. Am I not seeing something extremely obvious here?
import kotlinx.html.html
import kotlinx.html.stream.appendHTML
import kotlinx.html.title
import org.junit.jupiter.api.Test
class HtmlTest {
@Test
fun makesTitle() {
val output = StringBuilder()
output.appendHTML().html {
title("Let's try this.")
}
}
}
Cies
03/25/2023, 12:01 PMCies
03/25/2023, 12:09 PMpeekandpoke
05/05/2023, 6:56 AMCies
05/05/2023, 8:52 AMpeekandpoke
05/05/2023, 11:52 AMpeekandpoke
05/05/2023, 11:56 AMhhariri
Cies
05/05/2023, 1:01 PMhhariri
peekandpoke
05/08/2023, 6:55 AMpeekandpoke
05/08/2023, 6:59 AMinline fun <T : Tag> T.visit(crossinline block: T.() -> Unit) = visitTag { block() }
could already improve compile-times for @Cies a lot. I guess the compiler backend has to somehow recursively expand all this inlining which breaks memory locality, forces memory copies over memory copies (but i frankly have no clue what is going on there, just guessing...)Cies
05/08/2023, 7:50 AMEvgeniy Zemtsov
05/18/2023, 12:19 PMbuildString {
appendHTML().b { +"Here is a list of users" }
append("\n\n")
for (user in users) {
appendHTML().b { +"${user.type}: "}
append("${user.login}\n")
}
}
Maybe anyone has a better example?peekandpoke
06/21/2023, 6:48 AMMichael Strasser
07/03/2023, 4:09 AMCannot inline bytecode built with JVM target 11 into bytecode that is being built with JVM target 1.8
.
Kotest HTML Reporter sets minimum JVM version to 1.8. I will check the minimum version of Kotest JVM itself.Mikael Ståldal
07/07/2023, 10:04 AM<option value="a1">A1</option>
<option value="a3">A3</option>
<option value="a6">A6</option>
(without the containing <select>
element.) This is for JVM server-side, I am generating HTML snippets to be requested with AJAX and inserted into the DOM on the client.
I can do this to get it with a wrapping <select>
element:
val models = listOf(IdName("a1", "A1"), IdName("a3", "A3"), IdName("a6", "A6"))
val html: String = createHTML()
.select {
for (model in models) {
option {
attributes["value"] = model.id
+model.name
}
}
}
but how do I get rid of the wrapping element?Cies
07/07/2023, 1:48 PMfor (model in models) { ... }
is not very kotlinesque, try models.forEach { model -> ... }
instead, I think you'll come to love it!Jerry Preissler
08/06/2023, 12:23 PMclass ContentTemplate(idList: List<DokumentId>): Template<HTML> {
val ids = idList
override fun HTML.apply() {
body {
ul {
ids.forEach { it ->
li {
a(UriRenderer.render(it).toString()) { +it.shortString() }
}
}
}
}
}
}
Peter
08/11/2023, 7:04 AMkotlinx-html
(the JVM version) in combination with htmx
, and liking it a lot so far. 👍
Of course typed HTML is a big advantage, but one aspect I think isn’t highlighted as much but equally as important IMHO is: much better security out of the box.
Because it isn’t a simple string-based template engine, it knows when to escape input (text nodes and attributes) and reduces common risk like user injected XSS.Peter
08/15/2023, 1:06 PMkotlinx-html
with HTMX
and struggling a bit to nicely return (a wellformed) snippet. So far my solutions feel like a hack with some additional string manipulation.
So for example I want to return single parent “DIV” with some children (and not a BODY or HTML tag). What would be the idiomatic way to achieve this in a standard ktor route handler (PipelineContext)?
TIA!!Cies
08/15/2023, 1:48 PMCies
08/15/2023, 1:49 PMCies
08/15/2023, 1:49 PMCies
08/15/2023, 1:52 PM/** Evaluate a TemplateRenderer block into a String. Used in email rendering. */
fun stringFromHtml(renderer: TemplateRenderer): String {
return StringBuilder().apply {
append("<!DOCTYPE html>\n")
appendHTML().renderer()
}.toString()
}
/** Evaluate a TemplateRenderer block into a RePlay RenderHtml Result. <------- so this would be different for KTor! */
fun resultFromHtml(renderer: TemplateRenderer): RenderHtml {
return RenderHtml(stringFromHtml(renderer))
}
typealias TemplateRenderer = TagConsumer<*>.() -> Unit
typealias LayoutBuilder<T> = TagConsumer<*>.(data: T, renderer: TemplateRenderer) -> Unit
fun <T> layout(builder: LayoutBuilder<T>): LayoutBuilder<T> {
return { data, renderer -> builder(data, renderer) }
}
// In a render method we simply do:
fun render(input: Whatever): RenderHtml {
return resultFromHtml {
table {
tr {
+input.toString()
}
}
}
}
Cies
08/15/2023, 1:53 PMadambrangenberg
08/15/2023, 10:04 PMSlackbot
08/21/2023, 9:15 PMPeter
08/25/2023, 9:55 AMHTMX
and kotlinx-html
. Turns out it is not difficult to create inner html snippets using the filter
option. Simple example:
fun createInnerUL(block: UL.() -> Unit): String {
var first = true
return createHTML().filter {
if (first && it.tagName == "ul") {
first = false
SKIP
} else {
PASS
}
}.ul { block() }
}
val a = createInnerUL {
li { +"one" }
li { +"two" }
li {
ul {
li {
+"two-a"
}
}
}
}
println(a)
<li>one</li>
<li>two</li>
<li>
<ul>
<li>two-a</li>
</ul>
</li>