Upload
maltiyadav
View
175
Download
0
Embed Size (px)
Citation preview
Malti [email protected]
Play ! FrameworkIntroduction & Highlights
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
Architecture
Setup play project
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
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)
The conf/application file Configure database access
mongodb.servers=[“localhost:27017”] mongodb.db=”test”
Logger Router Specific modules
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)}
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)
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) }
}
Designing a helper class
package utils
import play.api.mvc.RequestHeader
object Helper { /* * find URI * @param request */ def findUri(request: RequestHeader): String = { request.uri }
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 { " " }
}
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 { " " }
}
}
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"}
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 {
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))
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))) }
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 }
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) }
}
}) }
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) }
} })
}
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)) } } }
}
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>
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> }
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")
Questions ?
THANK YOU