Play 2.0 access to request in templates
Asked Answered
L

3

11

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.

Linguiform answered 17/3, 2012 at 16:39 Comment(0)
V
7

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.

Villainage answered 17/3, 2012 at 20:52 Comment(0)
G
2

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.

Glossolalia answered 13/5, 2013 at 15:28 Comment(2)
With Play 2.3.x, I get "not found: value request".Kermis
@Wrench: Look at kaka 's answer, he offers an explanation. In short: you can have some implicit's available. Dig into that classPieria
M
2

If you're using Play for Java, you can do something this:

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

Just ignore the error in your ide, it compiles and run well.

The requestHeader method was import automatically by class play.TemplateImports:

javaImports.add("play.core.j.PlayMagicForJava._");
Marlea answered 18/8, 2015 at 3:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.