Declare variable in a Play2 scala template

HtmlScalaTemplatesPlayframeworkPlayframework 2.0

Html Problem Overview


How do you declare and initialize a variable to be used locally in a Play2 Scala template?

I have this:

@var title : String = "Home"

declared at the top of the template, but it gives me this error:

illegal start of simple expression """),_display_(Seq[Any](/*3.2*/var)),format.raw/*3.5*/(""" title : String = "Home"

Html Solutions


Solution 1 - Html

@defining("foo") { title=>
  <div>@title</div>
  ...
}

basically, you have to wrap the block in which you are going to use it

Solution 2 - Html

Actually, @c4k 's solution is working (and quite convenient) as long as you don't try to change the variable's value afterwards, isn't it?

You simply place this at the top of your template:

@yourVariable = {yourValue}

or, if it's a more complicated expression, you do this:

@yourVariable = @{yourExpression}

You can even work with things like lists like that:

@(listFromController: List[MyObject])
@filteredList = @{listFromController.filter(_.color == "red")}

@for(myObject <- filteredList){ ... }

For the given example, this would be

@title = {Home}  //this should be at beginning of the template, right after passing in parameters

<h1> Using title @title </h1>

In the comments you said, that it gets typed to HTML type. However, that is only relevant if you try to overwrite @title again, isn't it?

Solution 3 - Html

scala template supports this, you can define variable in template

@import java.math.BigInteger; var i=1; var k=1

if you want to change its value in template

@{k=2}

example

@(title:String)(implicit session:play.api.mvc.Session)
@import java.math.BigInteger; var i=1; var k=1
^
<div id='LContent_div@i'>
                     ^
  <div id='inner_div_@k'></div>
                     ^
</div>

Solution 4 - Html

virtualeyes' solution is the proper one, but there is also other possibility, you can just declare a view's param as usually with default value, in such case you'll have it available for whole template + you'll keep possibility for changing it from the controller:

@(title: String = "Home page")

<h1>Welcome on @title</h1>

controller:

def index = Action{
    Ok(views.html.index("Other title"))
}

Note that Java controller doesn't recognise templates' default values, so you need to add them each time:

public static Result index(){
    return ok(views.html.index.render("Some default value..."));
}

Solution 5 - Html

If you don't want to wrap all your content with @defining, you can do this :

@yourVariable = { yourValue }

The @defining directive is really unreadable in a template...

Solution 6 - Html

There is one obvious solution which looks quite clean and may be preferred sometimes: define a scope around the template, define your variable inside of it, and let the scope produce the html code you need, like this:

@{
  val title = "Home"
 
  <h1>Welcome on {title}</h1>
}

This has some drawbacks:

  • you are generating your html as Scala NodeSeq this way, which may be limiting sometimes
  • there is a performance issue with this solution: the code inside of @{ seems to be compiled runtime, because the Scala code generated for the page loooks like this (some usual Twirl stuff deleted):

The generated code:

...    

Seq[Any](format.raw/*1.1*/("""<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Basic Twirl</title>
    </head>
    <body>

        """),_display_(/*9.10*/{
            val title = "Home"

                <h1>Welcome on {title}</h1>
        }),format.raw/*15.10*/("""

    """),format.raw/*17.5*/("""</body>
</html>"""))
      }
    }
  }

...

Solution 7 - Html

In twirl templates I would recommend using the defining block, because the

@random = @{
     new Random().nextInt
}

<div id="@random"></div>
<div id="@random"></div>

would result in different values when used multiple times!

@defining(new Random().nextInt){ random =>
    <div id="@random"></div>
    <div id="@random"></div>
}

Solution 8 - Html

For anyone who tries the answer of Govind Singh:
I had to put the import line with the variable under the parameter list, i.e.

@(title:String)(implicit session:play.api.mvc.Session)
@import java.math.BigInteger; var i=1; var k=1

works.

But putting the import with the variable over the import statement, i.e.

@import java.math.BigInteger; var i=1; var k=1
@(title:String)(implicit session:play.api.mvc.Session)

did not work for me and resulted in the error:

expected class or object definition

Solution 9 - Html

@isExcel= {@Boolean.valueOf(java.lang.System.getProperty(SettingsProperties.isExcel))}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontravegaView Question on Stackoverflow
Solution 1 - HtmlvirtualeyesView Answer on Stackoverflow
Solution 2 - HtmlollieView Answer on Stackoverflow
Solution 3 - HtmlGovind SinghView Answer on Stackoverflow
Solution 4 - HtmlbiesiorView Answer on Stackoverflow
Solution 5 - Htmlc4kView Answer on Stackoverflow
Solution 6 - HtmlSumaView Answer on Stackoverflow
Solution 7 - HtmlPwnstarView Answer on Stackoverflow
Solution 8 - HtmlBlubsiwubsiView Answer on Stackoverflow
Solution 9 - HtmlEassa NassarView Answer on Stackoverflow