In my Play HTML template inside my custom
module, I have the following line of code:
<script type="text/javascript" src="@controllers.core.routes.WebJarAssets.at(WebJarAssets.locate("jquery.min.js"))"></script>
This references a WebJarAssets
class in the core
module that looks like this:
package controllers.core
import javax.inject._
import play.api.http.HttpErrorHandler
import play.api.{Environment, Configuration}
class WebJarAssets @Inject()(errorHandler: HttpErrorHandler, configuration: Configuration, environment: Environment) extends controllers.WebJarAssets(errorHandler, configuration, environment)
Please note that I have also included the following line in build.sbt
in the custom
module:
"org.webjars" %% "webjars-play" % "2.5.0",
When starting the application, I receive the following error:
[error] /Users/john/DemoProject/modules/custom/app/views/custom/templates/main.scala.html:36: not found: value WebJarAssets
[error] <script type="text/javascript" src="@controllers.core.routes.WebJarAssets.at(WebJarAssets.locate("jquery.min.js"))"></script>
[error] ^
Judging from the implementation of WebJarAssets in earlier releases, there was no need to implement and inject an own controller for this (for example, see this tutorial).
What am I doing wrong? Do I even need a WebJarAssets
class for this (as I need web jar assets in many modules, I added this for now in the core
module). Furthermore, why do I need to manually inject it in the template and why is it not automatically resolved?
In case you wonder what manually inject means for me:
@(title: String, webJarAssets: WebJarAssets)(content: Html)(implicit messages:Messages)
<script type="text/javascript" src="@controllers.core.routes.WebJarAssets.at(webJarAssets.locate("jquery.min.js"))"></script>
Before webjars-play
2.5.0
there was a static method that you could use in your templates. Since Play has been moving away from global state / static methods, that was removed from webjars-play
and now you need to inject WebJarAssets
. Unfortunately the Twirl templates don't support injection yet. So you have to inject it into your controller and then pass it to your template. Here is a full sample app that does this: https://github.com/webjars/webjars-play/tree/master/test-project
It can write like that.
controller:
class Application @Inject()(implicit webJarAssets: WebJarAssets,
val messagesApi: MessagesApi, materializer: Materializer)
extends Controller with I18nSupport {
template:
@(title: String)(content: Html)(implicit messages: Messages, webJarAssets: WebJarAssets)
<script type='text/javascript' src='@routes.WebJarAssets.at(webJarAssets.locate("jquery.min.js"))'></script>
As @james-ward said in play-2.5.12
with twirl-1.2.0
you can declare inject dependencies in templates but they will become classes and not objects that complicates the reference to the templates from other ones.
The changes are:
project/plugins.sbt
addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.2.0")
main.scala.html
@this(webJarAssets: WebJarAssets)
@(title: String)(content: Html)(implicit messages:Messages)
<script type="text/javascript"
src="@controllers.core.routes.WebJarAssets.at(webJarAssets.locate("jquery.min.js"))">
</script>
Note that a caller of the main template should also declare a constructor mainClient.scala.html:
@this(mainRef: main)
@(...)
content
@main("title"){ }
content
来源:https://stackoverflow.com/questions/37043458/automatically-inject-webjarassets-in-play-2-5-html-template