The core module of Vaadin-on-Kotlin. Always included in your project, usually transitively via one of the other VoK modules.
This module is intentionally minimal: it provides the VoK runtime bootstrap, an async executor, an i18n bundle, a
Session helper, and a Cookies accessor. There is no DB dependency here — that lives in
vok-framework-vokdb, which wires in ktorm + ktorm-vaadin.
Typically called from a ServletContextListener (or whatever boot hook your container provides):
@WebListener
class Bootstrap : ServletContextListener {
override fun contextInitialized(sce: ServletContextEvent?) {
VaadinOnKotlin.init()
}
override fun contextDestroyed(sce: ServletContextEvent?) {
VaadinOnKotlin.destroy()
}
}Other VoK modules tend to add fields to the VaadinOnKotlin object. For example vok-framework-vokdb adds
VaadinOnKotlin.dataSource — assigning a HikariDataSource to it also wires ActiveKtorm.database so ktorm
queries work immediately.
You can call Bootstrap().contextInitialized(null) from @BeforeAll and Bootstrap().contextDestroyed(null) from
@AfterAll. Since this fully initializes the VoK runtime (including the database access if vok-framework-vokdb
is on the classpath), tests can hit the real DB without any mocking. For non-H2 backends, spin up a Dockerized
PostgreSQL/MySQL/etc. before the test suite and tear it down after — the test code itself doesn't change.
The internationalization of strings used by VoK (e.g. error messages) is driven by ResourceBundles. See
I18n.kt for details.
The following bundles are searched:
VokMessages*.propertiesin the root package — create one to override VoK's defaults for your app.- The default
eu.vaadinonkotlin.VokMessages*.propertiesif nothing app-specific matches.
See the Translating Your App guide for more.
This module no longer ships a FilterBar DSL. Filter components live in ktorm-vaadin and are pulled in through
vok-framework-vokdb:
import com.github.mvysny.ktormvaadin.filter.FilterTextField
import com.github.mvysny.ktormvaadin.filter.DateRangePopup
import com.github.mvysny.ktormvaadin.filter.NumberRangePopup
import com.github.mvysny.ktormvaadin.filter.BooleanFilterFieldYou wire them into a Grid header row manually and combine their values into a ktorm
ColumnDeclaring<Boolean> filter that you hand to the data provider via setFilter(...). The
PersonListView in the demo and
the EmployeesRoute
in ktorm-vaadin's test app are the canonical end-to-end examples.
Provides a Session object that wraps VaadinSession:
Session.current— the currentVaadinSession.Session["key"] = value— store/retrieve values keyed by string.Session[MyService::class] = MyService()— store a session-scoped service.Session.getOrPut(MyService::class) { MyService() }— the idiomatic way to lazily attach a session-scoped service:
class LoggedInUser : Serializable {
var user: User? = null
private set
val isLoggedIn: Boolean get() = user != null
fun login(username: String, password: String) {
val u = User.findByUsername(username) ?: throw LoginException("No such user $username")
if (!u.validatePassword(password)) throw LoginException("$username: invalid password")
user = u
}
fun logout() { user = null; Session.current.close() }
}
val Session.loggedInUser: LoggedInUser get() = getOrPut(LoggedInUser::class) { LoggedInUser() }Session.loggedInUser.login(...) is now usable from anywhere — no DI needed.
Note: the session is only accessible from code holding the Vaadin UI lock. Background threads must call
ui.access {}.
There is a Cookies singleton for cookie access on the current request:
Cookies += Cookie("autologin", "secret")— add a cookieCookies.delete("autologin")— remove a cookieCookies["autologin"]— read a cookie