intorduction of playframework

Post on 13-Apr-2017

171 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Malti Yadavmalti@knoldus.com

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

top related