Reverse routes
URL support and reverse routes
ScalatraBase
provides two instances that provide you with relative URLs.
The url
method will return a string that can be used in your output or a
redirect statement.
In Scalatra 2.0.x, you used to need to extend the UrlSupport
trait, but
that’s now been moved into ScalatraBase
, so all you need is:
class MyApp extends ScalatraServlet {
}
Page relative url:
get("/"){
// This will redirect to http://<host>/page-relative
redirect(url("page-relative"))
}
Context relative url:
get("/"){
// This will redirect to http://<host>/<context>/context-relative
redirect(url("/context-relative"))
}
Mapped params:
get("/") {
// This will redirect to http://<host>/<context>/en-to-es?one=uno&two=dos
redirect( url("/en-to-es", Map("one" -> "uno", "two" -> "dos")) )
}
Reverse routes:
It is possible to save your routes as variables so that they have convenient handles:
class MyApp extends ScalatraServlet with UrlGeneratorSupport {
// When you create a route, you can save it as a variable
val viewUser = get("/user/:id") {
// your user action would go here
}
post("/user/new") {
// url method provided by UrlGeneratorSupport. Pass it the route
// and the params.
redirect(url(viewUser, "id" -> newUser.id))
}
}
There’s also a ScalateUrlGeneratorSupport
. It reflectively finds all
members of your app of type Route (e.g., viewUser above) and makes them
available in your templates. You should then be able to do something like this
right in your templates:
url(viewUser, "id" -> 1)
Note that there is potential for method names to collide if you have reverse-routes with the same variable names in different servlets. This could result in generation of incorrect urls. Ensure reverse-route variable names are unique across all your servlets to prevent this.