Reputation: 727
Are there any examples of large multi module play framework (Scala) applications. For example, using multiple visual themes and serving different content based on theme. What is the best way to organise code for such applications.
Upvotes: 0
Views: 469
Reputation: 213
I think there are two distinct points in your question :
The first point is quite simple, although it's not clearly (AFAIK) documented in the online documentation. A play! module is built like a regular play application but without any configuration file. So basically, remove the conf/
folder of any application, publish it in your favorite repository, and you're ready to use that module as a dependency in another application/module.
The second point is a little trickier. Since play templates are statically compiled, changing views at runtime is something that is not supported out of the box, you'll have to come up with your own solution.
A first solution would be to use a different template engine, one that interprets templates at runtime this blog post explains how to use the scalate template engine in a play 2.X application.
Another solution would involve the use of runtime reflexion to select the right template at runtime, but at the expense of loosing some of the compile time safeguards (if the needed template is not present you'll have a runtime error, and not a compile time error like in a regular application).
A third solution would be to abstract templates and routes from your controllers (making them traits or abstract class) in a parent module, and then create one child application per different theme, each child application would only have to implement the abstract controller by providing the needed templates and routes :
// in the parent module
trait AbsCtrl extends Controller {
val indexTemplate : (Foo, Bar) => Html // a template is like a function
// from some models to Html
val errorRoute : Call
def index() = Action {
request =>
val foo = Foo()
val bar = Bar()
if(someCondition) Ok(indexTemplate(foo, bar))
else Redirect(errorRoute)
}
}
// in the child module
object Ctrl extends AbsCtrl {
// assuming you have a scala template named index that take the right arguments
override val indexTemplate = views.html.index.render
override val errorRoute = routes.Application.error()
}
This solution is a bit more involved, it requires to have one application per theme which may not be acceptable in some contexts, but it retains the compile time safety, so it might be preferable compared to the previous one.
Last, you can choose to split your system in two different layers :
You can use another technology to write the later one, for example, a simple node.js server that will let you leverage a javascript based template engine.
Upvotes: 3