0
votes

I've a multi-module play app with a play module and other scala module and every thing works fine. I want to add a custom Twirl template and that's when problems arise. This is the Multiproject structure

build.sbt:

name := """scalaplay"""

version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala).dependsOn(restfulapi,util).aggregate(restfulapi,util)
scalaVersion := "2.11.7"

/**
  * .dependsOn(util). will let us use element from dbmodule into apirestmodule. Specifically some element and structure
  * of the data model.
  *
  */

lazy val restfulapi = (project in file("modules/apirest")).enablePlugins(PlayScala).dependsOn(util).settings(scalaVersion:="2.11.7",
  libraryDependencies ++= Seq(
    cache,
    "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test
  )
)

lazy val util = (project in file("modules/dbmodule")).settings(scalaVersion:="2.11.7")

TwirlKeys.templateFormats += ("csv" -> "views.CsvFormat")

Part of apirest.routes:

    #processing premierLeague
    POST     /premier/match             controllers.PremierleagueController.insertMatch

    GET      /premier/matchs            controllers.PremierleagueController.getMatchGame

    GET     /assets/*file            controllers.Assets.versioned(path="/public", file: Asset)

    GET     /records                    controllers.HomeController.records

The action that use the template is in HomeController.scala:

......

 def records = Action {
    Ok(views.csv.records(Record.sampleRecords))
  }

.....

This is the result when I show my source:

[scalaplay] $ show twirlCompileTemplates::sourceDirectories
[info] restfulapi/compile:twirlCompileTemplates::sourceDirectories
[info]  List(/Users/ldipotet/scala/scalaplay/modules/apirest/app)
[info] root/compile:twirlCompileTemplates::sourceDirectories
[info]  List(/Users/ldipotet/scala/scalaplay/app)

And Here is my compilation Error when I try to compile the project:

[info] Compiling 22 Scala sources and 1 Java source to /Users/ldipotet/scala/scalaplay/modules/apirest/target/scala-2.11/classes...
[error] /Users/ldipotet/scala/scalaplay/modules/apirest/app/controllers/HomeController.scala:72: object csv is not a member of package views
[error]     Ok(views.csv.records(Record.sampleRecords))
[error]              ^
[error] one error found
[error] (restfulapi/compile:compileIncremental) Compilation failed
[error] Total time: 6 s, completed 24-jul-2017 17:18:11

For more info the same Custom template compile and works in a single playframework project

2

2 Answers

0
votes

The problem was the reference to the Custom Format File:

TwirlKeys.templateFormats += ("csv" -> "views.CsvFormat")

It was in the only built.sbt file placed at the root of the multi-project.

-rw-r--r--   1 ldipotet  staff     695 27 jul 01:23 build.sbt
drwxr-xr-x   5 ldipotet  staff     170 27 jul 01:16 conf
-rw-r--r--   1 ldipotet  staff  895312 18 jul 10:44 football.txt
drwxr-xr-x   3 ldipotet  staff     102 27 jul 01:43 logs
drwxr-xr-x   5 ldipotet  staff     170 12 jul 12:28 modules
-rw-r--r--   1 ldipotet  staff     191 20 jul 13:36 package.txt
drwxr-xr-x   6 ldipotet  staff     204 27 jul 01:16 project
drwxr-xr-x   5 ldipotet  staff     170  1 jun 12:24 public
-rw-r--r--   1 ldipotet  staff  175256 12 jul 16:54 regex.png
drwxr-xr-x  11 ldipotet  staff     374 27 jul 01:43 target
drwxr-xr-x   4 ldipotet  staff     136  5 jul 09:22 test

It was wrong because the compiler was trying to look for the format in the project where the template was. I meant in the project itself(basedir/modules/api rest) where was the template and there wasn't any reference there.

Solution: Create a build.sbt in the subproject basedir/modules/apirest , where the Custom template is created:

basedir/modules/apirest/built.sbt

name := """apirest"""

TwirlKeys.templateFormats += ("csv" -> "views.CsvFormat")

And of course delete TwirlKeys.templateFormats += ("csv" -> "views.CsvFormat") from the built.sbt at the root project.

No matter if it is single or multiproject, the reference must be placed in the project where the custom template is located.

0
votes

Answen given by @ldipotet actually solves the problem, but there are other ways too.

1 Just moving the TwirlKeys.templateFormats += ("csv" -> "views.CsvFormat") inside the restfulapi definition in the main build.sbt, which would look like this:

...
lazy val restfulapi = (project in file("modules/apirest")).enablePlugins(PlayScala).dependsOn(util).settings(scalaVersion:="2.11.7",
  libraryDependencies ++= Seq(
    cache,
    "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test
  ),
  TwirlKeys.templateFormats += ("csv" -> "views.CsvFormat")
)
...

2 If you are going to need the custom format in other subprojects, moving common settings to an object in a new Common.scala file (name it whatever you want) in the basedir/project directory:

import sbt._

object Common {
  val settings: Seq[Setting[_]] = Seq(
    TwirlKeys.templateFormats += ("csv" -> "views.CsvFormat")
  )
}

Then use Common object in subprojects build.sbt:

name := """apirest"""

Common.settings

See the Play and SBT documentation on subprojects for more details.