Skip to content

Instantly share code, notes, and snippets.

@jroper
Created March 5, 2015 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jroper/656ccb99ea18bce5e983 to your computer and use it in GitHub Desktop.
Save jroper/656ccb99ea18bce5e983 to your computer and use it in GitHub Desktop.
ERQX router before and after Play 2.4 upgrade
class BlogRouter(controller: BlogController) extends SimpleRouter {
object ? { def unapply[A](a: A) = Some(a, a) }
def routes = {
// Index
case GET(p"/" | p"") ? Page(page) => controller.index(page)
// View single blog post
case GET(p"/${int(year)}<\d{4}>/${int(month)}<\d{2}>/${int(day)}<\d{2}>/$permalink.html") =>
controller.view(year, month, day, permalink)
// By date
case GET(p"/${int(year)}<\d{4}>.html") ? Page(page) =>
controller.year(year, page)
case GET(p"/${int(year)}<\d{4}>/${int(month)}<\d{2}>.html") ? Page(page) =>
controller.month(year, month, page)
case GET(p"/${int(year)}<\d{4}>/${int(month)}<\d{2}>/${int(day)}<\d{2}>.html") ? Page(page) =>
controller.day(year, month, day, page)
// By tag
case GET(p"/tags/$tag.html") ? Page(page) => controller.tag(tag, page)
// Atom feed
case GET(p"/atom.xml") => controller.atom()
// Fetch
case POST(p"/fetch/$key") => controller.fetch(key)
// Assets
case GET(p"/$path*") => controller.asset(path)
}
}
object BlogPaths {
val PostPattern = """/(\d{4})/(\d{2})/(\d{2})/([^/]+)\.html""".r
val YearPattern = """/(\d{4})\.html""".r
val MonthPattern = """/(\d{4})/(\d{2})\.html""".r
val DayPattern = """/(\d{4})/(\d{2})/(\d{2})\.html""".r
val TagPattern = """/tags/([^/]+)\.html""".r
val FetchPattern = """/fetch/([^/]+)""".r
val WebJarAssetsPattern = "/_assets/lib/(.*)".r
object ToInt {
def unapply(s: String): Option[Int] = try {
Some(s.toInt)
} catch {
case e: NumberFormatException => None
}
}
object Decode {
def unapply(s: String) = Some(UriEncoding.decodePathSegment(s, "UTF-8"))
}
def getPage(implicit req: RequestHeader): Page = {
Page(
req.getQueryString("page") match {
case Some(ToInt(p)) => p
case _ => 1
},
req.getQueryString("per_page") match {
case Some(ToInt(p)) => p
case _ => 5
}
)
}
}
class BlogRouter(controller: BlogController, path: String) extends Routes {
import BlogPaths._
def documentation = Nil
def routes = Function.unlift { implicit req =>
// Don't match more than we need to
if (req.path.startsWith(prefix) || req.path == path) {
val subPath = req.path.drop(path.length)
(req.method, subPath) match {
// Index
case ("GET", "/" | "") =>
Some(controller.index(getPage))
// View single blog post
case ("GET", PostPattern(ToInt(year), ToInt(month), ToInt(day), Decode(permalink))) =>
Some(controller.view(year, month, day, permalink))
// By date
case ("GET", YearPattern(ToInt(year))) =>
Some(controller.year(year, getPage))
case ("GET", MonthPattern(ToInt(year), ToInt(month))) =>
Some(controller.month(year, month, getPage))
case ("GET", DayPattern(ToInt(year), ToInt(month), ToInt(day))) =>
Some(controller.day(year, month, day, getPage))
// By tag
case ("GET", TagPattern(Decode(tag))) =>
Some(controller.tag(tag, getPage))
// Atom feed
case ("GET", "/atom.xml") =>
Some(controller.atom())
// Fetch
case ("POST", FetchPattern(Decode(key))) =>
Some(controller.fetch(key))
// Assets
case ("GET", path) =>
Some(controller.asset(path.drop(1)))
case _ => None
}
} else {
None
}
}
def setPrefix(prefix: String) = {}
val prefix = path + "/"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment