1

I have a project based on SBT-Web and Play Framework. Well, the Play is used just for development, then (when running stage command in SBT/Activator) everything is exported to static pages and deployed to some webserver that maybe does not Java even installed.

My current approach is adding a resourceGenerator:

resourceGenerators in Assets += Def.task {
  for(year <- PageGenerator.Years) yield {
    val file = (resourceManaged in Assets).value / "assets" / s"${year.year}.html"
    println(s"Writing $fileā€¦")
    IO.write(file, PageGenerator.forYear(year))
    file
  }
}.taskValue

This works right now, but it has some drawbacks:

  • First and foremost, I cannot use subdirectories. When I try to put a file into a subdirectory, it is placed into root.
  • When I change the template or source data, I have to reload the project in order to make it effective.
  • Last, I would slightly appreciate using Twirl or something similar there.

How to overcome those drawbacks? (The first one is the most important. Resolving other drawbacks is rather a smaller benefit.)

  • I've tried to put the generating code to a pipeline stage. This works when building the final artifact, but it does not work during the development.
  • Idea: Use a Twirl template, call it dynamically during development and invoke it somehow (using some ClassLoader and Reflection API) in a pipeline stage. I am not sure if this is the right way. Am I guaranteed that the Scala/Twirl code is already compiled when executing sbt-web pipeline stages?
  • A hacky idea: Generate the files to project root, serve them dynamically over routes in development mode, rename them in a pipeline stage. This is heavy hack, but it should work, in theory.
v6ak
  • 1,568
  • 2
  • 11
  • 26

2 Answers2

1

Well, found the solution for the main problem:

Get assets to compile when running via "activator run" in Play

Still, it does not resolve the other problems, so other answers are welcome.

v6ak
  • 1,568
  • 2
  • 11
  • 26
0

For anyone who comes across this issue, here is the important part of the solution from the link @v6ak mentioned:

To prevent files always being placed in the public root directory even if they are placed in a subdirectory, you also have to add the directory for your task's output to resourceDirectories.

val taskOutputDir = settingKey[File]("Resource directory for task output")
taskOutputDir  := (resourceManaged in Assets).value / "my-task"


// ADD THIS to preserve directory structure
resourceDirectories in Assets += taskOutputDir.value


resourceGenerators in Assets += Def.task {
  // Generate your assets and output them to 'taskOutputDir'
  // return a Seq[File] of the generated files
}.taskValue

David Dostal
  • 436
  • 11
  • 8