Help with applying this to use scalatags instead of Twirl; sbt workflow support for scalatags with Play
jbweeks opened this issue · 4 comments
Firstly, thanks for your contribution to the community!
Anyway, I am new to scalajs and scalatags, and am looking to migrate a Play application to use both scalatags and scalajs instead of Twirl and javascript.
I started down the road of following your example (split project into server, client, shared, etc.), only to realize the example and plugin were geared toward Twirl support.
Any pointers for scalatags instead of Twirl? I am pursuing a full-scala stack with no direct html or javascript. From what I can see based on playing with your example so far, is that I need a way to put the artifacts (scalajs) that will run on the client into a package that the server-side generated pages can include.
My expected execution for an example page would be:
- Browser request to Play server
- Play server Controller method authenticates request
- Play server serves page built with scalatags that includes scalajs "script"
- Browser receives page with embedded scalajs (built via scalatags), and executes scalajs main
...
The sbt workflow would have to put "client" artifacts into a place where they can be served much like other js (e.g. jquery)
Thanks!
Hi @jbweeks,
The sbt-play-scalajs
plugin does not depend on Twirl, you can absolutely use the plugin without Twirl.
Also, do not include the play-scalajs-scripts
library if you do not want to include the Scala.js scripts via Twirl.
To show you what play-with-scalajs-example would look like if it used ScalaTags instead of Twirl:
- Delete
app/views/index.scala.html
andapp/views/main.scala.html
- Edit the server's libraryDependencies in build.sbt to add ScalaTags and remove play-scalajs-scripts
libraryDependencies ++= Seq(
- "com.vmunier" %% "play-scalajs-scripts" % "0.3.0",
+ "com.lihaoyi" %% "scalatags" % "0.5.2"
- Update
app/controllers/Application.scala
to something like:
object Application extends Controller {
import scalatags.Text.all._
def index = Action {
Ok(indexView(SharedMessages.itWorks).toString).withHeaders(CONTENT_TYPE -> MimeTypes.HTML)
}
def indexView(message: String) = {
val body = Seq(
h2("Play and Scala.js share a same message"),
ul(
li("Play shouts out: ", em(message)),
li("Scala.js shouts out: ", em(id := "scalajsShoutOut", em))
))
mainView(body)
}
def mainView(content: Seq[Modifier]) = {
html(
body(
content,
// include the Scala.js scripts that sbt-play-scalajs has copied from the "client" project to the Play public target folder
scripts("client")
))
}
def scripts(projectName: String) = Seq(selectScript(projectName), launcher(projectName))
def selectScript(projectName: String): TypedTag[String] = {
import play.api.Play
if (Play.isProd(Play.current)) {
script(src := s"/assets/${projectName.toLowerCase}-opt.js", `type` := "text/javascript")
} else {
script(src := s"/assets/${projectName.toLowerCase}-fastopt.js", `type` := "text/javascript")
}
}
def launcher(projectName: String) = {
script(src := s"/assets/${projectName.toLowerCase}-launcher.js", `type` := "text/javascript")
}
}
- Done, you can run the application again
$ sbt
> run
$ open http://localhost:9000
Yes, worked perfectly. Sorry for the delay, got pulled onto other issues. Thank you very much!