Question

I've got an app using the Play! framework. I'm binding variables to templates and building on what could be a life-saver trait for Play!: https://github.com/asinghal/Play-ScalaGen/blob/master/misc_utils/EmailNotifier.scala

var templateHtmlBinding = new java.util.HashMap[String, Object]()
    var templateTextBinding = new java.util.HashMap[String, Object]()

    for (o <- args) {
      val names = LocalVariablesNamesTracer.getAllLocalVariableNames(o).toList
      for (name <- names) {
        templateHtmlBinding += (name -> o)
        templateTextBinding += (name -> o)
      }
    }

The issue is that when you do a getAllLocalVariableNames on line 155 the entire list returns empty. I can confirm that the objects passed into the function are not null as verified by printing them out inside the function. I'm wondering if there's something wrong using this in Scala or if anyone knows of a reflection method that could do the job?

Edit

I'm trying a little reflection but my reflection knowledge is somewhat limited. A sample:

val names = o.getClass.getMethods.toList.map(_.toString)

Output from a sample object passed in:

List(public java.lang.String models.Account.name(), public static final scala.Op
tion models.Account.get(long), public boolean models.Account.equals(java.lang.Ob...

Any idea how to filter this further?

Second Edit

I've gotten this far which successfully produces a list of each object and its properties, but unfortunately it still triggers the same error with a populated list:

val oname = o.getClass.getName.replaceAll("models.","").toLowerCase
val names = o.getClass.getDeclaredFields.toList.map(_.getName.toString).map(oname+"."+_)

gives:

List(account.id, account.name, account.address,...

Any insight on where something is going wrong in the Play! templating?

Was it helpful?

Solution

As in Edit 2 I was able to get the property names of every object passed in. However, the problem I had was actually caused by the class itself, so I modified a couple things to fix it. I created this:

for ((name:String, o:Object) <- args) {
  templateHtmlBinding += (name -> o)
  templateTextBinding += (name -> o)
}

and replaced lines 153-159:

for (o <- args) {
      var names = LocalVariablesNamesTracer.getAllLocalVariableNames(o).toList
      for (name <- names) {
        templateHtmlBinding += (name -> o)
        templateTextBinding += (name -> o)
      }
    }

It looks like you just can't get variable names if you want to expand outside of Play! controllers and get messy. So a fix is to simply pass in the template variable names like this:

mail.send("app/views/Mails/invite", "account"->account, "user"->user )

and reference in your template like:

${account.name}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top