Skip to content

celtric/kotlin-html

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CircleCI License Download

kotlin-html

kotlin-html is a library to generate HTML in Kotlin.

This library is heavily inspired by kotlinx.html, but with a strong emphasis on context-independent composability.

Getting started

You can define HTML elements independently from an HTML document. The following code:

p("A paragraph")

will render the following HTML when .render() is called:

<p>A paragraph</p>

Note: all HTML examples in this README are generated after calling .render() on the expression presented in Kotlin. It's encouraged that you keep the number .render() calls to the minimum and instead combine elements to increase your code's expressiveness.

Composability

You can join any number of elements:

p("First paragraph") + p("Second paragraph")

HTML:

<p>First paragraph</p>
<p>Second paragraph</p>

You can also easily interact with list transformations:

val people = listOf("Gael", "Laura", "Ricard")

ul { people.map { li(it) } }

HTML:

<ul>
    <li>Gael</li>
    <li>Laura</li>
    <li>Ricard</li>
</ul>

Working with functions is also straightforward:

ul { numbers() }

fun numbers() = li("One") + li("Two") + li("Three")

HTML:

<ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
</ul>

Attributes

Attributes are optional. If you wish to define them, you must use a block for the content:

p("A paragraph") // Text-only element, cannot contain attributes
p { "A paragraph" } // Equivalent to previous line
p(classes = "a-class") { "A paragraph" } // Same paragraph with "a-class" class

HTML

<p>A paragraph</p>
<p>A paragraph</p>
<p class="a-class">A paragraph</p>

Each element offers some relevant attributes depending on its tag:

a(href = "http://www.example.com/", target = "_blank") { "A link" }
img(src = "/img/logo.png", alt = "Our site")

HTML

<a href="http://www.example.com/" target="_blank">A link</a>
<img src="/img/logo.png" alt="Our site">

In case you wish to define other attributes you can do so using other:

div(other = mapOf("key" to "value")) { "Content" }

HTML

<div key="value">Content</div>

Custom data attributes are also supported:

div(data = mapOf("user" to "celtric")) { "Content" }

HTML

<div data-user="celtric">Content</div>

Text

You can join elements and text:

strong("Strongly") + " disagree"
p(strong("Strongly") + " disagree")

HTML:

<strong>Strongly</strong> disagree
<p><strong>Strongly</strong> disagree</p>

Due to a limitation in Kotlin's overloading capabilities, a native string cannot be the first element in a list:

"foo" + strong("bar") // NOT allowed by Kotlin operator overloading
text("foo") + strong("bar") // Valid Kotlin
strong("foo") + "bar" // Valid Kotlin, as the native string is not the first element

Full example

import org.celtric.kotlin.html.*

fun main(args : Array<String>) {
    val document = doctype("html") + html {
        head {
            title("Document title") +
            meta(charset = "utf-8") +
            link(href = "css/style.css", rel = "stylesheet") +
            script(type = "text/javascript", src = "js/script.js")
        } +
        body {
            div(classes = "container") {
                h1("A title") +
                p(classes = "introduction") {
                    "A paragraph"
                } +
                ul {
                    li(a("http://www.example.com/", "A link")) +
                    li(a("http://www.example.com/", "A second link"))
                }
            }
        }
    }

    print(document.render())
}

HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>Document title</title>
        <meta charset="utf-8">
        <link href="css/style.css" rel="stylesheet">
        <script type="text/javascript" src="js/script.js"></script>
    </head>
    <body>
        <div class="container">
            <h1>A title</h1>
            <p class="introduction">A paragraph</p>
            <ul>
                <li><a href="http://www.example.com/">A link</a></li>
                <li><a href="http://www.example.com/">A second link</a></li>
            </ul>
        </div>
    </body>
</html>