URL Routing
In a web application, routing is the process of using URLs to drive the user interface (UI). URLs are a prominent feature in every web browser, and have several main functions:
- Bookmarking - Users can bookmark URLs in their web browser to save content they want to come back to later.
- Sharing - Users can share content with others by sending a link to a certain page.
- Navigation - URLs are used to drive the web browser's back/forward functions.
Traditionally, visiting a different URL within the same website would cause a new page to be downloaded from the server, but current state-of-the-art websites are able to modify the page in response to URL changes without a full refresh.
With Kweb's routing mechanism you get this automatically.
A simple example
import kweb.Kweb
import kweb.dom.element.new
import kweb.dom.element.creation.tags.h1
import kweb.routing.route
fun main() {
Kweb(port = 16097) {
doc.body {
route {
path("/users/{userId}") { params ->
val userId = params.getValue("userId")
h1().text(userId.map { "User id: $it" })
}
path("/lists/{listId}") { params ->
val listId = params.getValue("listId")
h1().text(listId.map { "List id: $it" })
}
}
}
}
}
Now, if you visit http://localhost:16097/users/997, you will see:
User id: 997The value of these parameters can then be retrieved from the params
map, but note that the values are wrapped in a KVar<String>
object.
This means that you can use all of Kweb's state
management features to
render parts of the DOM using this value.
The key advantage here is that if the URL changes the page can be updated without a full page refresh, but rather only changing the parts of the DOM that need to change - this is much faster and more efficient.
Handing 404s
You can override the default 404 Page Not Found message in the event that none of the routes match, making it easy to integrate the 404 page with the style of your overall website:
route {
path("/users/{userId}") { params ->
// ...
}
notFound {
h1().text("Page not found!")
}
}
Modifying the URL
You can obtain and modify the URL of the current page using WebBrowser.url.
This returns a KVar<String>
which contains the URL relative to the
origin - so for the page http://foo/bar/z
the url
would be /bar/z
.
This KVar will update accordingly if the URL changes, and can also be
modified itself, which will change the URL.
Here is a more realistic example which demonstrates this:
import kweb.Kweb
import kweb.dom.element.creation.tags.a
import kweb.dom.element.new
import kweb.routing.route
import kweb.state.*
fun main() {
Kweb(port = 16097) {
doc.body {
route {
path("/") {
url.value = "/number/1"
}
path("/number/{num}") { params ->
val num = params.getValue("num").toInt()
a().text(num.map {"Number $it"}).on.click {
num.value++
}
}
}
}
}
}
If you visit http://localhost:16097/
the URL will immediately update
to http://localhost:16097/number/1
without a page refresh, and you'll
see a hyperlink with text Number 1
. If you click on this link you'll
see that the number increments (both in the URL and in the link text),
also without a page refresh.
num.value++
is worthy of additional attention. num
is a KVar<Int>
converted from the KVar<String>
supplied as a parameter. Because of this
it can be incremented via its value
property.
This change will propagate back causing the URL to update, which will in-turn cause the DOM to update to reflect the new URL. All of this is handled for you automatically.