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.
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.
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 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>
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
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>