Scala PlayFrameWork 2.04: Get pages dynamically

So you want to generate a page dynamically parsing the url. You could use a map or some hard coded matches. But i prefer to use Java reflection inside Scala.

The code

The HTTP routing file: Routes

GET     /:page       controllers.Director.index(page: String)

The controller: Director.scala

</pre>
package controllers

import play.api._
import play.api.mvc._
import play.api.data._
import play.api.data.Forms._
import views._
import models._
import java.util.Properties
import play.api.Play.current
import play.api.libs.iteratee.Enumerator
import java.lang.reflect.Method
import play.api.templates.Html
import models._
import play.api.http.Writeable

object Dynamic {

def render(keyword: String): Option[play.api.templates.Html] = {
 renderDynamic("views.html." + keyword)
 }

def renderDynamic(viewClazz: String): Option[play.api.templates.Html] = {
 try {
 val clazz: Class[_] = Play.current.classloader.loadClass(viewClazz)
 println(clazz.getMethods())
 val render: Method = clazz.getDeclaredMethod("render", classOf[String])
 val view = render.invoke(clazz, "test").asInstanceOf[play.api.templates.Html]
 return Some(view)
 } catch {
 case ex: ClassNotFoundException => Logger.error("Html.renderDynamic() : could not find view " + viewClazz, ex)
 }

return None
 }
}

object Director extends Controller with Secured {

def index(clazz: String) = Action {

 Dynamic.render(clazz) match {
 case Some(i) => Ok(i)
 case None => NotFound
 }
 }
}
<pre>

As you can see i used reflection by using following method: “Play.current.classloader.loadClass(viewClazz)”. Now that i have the class, i can look up the declared methods (Notice the parameters) “clazz.getDeclaredMethod(“render”, classOf[String])”.
Then we are going to invoke it with the params by doing “invoke(clazz, “test”)”. Where “test” is the param of the method. And is actually the @title in the Play! html template below:

The view: template1.html.scala
</pre>
@(title:String)
@main(title){
 <div class="content">
 Here we put some content. .......

 </div>

}
<pre>
Advertisements
Leave a comment

1 Comment

  1. Inspirational! I extended this example into a generic PartialView controler implementation: Full Source: https://gist.github.com/ntbrock/6049260

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: