26
Malti Yadav [email protected] Play ! Framework Introduction & Highlights

Intorduction of Playframework

Embed Size (px)

Citation preview

Page 1: Intorduction of Playframework

Malti [email protected]

Play ! FrameworkIntroduction & Highlights

Page 2: Intorduction of Playframework

Quick Overview

Stateless framework Integration of JSON Full stack web framework Compilation and Exact Error Lots of build in feature for fast developement Urls are entry poin to application RESTful by default

Page 3: Intorduction of Playframework

Architecture

Page 4: Intorduction of Playframework

Setup play project

Page 5: Intorduction of Playframework

Standard Application Layoutapp → Application sources └ assets → Compiled asset sources └ stylesheets → Typically LESS CSS sources └ javascripts → Typically CoffeeScript sources └ controllers → Application controllers └ models → Application business layer └ views → Templatesbuild.sbt → Application build scriptconf → Configurations files and other non-compiled resources (on classpath) └ application.conf → Main configuration file └ routes → Routes definitionpublic → Public assets └ stylesheets → CSS files └ javascripts → Javascript files └ images → Image filesproject → sbt configuration files └ build.properties → Marker for sbt project └ plugins.sbt → sbt plugins including the declaration for Play itselflib → Unmanaged libraries dependencieslogs → Standard logs folder └ application.log → Default log filetarget → Generated stuff └ scala-2.10.0 └ cache └ classes → Compiled class files └ classes_managed → Managed class files (templates, ...) └ resource_managed → Managed resources (less, ...) └ src_managed → Generated sources (templates, ...)test → source folder for unit or functional tests

Page 6: Intorduction of Playframework

The conf/routes file# Routes# This file defines all application routes (Higher priority routes first)# ~~~~

# Home pageGET / controllers.Application.index

# Registration pageGET /registration controllers.Application.registration

# Login pageGET /login controllers.Application.login

# logoutGET /logout controllers.Application.logout

#save userdataPOST /registration controllers.Application.createUser

# loginAuthentication

POST /login controllers.Application.loginAuthentication

# Dashboard pageGET /dashboard controllers.Application.dashboard

# Map static resources from the /public folder to the /assets URL pathGET /assets/*file controllers.Assets.at(path="/public", file)

Page 7: Intorduction of Playframework

The conf/application file Configure database access

mongodb.servers=[“localhost:27017”] mongodb.db=”test”

Logger Router Specific modules

Page 8: Intorduction of Playframework

Designing a domain modelspackage models

import java.util.Date

object Domains { /* * Case class for UserForm */ case class UserForm(name:String,email:String,password:(String,String),joinDate: Date) /* * Case class for LoginForm */ case class LoginForm(email:String,password: String)}

Page 9: Intorduction of Playframework

Designing a QueryBuilder modelspackage models

import play.api._import play.api.mvc._import play.api.libs.functional.syntax._import play.api.libs.json._import play.api.libs.concurrent.Execution.Implicits.defaultContext

import scala.concurrent.Future

import reactivemongo.api._import play.modules.reactivemongo.MongoControllerimport play.modules.reactivemongo.json.collection.JSONCollection

object QueryBuilder extends Controller with MongoController { /* * Get a JSONCollection (a Collection implementation that is designed to work * with JsObject, Reads and Writes.) * Note that the `collection` is not a `val`, but a `def`. We do _not_ store * the collection reference to avoid potential problems in development with * Play hot-reloading. */ def collection(collectionname: String): JSONCollection = db.collection[JSONCollection](collectionname)

Page 10: Intorduction of Playframework

Cont...def getDocumentsByQuery(collectionname: String, query: JsObject): Future[List[JsObject]] = { val cursor: Cursor[JsObject] = collection(collectionname).find(query).cursor[JsObject] val futureresult: Future[List[JsObject]] = cursor.collect[List]() futureresult }

def insertDocuments(collectionname: String, documents: JsObject) { collection(collectionname).insert(documents) }

}

