Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play 2.0 access to request in templates

I have the following simplified template setup:

  • Main (template)
    • Homepage
    • Details

Now when a user logs in, a session attribute username is set so that I can figure out if a user is logged in or not. In order to help me to figure out if a user is logged in or not, I have the following session helper object:

object SessionHelper {
  val sessionKey = "username"

  def authenticated(implicit request: RequestHeader) = {
    request.session.get(sessionKey).exists(_ => true)
  }
}

Which I can use in a template that takes an implicit request object, for example:

(implicit request: play.api.mvc.RequestHeader)
...
@if(SessionHelper.authenticated) {
    <strong>Authenticated!</strong>
}
...

Since — as far as I can tell — this is the only way to get an implicit variable in a template, it means that everywhere I render a view, I need to explicitly "define" the implicit request variable. For example:

def index = Action { implicit request =>
  Ok(views.html.index(myStuff))
}

Without the implicit request => statement, it doesn't compile. Now while this is a little awkward, as long as I stay within any of the "sub-views" (e.g. Homepage or Details) that's fine because for each of those views I have a controller method and as such also access to the implicit RequestHeader instance. However, when I need to get access to the session in my template (e.g. Main) this doesn't work because it is never explicitly rendered by a controller.

I'm not immediately seeing a way to get access to the session in a template, and a quick Google doesn't reveal much other than a couple questions on the same topic with no resolution. Any ideas?

Update: seems like this is somewhat related to this question.

like image 489
tmbrggmn Avatar asked Mar 17 '12 16:03

tmbrggmn


2 Answers

There is no alternative to passing the implicit request around all your templates, at least not as of Play Framework 2.0.

The link you add in the update is to move more data around the templates in only 1 object, but you still need to declare the implicit parameter everywhere.

like image 139
Pere Villega Avatar answered Oct 22 '22 08:10

Pere Villega


I noticed an interesting thing: in my Java Play 2.1.0 application I can use implicit objects listed in Play 1.2.5 documentation, while they are not documented at all in play 2! Probably it is something like undocumented backward-compatibility fix. Anyway, I can do this:

<li @if(request.uri == routes.Help.index.url){class="active"}>

and this:

@for( (key, message) <- flash) { ... }

As you can see, I can use request and flash variables without defining them. My IntelliJ constantly highlights it as error, but it compiles and works anyway. So it seems like a few versions after 2.0 they addressed this problem.

like image 2
NIA Avatar answered Oct 22 '22 08:10

NIA