Automatically inject WebJarAssets in Play 2.5 HTML

2019-04-08 18:46发布

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>

3条回答
forever°为你锁心
2楼-- · 2019-04-08 19:24

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>
查看更多
一夜七次
3楼-- · 2019-04-08 19:40

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
查看更多
成全新的幸福
4楼-- · 2019-04-08 19:44

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

查看更多
登录 后发表回答