Lift Web Framework DRY dispatch
I have an Image class:
class Image extends LongKeyedMapper[Image] with IdPK with Logger {
which overrides toH开发者_高级运维tml method:
override def toHtml =
<img src={"/gallery/image/%s/%s/%s/%s" format (slug.is, "fit", 100, 100)} />
and it works beacause of this:
def dispatch = {
LiftRules.dispatch.append {
case Req("gallery" :: "image" :: slug :: method :: width :: height :: Nil, _, _) => {
() => Image.stream(slug, method, width, height)
}
}
}
As you can see this is not DRY approach, since you have to define the URL (/gallery/image) twice.
Is it possible to make it DRY? Can you get the path from LiftRules or something?
Thanks in advance, Etam.
This was answered by David Pollak on the lift list:
https://groups.google.com/d/topic/liftweb/VG0uOut9hb4/discussion
In short, you:
encapsulate the things in common (in this case, the path) in an object:
object ImageGallery {
val path = "gallery" :: "image" :: Nil
val pathLen = path.length
def prefix = path.mkString("/", "/", "/")
}
create a custom unapply method that allows you to use the object in the pattern match in your dispatch method.
object ImageGallery {
// ...
def unapply(in: List[String]): Option[List[String]] =
Some(in.drop(pathLen)).filter(ignore => in.startsWith(path))
}
Your code is now:
<img src={ImageGallery.prefix+"%s/%s" ...}>
...and:
case Req(ImageGallery(slug :: method :: width :: height :: _), _, _) => // ...
See the message thread for more suggestions.
精彩评论