grailsInvas0r
grailsInvas0r

Reputation: 655

play 2.0 creating a variable and assign values

I searched a lot for this issue. I just want to create a variable in a scala html template and needed a temporary variable.

The only solution I found and which makes "sense" is the following:

@defining("hello text") {testvariable =>
    <h1>output of variable: @testvariable</h1>
}

Is that really the only way? Are the guys from playframework serious? I don't want to pass a variable value from controller to the template. I just want to create a local simple variable and assign a value to it in an "if-block", nothing else.

Upvotes: 2

Views: 3904

Answers (3)

Oskar Andersson
Oskar Andersson

Reputation: 61

Sorry for creating a zombie... But since I ended up here searching myself, I wanted to contribute by elaborating on my preferred alternative, Biesiors second alternative (with a trivial stripe row example):

/** This goes in the top of the scala template, before the HTML **/
@injectStripeColor(index: Integer) = @{
    if(index % 2 == 0){
        "#EEE" // Even row
    } else {
        "#AAA" // Odd row
    }
}

You now have a function that you can use in your template. (You could also store the function above in a separate file that you include whenever you need it in whatever template that needs it).

/** This goes in your row loop where i is current index **/
<tr><td style="background-color: @injectStripeColor(i)"> @content </td></tr> 

Upvotes: 0

biesior
biesior

Reputation: 55798

Yes, I think that Play guys are serious.

First.

What is the sense of defining variable as a hardcoded element of the template? Ok I understand that you doesn't want to insert the one value many times but the way you showed with @defining solves the problem. On the other hand - if you want to place variable only for using it as a condition in the if block, that doesn't make sense too, as you can just also write something like @if(1==1){ code } to simulate some behaviour. In other cases your variables should be determined by the controller, and to make it clear you can use for an example some Map for passing groups of variables from controllers to the view.

Second.

Scala templates in Play are just functions, that means you can also call other function or method. You can for an example call some getter or another method that will do and will return anything you want. There are many samples so I'll skip this part.

Third.

As stated in the second part if you don't like the @defining approach, you can just create some super-simple methods somwhere in your app (let's consider that's app/controllers/Application.java ) for storing and setting/getting some value. Of course if you plan to use many 'variables' it's better to store it in one map instead creating separate getters and setters for each one.

in your Application controller, just add these simple methods (also create own getters for other types if required)

private static Map<String, Object> map = new HashMap<String, Object>();

// setter
public static void setValue(String key, Object value) {
    map.put(key, value);
}

// general getter would work well with String, also numeric types (only for displaying purposes! - not for calculations or comparisons!)
public static Object getValue(String key) {
    return map.get(key);
}

public static Boolean isTrue(String key) {
    return  Boolean.valueOf(map.get(key).toString());
}

public static Double getDouble(String key) {
    return Double.valueOf(map.get(key).toString());
}

So next you can use it in your view by setting and reading the Map keys and values

@Application.setValue("name", "Stefan")
@Application.setValue("age", 30)
@Application.setValue("developer", false)
@Application.setValue("task1", 123.5)
@Application.setValue("task2", 456.7)


<h1>ellou' @Application.getValue("name")!</h1>

<div>
    Today there are your  @Application.getValue("age") birthday!
</div>

<div>
    You are @if( Application.isTrue("developer")  ) {
        very big developer
    } else {
        just common user
    }
</div>

<div>
    Once again: @{ val status = if (Application.isTrue("developer"))  "veeeeery big developer" else "really common user"; status }
</div>

<div>
    Today you earned $ @{ Application.getDouble("task1") + Application.getDouble("task2") }
</div>


<div> etc... </div>

As can you see, you can even perform some basic operations, anyway for more sophisticated tasks I would redirect the weight from the (just) template engine to dedicated controller's methods.

Upvotes: 4

jon hanson
jon hanson

Reputation: 9408

That example isn't "pass[ing] a variable value from controller to the template". It's binding a value to a variable to allow it to be reused within the scope of the subsequent braces, which appears to be precisely what you want. I.e. you would use that code in a template and by binding "hello text" to testvariable it would yield:

<h1>output of variable: hello world</h1>

I.e. it has nothing to do with controllers.

If you post some template code where you're trying to use it we might be able to help.

Upvotes: 0

Related Questions