Page 11: Intorduction of Playframework

Designing a helper class

package utils

import play.api.mvc.RequestHeader

object Helper { /* * find URI * @param request */ def findUri(request: RequestHeader): String = { request.uri }

Page 12: Intorduction of Playframework

Cont.../* * find session values * @param request * @param element - find session value stored in element */ def findSession(request: RequestHeader, element: String): String = { request.session.get(element).map { sessionvalue => sessionvalue }.getOrElse { " " }

}

Page 13: Intorduction of Playframework

Cont... /* * find flash values * @param request - HTTP request * @param element - find flash value stored in element */ def findFlash(request: RequestHeader, element: String): String = { request.flash.get(element).getOrElse { " " }

}

}

Page 14: Intorduction of Playframework

Designing a constants classpackage utils

object Constants { val USER_COLLECTION_NAME = "user" val MIN_LENGTH_OF_PASSWORD = 6 val PASSWORD_NOT_MATCHED = "Password must be matched" val HOME_PAGE_TITLE = "Welcome to home page" val WRONG_LOGIN_DETAILS = "The email or password you entered is incorrect" val DASHBOARD_TITLE = "Welcome to dashboard" val ENTERED_EMAIL_EXISTS = "Entered email id already exist in database" val DEFAULT_PROFILE_IMAGE = "profile.jpeg"}

Page 15: Intorduction of Playframework

Calling business logic (Controller)package controllers

import models.Domains._import models.QueryBuilder._

import utils.Helper._import utils.Constants._

import play.api._import play.api.mvc._import play.api.data.Formimport play.api.data.Forms._import play.api.libs.concurrent.Execution.Implicits.defaultContextimport play.api.libs.functional.syntax._import play.api.libs.json._

import java.util.Dateimport scala.concurrent.Future

import views.html

object Application extends Controller {

Page 16: Intorduction of Playframework

Cont... /* * userForm */ val userForm = Form( mapping( "name" -> nonEmptyText, "email" -> email, "password" -> tuple("main" -> nonEmptyText(MIN_LENGTH_OF_PASSWORD), "confirm" -> nonEmptyText). verifying(PASSWORD_NOT_MATCHED, passwords => passwords._1 == passwords._2), "joinDate" -> date("yyyy-MM-dd"))(UserForm.apply)(UserForm.unapply)) /* * Login Form */ val loginForm = Form( mapping( "email" -> email, "password" -> nonEmptyText)(LoginForm.apply)(LoginForm.unapply))

Page 17: Intorduction of Playframework

Cont...../* * Redirect Home Page */ def index = Action { request => Ok(html.index(HOME_PAGE_TITLE, findUri(request))) }

/* * Redirect Registration Page */ def registration = Action { implicit request =>

val name = findFlash(request, "name") val email = findFlash(request, "email") if (email != " ") { val userForm = Application.userForm.fill(UserForm(name, email, (" ", " "), new Date)) }

Ok(html.registration(userForm, findUri(request))) }

Page 18: Intorduction of Playframework

Cont.../* * Redirect Login Page */ def login = Action { implicit request =>

val email = findFlash(request, "email") if (email != " ") { val loginForm = Application.loginForm.fill(LoginForm(email, " ")) }

Ok(html.login(loginForm, findUri(request))) }

/* * Logout and clean the session. */ def logout = Action { implicit request => Redirect(routes.Application.login).withNewSession }

Page 19: Intorduction of Playframework

Cont... /* * Handle UserForm Submission */ def createUser = Action.async { implicit request => userForm.bindFromRequest.fold( error => Future(BadRequest(html.registration(error, findUri(request)))), userForm => { val name = userForm.name val email = userForm.email val (password, _) = userForm.password val joinDate = userForm.joinDate val saveRecord = Json.obj("name" -> name, "email" -> email, "password" -> password, "joinDate" -> joinDate)

val jsonuserdata = Json.obj("email" -> email) val futureUserdetails = getDocumentsByQuery(USER_COLLECTION_NAME, jsonuserdata)

futureUserdetails.map { result => if (result.size > 0) { Redirect(routes.Application.registration).flashing( "message" -> ENTERED_EMAIL_EXISTS, "name" -> name, "email" -> email) } else { val futuresaveUser = insertDocuments(USER_COLLECTION_NAME, saveRecord) Redirect(routes.Application.dashboard).withSession( "email" -> email) }

}

}) }

Page 20: Intorduction of Playframework

Cont.../* * Login Authentication */

def loginAuthentication = Action.async { implicit request => loginForm.bindFromRequest.fold( error => Future(BadRequest(html.login(error, findUri(request)))), loginForm => { val email = loginForm.email val password = loginForm.password val jsonuserdata = Json.obj("email" -> email, "password" -> password) val futureUserdetails = getDocumentsByQuery(USER_COLLECTION_NAME, jsonuserdata)

futureUserdetails.map { result => if (result.size > 0) { Redirect(routes.Application.dashboard).withSession( "email" -> email) } else { Redirect(routes.Application.login).flashing( "message" -> WRONG_LOGIN_DETAILS, "email" -> email) }

} })

}

Page 21: Intorduction of Playframework

Cont.../* * Redirect Dashboard */ def dashboard = Action.async { implicit request => if (findSession(request, "email") == " ") { Future(Redirect(routes.Application.login)) } else { val jsonuserdata = Json.obj("email" -> findSession(request, "email")) val userfutureresult = getDocumentsByQuery(USER_COLLECTION_NAME, jsonuserdata)

userfutureresult.map { result => Ok(html.dashboard(DASHBOARD_TITLE, findUri(request),result)) } } }

}

