tips and tricks for setting up a play 2 project
DESCRIPTION
A small set of tips and tricks for setting up a vanilla Play 2 project. Presentation given at Devoxx 2013 in Antwerp.TRANSCRIPT
@elmanu#DV13PlayTricks
Tips and tricks for setting up a Play 2 project
!!
Manuel Bernhardt
@elmanu#DV13PlayTricks
play new hello-playLet’s get started
@elmanu#DV13PlayTricks
name := "hello-play"!!version := "1.0-SNAPSHOT"!!libraryDependencies ++= Seq(! jdbc,! anorm,! cache!) !!play.Project.playScalaSettings!
Hello world - build.sbt
@elmanu#DV13PlayTricks
// Comment to get more information during initialization!logLevel := Level.Warn!!// The Typesafe repository !resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"!!// Use the Play sbt plugin for Play projects!addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.1")!
Hello world - plugins.sbt
@elmanu#DV13PlayTricks
First things first: Scalariform!
Code indentation is good for your health
@elmanu#DV13PlayTricks
// Comment to get more information during initialization!logLevel := Level.Warn!!// The Typesafe repository !resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"!!// Use the Play sbt plugin for Play projects!addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")!!addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.2.0")!
Scalariform! - plugins.sbt
@elmanu#DV13PlayTricks
name := "hello-play"!!version := "1.0-SNAPSHOT"!!libraryDependencies ++= Seq(cache)!!play.Project.playScalaSettings!!scalariformSettings
Scalariform! - build.sbt
@elmanu#DV13PlayTricks
@elmanu#DV13PlayTricks
@elmanu#DV13PlayTricks
Scalastyle Keep it clean
@elmanu#DV13PlayTricks
// Comment to get more information during initialization!logLevel := Level.Warn!!// The Typesafe repository !resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"!!// Use the Play sbt plugin for Play projects!addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")!!addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.2.0")!!addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.3.2")
Scalastyle! - plugins.sbt
@elmanu#DV13PlayTricks
name := "hello-play"!!version := "1.0-SNAPSHOT"!!libraryDependencies ++= Seq(cache)!!play.Project.playScalaSettings!!scalariformSettings!!org.scalastyle.sbt.ScalastylePlugin.Settings
Scalastyle! - build.sbt
@elmanu#DV13PlayTricks
<scalastyle>! <name>Scalastyle sample configuration</name>! <check level=“warning”! class=“org.scalastyle.file.FileLineLengthChecker"! enabled="true">! <parameters>! <parameter name="maxLineLength"><![CDATA[100]]></parameter>! <parameter name="tabSize"><![CDATA[2]]></parameter>! </parameters>! </check>!</scalastyle>
Scalastyle! - scalastyle-config.xml
@elmanu#DV13PlayTricks
<?xml version="1.0" encoding="US-ASCII"?>!<checkstyle version=“5.0”>! <file name=“/Users/manu/w/hello-play/app/controllers/Application.scala">! <error line=“12"! source=“org.scalastyle.file.FileLineLengthChecker"! severity=“warning"! message="File line length exceeds 100 characters”>! </error>! </file>!</checkstyle>!
Scalastyle! - Output
@elmanu#DV13PlayTricks
Sub-projects!
Keeping things fast
@elmanu#DV13PlayTricks
Core
Module 1 Module 2
Root
@elmanu#DV13PlayTricks
play.Project.playScalaSettings!!def playProject(name: String) = play.Project(! name = name,! path = file("modules/" + name)! ).! settings(scalariformSettings :_*).! settings(org.scalastyle.sbt.ScalastylePlugin.Settings :_*)!!lazy val core = playProject("core")!!lazy val module1 = playProject("module1").dependsOn(core)!!lazy val module2 = playProject("module2").dependsOn(core)!!lazy val root = playProject("hello-play").in(file(".")).!! ! dependsOn(module1, module2).! aggregate(module1, module2)
Sub-projects - build.sbt
@elmanu#DV13PlayTricks
play.Project.playScalaSettings!!def playProject(name: String) = play.Project(! name = name,! path = file("modules/" + name)! ).! settings(scalariformSettings :_*).! settings(org.scalastyle.sbt.ScalastylePlugin.Settings :_*)!!lazy val core = playProject("core")!!lazy val module1 = playProject("module1").dependsOn(core)!!lazy val module2 = playProject("module2").dependsOn(core)!!lazy val root = playProject("hello-play").in(file(".")).!! ! dependsOn(module1, module2).! aggregate(module1, module2)
Sub-projects - build.sbt
@elmanu#DV13PlayTricks
play.Project.playScalaSettings!!def playProject(name: String) = play.Project(! name = name,! path = file("modules/" + name)! ).! settings(scalariformSettings :_*).! settings(org.scalastyle.sbt.ScalastylePlugin.Settings :_*)!!lazy val core = playProject("core")!!lazy val module1 = playProject("module1").dependsOn(core)!!lazy val module2 = playProject("module2").dependsOn(core)!!lazy val root = playProject("hello-play").in(file(".")).!! ! dependsOn(module1, module2).! aggregate(module1, module2)
Sub-projects - build.sbt
@elmanu#DV13PlayTricks
play.Project.playScalaSettings!!def playProject(name: String) = play.Project(! name = name,! path = file("modules/" + name)! ).! settings(scalariformSettings :_*).! settings(org.scalastyle.sbt.ScalastylePlugin.Settings :_*)!!lazy val core = playProject("core")!!lazy val module1 = playProject("module1").dependsOn(core)!!lazy val module2 = playProject("module2").dependsOn(core)!!lazy val root = playProject("hello-play").in(file(".")).!! ! dependsOn(module1, module2).! aggregate(module1, module2)
Sub-projects - build.sbt
@elmanu#DV13PlayTricks
play.Project.playScalaSettings!!def playProject(name: String) = play.Project(! name = name,! path = file("modules/" + name)! ).! settings(scalariformSettings :_*).! settings(org.scalastyle.sbt.ScalastylePlugin.Settings :_*)!!lazy val core = playProject("core")!!lazy val module1 = playProject("module1").dependsOn(core)!!lazy val module2 = playProject("module2").dependsOn(core)!!lazy val root = playProject("hello-play").in(file(".")).!! ! dependsOn(module1, module2).! aggregate(module1, module2)
Sub-projects - build.sbt
@elmanu#DV13PlayTricks
@elmanu#DV13PlayTricks
application.conf
@elmanu#DV13PlayTricks
routes
module2.routes
module1.routes
application.conf
@elmanu#DV13PlayTricks
Snapshot dependencies and multi-module projects
Workarounds
@elmanu#DV13PlayTricks
Snapshot dependencies
• https://github.com/sbt/sbt/issues/413
@elmanu#DV13PlayTricks
Snapshot dependencies
• https://github.com/sbt/sbt/issues/413
@elmanu#DV13PlayTricks
Snapshot dependencies - workarounds
• Don’t use snapshot dependencies
• Convince library authors to make releases
• Use a cache, e.g. Squid
• OS X: http://squidman.net/squidman
-‐Dhttp.proxyHost=localhost -‐Dhttp.proxyPort=8090
@elmanu#DV13PlayTricks
Tools for ChromeAfter all, we’re building web-applications
@elmanu#DV13PlayTricks
https://chrome.google.com/webstore/detail/play-framework-tools/dchhggpgbommpcjpogaploblnpldbmen
@elmanu#DV13PlayTricks
// Comment to get more information during initialization!logLevel := Level.Warn!!// The Typesafe repository !resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"!!// Use the Play sbt plugin for Play projects!addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.2.0")!!addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.2.0")!!addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "0.3.2")!!addSbtPlugin("com.jamesward" %% "play-auto-refresh" % "0.0.7")
Play Auto Refresh - plugins.sbt
@elmanu#DV13PlayTricks
name := "hello-play"!!version := "1.0-SNAPSHOT"!!libraryDependencies ++= Seq(! jdbc,! anorm,! cache!) !!play.Project.playScalaSettings!!scalariformSettings!!org.scalastyle.sbt.ScalastylePlugin.Settings!!com.jamesward.play.BrowserNotifierPlugin.livereload
Play Auto Refresh - build.sbt
@elmanu#DV13PlayTricks
No more ⌘+R, yeah!
play ~ run
Chrome
Your IDE
@elmanu#DV13PlayTricks
Open errors in IDE
Instructions at https://github.com/jamesward/play-framework-chrome-tools
Click to open in editor
@elmanu#DV13PlayTricks
Use dependency injection right away
A poor man’s solution
@elmanu#DV13PlayTricks
package controllers!!class Users(greeting: String) extends BaseController {!! def hello = Action { implicit request =>! ! Ok(greeting)! }!!}
DI - Users controller
@elmanu#DV13PlayTricks
GET /users @controllers.Users.hello!
DI - Routes
@elmanu#DV13PlayTricks
import controllers.Users!import play.api.GlobalSettings!!object Global extends GlobalSettings {!! override def getControllerInstance[A](controllerClass: Class[A]): A = {!! val USERS = classOf[Users]!! val instance = controllerClass match {! case USERS => new Users("Hello users")! case _ => super.getControllerInstance(controllerClass)! }!! instance.asInstanceOf[A]! }!}
DI - Global.scala
@elmanu#DV13PlayTricks
That’s it! Questions?!
https://github.com/manuelbernhardt/hello-play-dv13 !
http://manuel.bernhardt.io