Play 2.6: variables in twirl templates

2,697 views
Skip to first unread message

David

unread,
May 13, 2017, 10:34:59 AM5/13/17
to Play Framework
I might be missing something but how does one declare a variable in a Play 2.6 template?
Play 2.5 allows things like: 

@import java.math.BigInteger; var i=0

After upgrading to 2.6, I get the following compilation error:

[error] /project/app/views/repositoryLister.scala.html:2: expected class or object definition
[error] @import java.math.BigInteger; var i: BigInteger = 0
[error]                                                   ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed


Greg Methvin

unread,
May 13, 2017, 2:50:28 PM5/13/17
to play-framework
I am not aware of that ever being a feature. Did you see it documented somewhere? The parser was improved in twirl 1.3 which may have eliminated weird edge cases like this.


You can also use var within a block of code:
@{
  var x = 1
  // do something with x anywhere in this block
}

or define reusable blocks:
@x = { "foo" }
x is @x

Templates are meant to be stateless so it really doesn't make sense to declare a variable within a template.

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/67238056-3ab3-4170-994d-523a6a0c6ad0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Tech Lead - Play Framework

David

unread,
May 13, 2017, 3:34:24 PM5/13/17
to Play Framework
Hi Greg,

Thanks, I guess I will have to rewrite that part of my code.

I don't remember where I saw that. I had this code working for a while.
I can see it mentioned in various stackoverflow threads and other sources from 2014 and after: 

So, I am probably not the only one to have used this "feature". Can a sentence about this be added to the migration guide?

Best,

David

On Saturday, May 13, 2017 at 8:50:28 PM UTC+2, Greg Methvin wrote:
I am not aware of that ever being a feature. Did you see it documented somewhere? The parser was improved in twirl 1.3 which may have eliminated weird edge cases like this.


You can also use var within a block of code:
@{
  var x = 1
  // do something with x anywhere in this block
}

or define reusable blocks:
@x = { "foo" }
x is @x

Templates are meant to be stateless so it really doesn't make sense to declare a variable within a template.
On Sat, May 13, 2017 at 7:34 AM, David <massar...@gmail.com> wrote:
I might be missing something but how does one declare a variable in a Play 2.6 template?
Play 2.5 allows things like: 

@import java.math.BigInteger; var i=0

After upgrading to 2.6, I get the following compilation error:

[error] /project/app/views/repositoryLister.scala.html:2: expected class or object definition
[error] @import java.math.BigInteger; var i: BigInteger = 0
[error]                                                   ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed


--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Greg Methvin

unread,
May 13, 2017, 3:55:57 PM5/13/17
to play-framework
We can add something to the migration guide. It would probably be best for you or someone else who used it to do that, since you better understand the use case. If I have some examples of its use I can suggest an alternative.

To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/cf215ba3-79d7-420c-84d5-53ea6aa4fdc7%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

David

unread,
May 13, 2017, 4:54:47 PM5/13/17
to Play Framework
I don't know if my use case is really representative.

In my app, a Seq is passed to a template:

@import play.api.libs.json.JsObject

@(reps: Seq[JsObject])


The content of this Seq is used to fill an html table where one wants to distinguish between even and odd rows

With Play 2.5, a variable 'i' was used as follows:

@import play.api.libs.json.JsObject

@import java.math.BigInteger; var i=0

@(reps: Seq[JsObject])


...

     <table>

...

     @for(rep <- reps) {

    @(i+=1)

@if((i % 2) == 0) { <tr class="even"> } else { <tr> }

<td>@{(rep \ "_id").as[String]}</td>

...

With Play 2.6, I had to change it to

@import play.api.libs.json.JsObject

@(reps: Seq[JsObject])


...

     <table>

...

     @for( i <- 0 to (reps.length - 1) ) {

    @if((i % 2) == 0) { <tr class="even"> } else { <tr> }

<td>@{(reps(i) \ "_id").as[String]}</td>







Greg Methvin

unread,
May 13, 2017, 5:13:42 PM5/13/17
to play-framework
Oh okay. You just need:

@for((rep, i) <- reps.zipWithIndex) {
  <tr @if(i % 2 == 0){class="even"}>
    <td>@{rep \ "_id"}</td>
    ...
  </tr>
}

But actually if I were you I would just use :nth-child(even) in CSS, since I'm assuming the class is an entirely presentational thing: https://www.w3schools.com/cssref/sel_nth-child.asp. (Unless you need this to work on IE<9.)

To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/365a882e-ab6c-4a82-8bde-c016a6f97f7c%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

David

unread,
May 13, 2017, 6:45:30 PM5/13/17
to Play Framework

Will Sargent

unread,
May 15, 2017, 12:24:18 PM5/15/17
to play-fr...@googlegroups.com
As Greg said, the best way to declare variables is to use a @defining block or page fragments:

@defining(foo.bar) { bar: Bar =>

}

or create barFragment.scala.html and do:

@barFragment(foo.bar)

Hope that helps,
Will.

--
Will Sargent
Engineer, Lightbend, Inc.


To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/8da41650-ee41-4980-aadf-fa95368bc5a7%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages