https://kotlinlang.org logo
Join SlackCommunities
Powered by
# kotlinx-html
  • a

    Alex Fairley

    02/14/2024, 3:07 PM
    Hey guys, I am building a html file using kotlinx. I am doing something like this
    val htmlString = buildString {
    appendHTML().html {
    // build html here
    }
    }
    but the html file is getting to long for StringBuilder to handle and I am running out of java heap space. Aside from allocating more heap space to my process would another (stream based) approach work?
    c
    • 2
    • 3
  • a

    Alex Fairley

    02/15/2024, 3:56 PM
    In the kotlinx documentation it mentions Streaming to System.out for example. Does the appendHTML() function append each html tag on the fly i.e. line by line? For example if I generate the following html using kotlinx.html
    Copy code
    <div class="a">
      <div class="b">
        <div class="c"></div>
        <div class="c"></div>
      </div>
    </div>
    How does appendHTML() work? Does it wait for a tag to be closed before appending or does it append everytime it encounters a new tag (the latter behaviour would be desired for my use case)
  • r

    Reuben Firmin

    04/13/2024, 7:50 PM
    anybody have a technique to allow building a fragment with the dsl, but get back an HTMLTag (i.e. a consumer that builds a tag hierarchy rather than a string)? i'm looking at implementing support for hx-swap-oob, a feature of htmx; it allows you to add supplementary tags to the response which get swapped with other parts of the dom from the main element that you're targeting. (e.g. maybe you want to update a bunch of existing table cells selectively.) to do this i need to add an attribute (and an id) to the container for each of the tags that i'm adding; i want to provide this as a mostly automatic feature for callers of this function. since i can't add an id and attribute to a string, i need to get back an HTMLTag (or, actually, the very weirdly named CommonAttributeGroupFacade, because i need to set id) at the point at which i'm composing everything together. i.e. i want something like this in my library:
    Copy code
    data class AuxResponse(val target: HTMXTarget, val tag: TagConsumer<*>.() -> CommonAttributeGroupFacade)
    
        fun render(target: HTMXTarget,
                   vararg composed: AuxResponse,
                   block: FlowContent.() -> Unit): Response {
    which ideally users of the library could call with:
    Copy code
    render(someTarget, 
        AuxResponse(someOtherTarget) { 
           some_adapter {
             p {
                +"Hello world supplemented"
             }
           }
        )) {
            p {
               +"Hello world main"
            }
    a
    • 2
    • 6
  • r

    Reuben Firmin

    04/22/2024, 5:07 PM
    The K2 mode in the new Intellij version breaks the html -> kotlinx.html plugin. For me this is a big issue and will force me to stay on the old version of Intellij - when making components, I rely on being able to paste FlowBite/Tailwind html chunks and have them be converted. It would be a lot slower if I had to type them out
    e
    • 2
    • 2
  • m

    Mario Palka

    05/29/2024, 7:42 PM
    Hello, stupid queastion, but why
    li
    is unresolved reference?
    c
    • 2
    • 3
  • k

    Kirill Gagarski

    05/30/2024, 11:27 PM
    Is it possbile to generate a boolean attribute for a tag from kotlinx.html. Meaning, is that possible to produce the following code:
    Copy code
    <label><input type=checkbox checked name=cheese disabled> Cheese</label>
    I am aware about
    checked="checked"
    or
    checked=""
    options and how to do it with kotlinx.html, but I want the exact syntax as above in the output
    c
    • 2
    • 1
  • a

    Anders Sveen

    06/11/2024, 12:00 PM
    Hi! Started using the HTML DSL with KTor and wondering if people have some solutions for some things I would like to do: • Is there a way to ensure binding between an object, HTML form and form submit? Showing existing values, binding new values from submit. Or do you just do that manually? • Any good way to do validations, preferrably bound to the object, something like javax.validation would be nice.
  • c

    Cies

    06/11/2024, 2:55 PM
    We use a library we made ourselves to convert www-url-encoded form submits to a Jackson-internal representation of JSON, which Jackson can the type coerce into a data class that we call a
    FormDto
    . The library sets a standard for the names (the
    name
    attribute on HTML form fields) so they can be used to provide a structure to the data.
    a
    • 2
    • 22
  • c

    Cies

    06/11/2024, 2:55 PM
    For validation we use Konform, but since then there's a new kid on the block.
  • c

    Cies

    06/11/2024, 2:56 PM
    https://akkurate.dev/docs/overview.html
    👀 1
  • a

    Ahmed

    07/12/2024, 6:09 PM
    Please give me some advices as just started using html and css dsl for server side rendering, with htmx along with spring boot,
    c
    • 2
    • 1
  • a

    Ahmed

    07/14/2024, 2:10 AM
    Is there a library to generate js on jvm, Just like html and css
    r
    c
    • 3
    • 2
  • b

    Bernhard

    07/20/2024, 10:24 PM
    is there a way to create an html string using this library? instead of using an html file, I'd like to inline it's content in typesafe HTML, starting with a div tag
    ✅ 1
    c
    • 2
    • 3
  • m

    Mario Andhika

    08/06/2024, 2:18 AM
    What are the pros and cons of kotlinx HTML vs Thymeleaf?
    c
    m
    m
    • 4
    • 18
  • r

    robnik

    08/15/2024, 3:00 PM
    How do you translate this, specifically that attribute with no value?
    Copy code
    <link rel="preconnect" href="<https://fonts.gstatic.com>" crossorigin>
    This guess doesn't work (crossorigin is not a parameter).
    Copy code
    link(rel="preconnect", href="<https://fonts.gstatic.com>", crossorigin=true)
    t
    • 2
    • 1
  • c

    Cies

    10/15/2024, 8:31 AM
    Hi @dmcg! I'm not sure this is what you are looking for, but I have responded to a similar question before in this channel with the following snippet from our code base that we use for the rare case that we want to respond with an HTML "snippet" (= just a fragment, no proper HTML document):
    Copy code
    /** 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()
          }
        }
      }
    }
  • c

    Cies

    10/15/2024, 8:32 AM
    I hope this helps, and --especially if it does help-- since this question keeps coming up: we may want to extend the README of this project with some examples to guide users of the lib in the right direction for these common usecases.
  • c

    Cies

    10/15/2024, 8:37 AM
    We are happy users of kotlinx.html, it does have an impact on our compile times, but the added type safety and debugability makes up for it. The only otehr contender we found that was acceptable to us was KTE (=JTE for Kotlin). Since we use Elm for browser apps (and in Elm you write HTML-in-Elm using the eDSL for it), kotlinx.html's approach (writing HTML-in-Kotlin, also an eDSL) serves us really well. Also we use jOOQ, another eDSL, so to our team it feels quite natural to use "thin abstractions" (eDSLs) over other languages.
  • d

    dmcg

    10/15/2024, 9:22 AM
    Thank you. I pulled the following from a project of @Tim Schraepen
    Copy code
    fun partial(block: FlowContent.() -> Unit): String {
        val writer = StringWriter()
        val consumer = writer.appendHTML()
        // hacky stuff so we don't have to return a wrapper div
        object : FlowContent {
            override val consumer = consumer
            override val attributes: MutableMap<String, String>
                get() = mutableMapOf()
            override val attributesEntries: Collection<Map.Entry<String, String>>
                get() = emptyList()
            override val emptyTag: Boolean
                get() = true
            override val inlineTag: Boolean
                get() = true
            override val namespace: String?
                get() = null
            override val tagName: String
                get() = ""
        }.block()
        return writer.toString()
    }
    I don’t know the library well enough to choose between the approaches, but thanks giving for your experience.
  • t

    Tim Schraepen

    10/15/2024, 12:58 PM
    Thank you for mentioning me so that I learn about the existence of this channel!
  • e

    e5l

    10/16/2024, 7:07 AM
    Hey @Cies, thanks for the request. We have prototyped htmx support some time ago and will publish an update soon 🙂
    c
    r
    • 3
    • 5
  • r

    Reuben Firmin

    10/16/2024, 11:37 AM
    Is there a kotlinjs wrapper that's compatible with kotlinx.html on the frontend for doing css? I've been experimenting with frontend kotlinx.html here: https://github.com/reubenfirmin/kdemo.cc, and so far have been using tailwind only for styling (which is fine as far as it goes). https://jetbrains.github.io/kotlin-wrappers/kotlin-styled-next/index.html seems react centric. https://jetbrains.github.io/kotlin-wrappers/kotlin-css/index.html might work, though I'm unclear about how I'd use it other than giving everything a class (which...maybe)
    • 1
    • 1
  • d

    dmcg

    10/18/2024, 2:44 PM
    Thanks for your help with partials - here’s some content in return

    https://youtu.be/Dpnj5qRWLHY▾

    👀 3
    ❤️ 2
    e
    • 2
    • 1
  • a

    Anders Sveen

    11/13/2024, 4:28 PM
    I built a pretty awesome demo of KTor+SSE and HTMX. At least I think so. Have a look. 🙂 https://blog.f12.no/wp/2024/11/11/htmx-sse-easy-updates-of-html-state-with-no-javascript/ Slack Conversation
    K 1
    t
    r
    • 3
    • 4
  • r

    Reuben Firmin

    12/05/2024, 3:49 PM
    I built a demo of using kotlinx.html in frontend code (along with kotlin-css). It's pretty nice - happy to take requests or contributions. https://github.com/reubenfirmin/kdemo.cc
    🔥 2
  • m

    Mikael Ståldal

    01/01/2025, 7:50 PM
    A simple alternative to kotlinx.html, specifically designed to support fragments/partials and htmx: https://github.com/mikaelstaldal/kotlin-html-builder/
    c
    • 2
    • 4
  • m

    Mikael Ståldal

    01/03/2025, 3:24 PM
    How are you supposed to use SVG and MathML in kotlinx.html?
    c
    • 2
    • 1
  • e

    e5l

    01/15/2025, 12:49 PM
    Hey! kotlinx-html 0.12.0 is out: https://github.com/Kotlin/kotlinx.html/releases/tag/0.12.0 Please check it out!
    K 3
    👍 1
  • m

    Mario Andhika

    02/04/2025, 3:02 AM
    Hi! Can kotlinx-HTML be used for parsing HTML?
    🚫 1
    ✅ 1
    a
    c
    • 3
    • 2
  • b

    Bernhard

    03/11/2025, 12:19 PM
    how do I insert an element before another element? .prepend adds a child element to the node, not a node before the element regarding the dom api, this is what I need in a DSL context: .insertAdjacentElement("beforeBegin", element)
    ✅ 1
    c
    • 2
    • 1