Open bitspittle opened 1 year ago
Probably worth looking at Compose Navigation as well: https://developer.android.com/jetpack/compose/navigation in case there's anything worth borrowing from their approach
That people still have to find their own way to deal with external URLs makes me think that this is not something kobweb should handle. Unless there is an option to add custom URLs. Also, you would have to consider query parameters, which in contrast to compose navigation can only be strings anyway.
object Routes {
const val login = "/login"
fun video(id: Int) = "/video?id=$id"
}
Something like this works for me right now
I'm still on the fence whether this feature is worth doing or not. You're right that external URLs would be raw strings anyway.
The main benefit I could see is if you used this and your site got big and then someone changed some routes around, this could give you a compile error instead of a runtime error later that would be easier to miss.
Actually, methods might solve the problem I was worrying about before with name conflicts?
Imagine for my setting example we would generate this:
object Routes {
fun setting(vararg params: Pair<String, Any>) = ...
object setting {
fun admin(vararg params: Pair<String, Any>) = ...
}
}
Now, the settings
method and the settings
object don't conflict.
One more idea: the inner objects could be capitalized, which would give us more flexibility too:
object Routes {
fun setting(vararg params): String = ...
fun setting(fragment: String, vararg params): String = ...
val setting: String = ...
object Setting {
fun admin(...) = ...
fun admin(fragment, ...) = ...
val admin = ...
}
}
Then the question is if people would be OK with the route settings/admin
translating to Routes.Settings.admin
or if the mixed capitalization is weird...
It would also be possible to do something like this:
interface Route { fun toRouteString() }
fun Link(path: String, text: String) // Already exists
fun Link(route: Route, text: String) = Link(route.toRouteString(), text) // New version
// Assume pages defined for blog/about, settings, and settings/admin
object Routes {
object blog {
object about : Route {
override fun toRouteString("blog/about")
}
}
object setting : Route {
override fun toRouteString("setting")
object admin : Route {
override fun toRouteString("setting/admin")
}
}
}
I haven't written the code down, but I'm hoping this could allow both: Link(Routes.setting)
and Link(Routes.setting.admin)
and also Link(Routes.blog.about)
but not Link(Routes.blog)
Currently, if you want to link to different routes, you have to do it by String, e.g.
But it could be nice to have type-safe destinations as well, so the code might look like this:
Technically, it shouldn't be too hard to do, but designing this right may requires some thinking.
Some issues to consider off the top of my head:
/1/2/3
would probably correspond toKobwebRoutes._1._2._3
/1
and/_1
could be different routes but would both translate toKobwebRoutes._1
settings
andsettings/admin
are both valid routes, but you can't have some Kotlin object that supports bothKobwebRoutes.settings
as a string but alsoKobwebRoutes.settings.admin
at the same timeKobwebRoutes.settings
andKobwebRoutes.settings_admin
? Is that ugly?kobweb { ... }
block setting OR just make the logic for generating this file be a separate task that people can run manually