Page 22: Intorduction of Playframework

The templating system (main.scala.html) @(title:String)(content:Html)<!DOCTYPE html><html lang="en"><head><title>@title</title><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" media="screen" href="@routes.Assets.at("Bootstrap/css/bootstrap.min.css")"><link rel="stylesheet" media="screen" href="@routes.Assets.at("Bootstrap/css/bootstrap-theme.min.css")"><link rel="stylesheet" media="screen" href="@routes.Assets.at("css/custom.css")"><script src="@routes.Assets.at("jquery/jquery-1.11.1.min.js")" type="text/javascript"></script><script src="@routes.Assets.at("Bootstrap/js/bootstrap.min.js")" type="text/javascript"></script><script src="@routes.Assets.at("Bootstrap/js/bootstrap.js")" type="text/javascript"></script></head><body>@content</body></html>

Page 23: Intorduction of Playframework

Cont...registration.scala.html

@import models.Domains._

@(userForm:Form[UserForm],path:String)(implicit flash: Flash)

@import helper._

@main("Welcome to Registration Page"){<div class="container"> @header(path) <div class="jumbotron"> @form(routes.Application.createUser){

@registrationformElements(userForm)

<div class="registration-error">@flash.get("message")</div>

<input type="submit" name="submit" value="Submit" class="btn btn-primary">

} </div> @footer()

</div> }

Page 24: Intorduction of Playframework

Cont...registrationformElements.scala.html

@import models.Domains._@(userForm: Form[UserForm])@import helper._@implicitField = @{ helper.FieldConstructor(BootstrapInput.f) }@inputText(userForm("name"),'_label -> "Name", '_showConstraints -> false,'class -> "form-control")@inputText(userForm("email"),'_label -> "Email", '_showConstraints -> false,'class -> "form-control")@inputPassword(userForm("password.main"),'_label -> "Password", '_help ->"Password should be minimum 6 character",'class -> "form-control")@inputPassword(userForm("password.confirm"),'_error ->userForm.error("password"), '_label -> "Confirm Password", '_showConstraints -> false,'class -> "form-control")@inputText(userForm("joinDate"),'_label -> "Joining Date", '_showConstraints -> false,'class -> "form-control")

Page 25: Intorduction of Playframework

Questions ?

Page 26: Intorduction of Playframework

THANK YOU