noncom
noncom

Reputation: 4992

Play 2.0 templating - Scala `match` and `val` do not compile in a view template

I have the following code in Play 2.0 template:

@content.toString.lines.map{
    case line =>     // i put `case` here as another attempt to make it work
    line match {
        case "" => @Html("")
        case _ => <li>@Html(line)</li>   /*CRASH*/
    }   
}

It fails on the marked line, saying that not found: value line. The second variant of it:

@for(line <- content.toString.lines){
    @line match {                            /*CRASH*/
        case "" => @Html("")
        case _ => <li>@Html(line)</li>
    }   
}

fails on the marked line, claiming that 'case' expected but identifier found.

UPDATE:

Same thing goes for val:

@val headID = "head"

comes up with illegal start of simple expression.

UPDATE ENDS

I would like to know, what am I doing wrong and how to correctly implement the match-case structure and val assignment in Play's templates?

Upvotes: 9

Views: 5599

Answers (4)

0fnt
0fnt

Reputation: 8661

Another frequent cause of this error is to have the starting brace on a separate line:

@x match {
case y => 
  { //offending brace, put it back on the same line as case
  } //This can go anywhere
}

Upvotes: 0

Guan
Guan

Reputation: 136

I found that add a {} outside to enclose entire code would work

@{content.toString.lines.map{ line => 
  line match {
    case "" =>  @Html("")
    case _ => <li>@Html(line)</li> 
}}  

Upvotes: 4

Julien Richard-Foy
Julien Richard-Foy

Reputation: 9663

Using match expressions in templates

You need to enclose in braces (“{” and “}”) the HTML content of your templates:

@for(line <- content.toString.lines) {
  @line match {
    case "" => { }
    case _ => { <li>@Html(line)</li> }
  }
}

In your specific case, the following code would read better IMHO:

@content.toString.lines.collect {
  case line if !line.isEmpty => { <li>@Html(line)</li> }
}

Defining values

You can define values using the defining[T](value: T)(usage: T => Html) helper:

@defining(1 + 2 * 3) { value =>
  <div>@value</div>
}

Upvotes: 26

Jamil
Jamil

Reputation: 2160

following seems to work for me

@content.toString.lines.map{ line => 
    line match {
      case "" =>  @Html("")
     case _ => <li>@Html(line)</li> 
}  

hard on eyes, but you can look at target/scala-2.9.1/src_managed/main/views/html/index.template.scala in the play project directory to see what its putting in string literals.

As for val assignment, I don't know, but @defining may help

Upvotes: 1

Related Questions