Getting Started


Downloading skinny-blank-app(-with-deps).zip


We highly recommend using skinny-blank-app for your first Skinny app.

github.com/skinny-framework/skinny-framework/releases

Download latest skinny-blank-app(-with-deps).zip and unzip it, then just run ./skinny command on your terminal. That’s all!

If you’re a Windows user, don’t worry. Use skinny.bat on cmd.exe instead.

./skinny run

When you need to specify Skinny’s env, set SKINNY_ENV env variable. staging.* configuration will be used instead of default development.* in src/main/resources/application.conf.

export SKINNY_ENV=staging # default: development
./skinny run

Homebrew


If you’re a MacOS X user, try our Homebrew formula out.

https://github.com/Homebrew/homebrew/blob/master/Library/Formula/skinny.rb

brew update
brew install skinny
skinny new skinny-blank-app
cd skinny-blank-app
skinny run

Using generator


Let’s create our first Skinny app by using the scaffold generator.

# If you're a zsh user, try "noglob ./skinny g scaffold ..."
./skinny g scaffold members member name:String activated:Boolean luckyNumber:Option[Long] birthday:Option[LocalDate]
./skinny db:migrate
./skinny run

FYI: It’s also possible to specify the column data type for each field. However you will need to add the length validation code to MembersController yourself.

./skinny g scaffold members member "name:String:varchar(128)"

And then, access http://localhost:8080/members.

See in detail here: Scaffolding

You can also run the generated tests.

./skinny db:migrate test
./skinny test

If you just need a controller, run the generator like this:

./skinny g controller help

And then, access http://localhost:8080/help.

Finally, let’s create a war file to deploy.

./skinny package

What should I do first?


Skinny app development is very simple. When you create new pages, all the things you should do is below:


Create new SkinnyController under controller package

You can create a controller by hand or by using generator.

% ./skinny g controller help

 *** Skinny Generator Task ***

  "src/main/scala/controller/ApplicationController.scala" skipped.
  "src/main/scala/controller/HelpController.scala" created.
  "src/main/scala/controller/Controllers.scala" modified.
  "src/test/scala/controller/HelpControllerSpec.scala" created.


Add routing definition to controller.Controllers

When you use generator, this will be done by generator.

package controller
import skinny._
object Controllers {

  object root extends RootController with Routes {
    val indexUrl = get("/")(index).as("index")
  }

  def mount(ctx: ServletContext): Unit = {
    root.mount(ctx)
  }
}

Add view templates for render methods

Add Scalate (ssp, scaml, jade, mustache) or FreeMarker, Thymeleaf, Velocity templates under src/main/webapp/WEB-INF/views.

The above HelpController expects src/main/webapp/WEB-INF/views/help/index.html.ssp.

When you forgot creating view templates, Skinny Framework will create template file for you when accessing the URL for the first time.


Simple Example


You can see a simple example application here.

https://github.com/skinny-framework/skinny-framework-example


Project Structure


The following tree shows the directories and files in skinny-blank-app project. Using this directory layout is recommended.

.
├── README.md
├── bin
│   └── sbt-launch.jar # global sbt script in PATH is given priority over this
├── build.sbt
├── project
│   ├── build.properties
│   └── plugins.sbt
├── sbt      # Skinny uses this sbt command
├── sbt.bat  # Skinny uses this sbt command
├── skinny     # skinny command for Mac OS X, Linux
├── skinny.bat # skinny command for Windows
├── src
│   ├── main
│   │   ├── resources
│   │   │   ├── application.conf
│   │   │   ├── logback.xml
│   │   │   └── messages.conf
│   │   ├── scala
│   │   │   ├── Bootstrap.scala # reserved name by convention
│   │   │   ├── controller
│   │   │   │   ├── ApplicationController.scala
│   │   │   │   ├── Controllers.scala
│   │   │   │   └── RootController.scala
│   │   │   ├── lib
│   │   │   ├── model
│   │   │   │   └── package.scala
│   │   │   └── templates
│   │   │       └── ScalatePackage.scala # Scalate convention
│   │   └── webapp
│   │       └── WEB-INF
│   │           ├── assets
│   │           │   ├── build.sbt
│   │           │   ├── coffee # Put coffee scripts here
│   │           │   ├── jsx    # Put React JSX templates here
│   │           │   ├── less   # Put LESS files here
│   │           │   ├── scala  # Put Scala.js code here
│   │           │   └── scss   # Put sass/scss files here
│   │           ├── layouts
│   │           │   └── default.ssp # layout template
│   │           ├── views
│   │           │   ├── error
│   │           │   │   ├── 403.html.jade
│   │           │   │   ├── 403.html.mustache
│   │           │   │   ├── 403.html.scaml
│   │           │   │   ├── 403.html.ssp
│   │           │   │   ├── 404.html.jade
│   │           │   │   ├── 404.html.mustache
│   │           │   │   ├── 404.html.scaml
│   │           │   │   ├── 404.html.ssp
│   │           │   │   ├── 406.html.jade
│   │           │   │   ├── 406.html.mustache
│   │           │   │   ├── 406.html.scaml
│   │           │   │   ├── 406.html.ssp
│   │           │   │   ├── 500.html.jade
│   │           │   │   ├── 500.html.mustache
│   │           │   │   ├── 500.html.scaml
│   │           │   │   ├── 500.html.ssp
│   │           │   │   ├── 503.html.jade
│   │           │   │   ├── 503.html.mustache
│   │           │   │   ├── 503.html.scaml
│   │           │   │   └── 503.html.ssp
│   │           │   └── root
│   │           │       └── index.html.ssp # default top page
│   │           └── web.xml # because this is on the Servlet
│   └── test
│       ├── resources
│       │   ├── factories.conf # for FactoryGirl
│       │   └── logback.xml
│       └── scala
│           ├── controller
│           │   └── RootControllerSpec.scala # testing with MockController
│           └── integrationtest
│               └── RootController_IntegrationTestSpec.scala # testing with embedded Jetty
└── task
    └── src
        └── main
            └── scala
                └── TaskRunner.scala # when you add new tasks, modify this code
If you find a typo or mistake in this page, please report or fix it. How?