Closed wedens closed 7 years ago
There's already work in progress on this, but it's not possible yet. I'm currently removing the untyped routing and after that refactoring I will implement this.
I've started writing routes standalone like:
usersRoute = "admin" <//> "users"
userRoute = usersRoute <//> (var :: Var UserId)
deleteUserRoute = userRoute <//> "delete"
and then using this routes in spock application:
get usersRoute usersAction
post usersRoute newUserAction
post deleteUserRoute deleteUserAction
with this approach I'm able to re-use this routes for reverse-routing (e.g. in templates).
Yes, that's the idea! The problem is that this will not work properly for subcomponents (yet). I'll have to find a good solution for this first...
I find myself wanting the same thing. Is this a feature solvable by someone else other than @agrafix, or is it deeply routed in the library internals such that it would take quite a while for someone unfamiliar with spock-core to contribute this functionality?
@tdietert : Personally I would discourage using subcomponents
all the way, because they break route referencing and reusability. If you still would like to implement this, I think the proper way to do would be using the contexts feature because otherwise with the syntax from above it will make the routing tree somewhat dynamic.
@agrafix: What do you mean by "using subcomponents
all the way, because they break route referencing and reusability"? If you don't agree that this is a good thing to do, my first instinct is to trust the library author.
If you define your routes like @wedens describes:
usersRoute = "admin" <//> "users"
userRoute = usersRoute <//> (var :: Var UserId)
deleteUserRoute = userRoute <//> "delete"
You can wire them in your server:
do get usersRoute usersAction
post usersRoute newUserAction
post deleteUserRoute deleteUserAction
But also use them to actually render them in the frontend/templates:
renderRoute userRoute (UserId 5) -- returns: /admin/users/5
If you'd put a subcomponent into your wiring logic above, then renderRoute would return the wrong route.
It will also make it possible to share the APIs between client and server (see https://www.spock.li/2016/08/25/shareable-apis.html ).
I will add a warning/notice about this in the docs. If you use the routes like described here, you can still come pretty close to this because routes are composable:
-- routes:
myBaseRoute = "basic" <//> "route" <//> var
mySpecialRoute = myBaseRoute <//> "special"
myOtherSpecialRoute = myBaseRoute <//> "other" <//> var
-- hooking in server:
do get mySpecialRoute $ \v1 -> undefined
get myOtherSpecialRoute $ \v1 v2 -> undefined
For that reason, this I will mark this as "wont fix" and try to document better what the alternative would look like.
It'd be nice to be able to be able to nest routes with variables:
Probably it's already possible, but I don't understand how.