Reputation: 278
I'm wandering if there is a way to do a regex inside the routes file, where the path may contain alphanumerics, but only the number is passed to the controller. So for example: http://example.com/person/Jay-Z-12344 would resolve properly.
GET /person/$id<[\d]+> controllers.App.person(id:Long)
Thanks for your help!
Upvotes: 0
Views: 117
Reputation: 1339
You'll just need to override Global.onRouteRequest
to modify the URL before passing the request through to the routes, or call the controller directly.
To the controller directly:
object PersonIdRouteExtractor {
private[this] val Pattern = """/person/[^0-9]*([\d]*)""".r
def unapply(req: Request): Option[Long] = {
req.path match {
case Pattern(path) ⇒ Try(path.toLong).toOption
case _ ⇒ None
}
}
}
override def onRouteRequest(req: RequestHeader): Option[Handler] = {
(req.method, req.path) match {
case ("GET", PersonIdRouteExtractor(id)) ⇒ Some(controllers.App.person(id))
case _ ⇒ super.onRouteRequest(req)
}
}
Modifying the request path with default routes:
object PersonRouteTransformer {
private[this] val Pattern = """/person/[^0-9]*([\d]*)""".r
def unapply(req: Request): Option[String] = {
req.path match {
case Pattern(id) ⇒ Some(s"/person/$id")
case _ ⇒ None
}
}
}
override def onRouteRequest(req: RequestHeader): Option[Handler] = {
(req.method, req.path) match {
case ("GET", PersonRouteTransformer(xpath)) ⇒ super.onRouteRequest(req.copy(path = xpath) // not sure if you need to do the uri too?
case _ ⇒ super.onRouteRequest(req)
}
}
This could be cleaner and refactored for better reusability but you get the idea. Also check out James Roper's blog post about Advanced routing in Play Framework
Upvotes: 1
Reputation: 1446
You can use Regex inside the routes but I think it is only for matching. You cannot replace the dynamic part.
Upvotes: 1