With the new Version 2.4/2.5 of the Play Framework they moved further towards injecting everything and removing the servers state. play.Play.application()
is now deprecated. However, I need the application in my template (e.g. to get all supported languages displayed on all pages with play.i18n.Lang.availables(play.Play.application())
).
I'm aware I could:
play.Application
explicitly to all of my templates.@()(implicit app: play.Application)
. However, in my Java-Project it's not really implicit, I have to pass it every time I render the template.play.api.Play.current
.How can I inject play.Application
in my templates?
---- Update: ----
What I've tried so far, I created the following setup:
index.scala.html:
@(title: String)
@template(title) { //here is the play.Application obviously missing, however I don't want to pass it in every template - even worse in every Controller <-- this is the core of my question
Welcome to my page!
}
template.scala.html:
@(title: String)(content: Html)(implicit app: play.Application)
<html>
<head>
<title>@title</title>
</head>
<body>
<p>Is live? @app.isProd</p>
@content
</body>
</html>
Controller function:
public Result index() {
return ok(views.html.index.render("home"));
}
I just had to look into this for Play framework 2.6.x. It is possible to inject an object into a template according to the documentation: https://www.playframework.com/documentation/2.6.x/ScalaTemplatesDependencyInjection.
I implemented a simple sample (a bit contrived) and I used scala:
test.scala.html:
@this(configuration: play.api.Configuration)
@(key: String)
config = @configuration.get[Seq[String]](key).mkString(", ")
HomeController.scala
package controllers
import javax.inject._
import play.api._
import play.api.i18n._
import play.api.mvc._
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
@Singleton
class HomeController @Inject()(cc: ControllerComponents, testView: views.html.test) (implicit configuration: Configuration) extends AbstractController(cc) with I18nSupport{
def test() = Action { implicit request =>
Ok(testView("play.i18n.langs"))
}
}
routes:
GET /test controllers.HomeController.test()
The configuration object gets injected into views.html.test template and the view itself is injected into the controller. Note the @this(configuration: play.api.Configuration)
statement in the template. Play will generate a class behind the template with a constructor that is injected the Configuration object.
Please note that the injected configuration into the controller doesn't have any role in this particular code. I experimented with other permutations before I found this solution ... Let's say that if you have an inner template used by an outer template called from the controller, and the inner template needs the configuration object you need to feed the configuration from the controller top down, and add an implicit configuration: play.api.Configuration
parameter in all the templates in the hierarchy path right to the template that needs it, something like this: @(message: String)(implicit messagesProvider: MessagesProvider, configuration: play.api.Configuration)
. Then the controller injected configuration is fed to the top template all the way to the template that needs it.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments