From 7ad0b11c420a69f65353256705bbf7be7610bc3a Mon Sep 17 00:00:00 2001 From: Minglei Tu Date: Mon, 29 Feb 2016 13:42:02 +0800 Subject: [PATCH 1/2] Add `form-binder` guide --- _includes/_upper_body_common.html | 1 + guides/formats/formbinder.md | 103 ++++++++++++++++++++++++++++++ guides/index.md | 2 +- 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 guides/formats/formbinder.md diff --git a/_includes/_upper_body_common.html b/_includes/_upper_body_common.html index 0c5e20c6..7582b60b 100644 --- a/_includes/_upper_body_common.html +++ b/_includes/_upper_body_common.html @@ -103,6 +103,7 @@
  • File Upload
  • JSON
  • Commands
  • +
  • Form Binder
  • diff --git a/guides/formats/formbinder.md b/guides/formats/formbinder.md new file mode 100644 index 00000000..11d0442b --- /dev/null +++ b/guides/formats/formbinder.md @@ -0,0 +1,103 @@ +--- +layout: guide +title: Form Binder | Formats | Scalatra guides +--- + + + + +Form-binder is a micro data binding and validating framework, easy to use and hack. + +## Usage at a glance + +```scala +import com.github.tminglei.bind.simple._ + +val binder = FormBinder(messages, errsTree()) + +val mappings = tmapping( + "id" -> long(), + "body" -> (expandJson() >-: tmapping( + "email" -> (required() >+: text(email())), + "price" -> (omitLeft("$") >-: float()), + "count" -> number().verifying(min(3), max(10)) + ).label("xx").verifying { case (label, (email, price, count), messages) => + if (price * count > 1000) { + Seq(s"$label: $price * $count = ${price * count}, too much!") + } else Nil + }) +) + +binder.bind(mappings, params).fold( + errors => errors, + { case (id, (email, price, count)) => + // do something here + } +) + +``` + +1) define your binder +2) define your mappings +3) prepare your data +4) bind and consume + + +## Installation & Integration + +#### 1. Add the dependency to your sbt project file: + +```scala +libraryDependencies += "com.github.tminglei" %% "form-binder" % "0.10.0" +``` + +#### 2. Define your helper trait: + +```scala +object FormBinderSupport { + val BindMessagesKey = "__bind_messages" +} + +trait FormBinderSupport extends I18nSupport { self: ScalatraBase => + import FormBinderSupport._ + + before() { + request(BindMessagesKey) = Messages(locale, bundlePath = "bind-messages") + } + + def binder(implicit request: HttpServletRequest) = FormBinder(bindMessages.get, errsTree()) + + /// + private def bindMessages(implicit request: HttpServletRequest): Messages = if (request == null) { + throw new ScalatraException("There needs to be a request in scope to call bindMessages") + } else { + request.get(BindMessagesKey).map(_.asInstanceOf[Messages]).orNull + } +} +``` + +#### 3. Then, mix and use it in your app codes: + +```scala +import org.scalatra.ScalatraServlet +import com.github.tminglei.bind.simple._ + +class SampleServlet extends ScalatraServlet with FormBinderSupport { + + get("/:id") { + val mappings = tmapping( + "id" -> long() + ) + binder.bind(mappings, data(multiParams)).fold( + errors => holt(400, errors), + { case (id) => + Ok(toJson(repos.features.get(id))) + } + ) + } +} +``` + +That's it. _See the [project site](https://github.com/tminglei/form-binder) for more details._ diff --git a/guides/index.md b/guides/index.md index 72ec033b..b926c226 100644 --- a/guides/index.md +++ b/guides/index.md @@ -35,7 +35,7 @@ title: Scalatra guides | Scalatra [wro4j](resources/wro4j.html)

    Formats

    -[File Upload](formats/upload.html), [JSON](formats/json.html), [Commands](formats/commands.html), XML, forms +[File Upload](formats/upload.html), [JSON](formats/json.html), [Commands](formats/commands.html), [Form Binder](formats/formbinder.html), XML, forms

    Persistence

    [Introduction](persistence/introduction.html), [MongoDB](persistence/mongodb.html), [Riak](persistence/riak.html),[Slick](persistence/slick.html), [Squeryl](persistence/squeryl.html) From 30c7f4c40329ff9fadb41c0da44de15fcadafb71 Mon Sep 17 00:00:00 2001 From: tminglei Date: Thu, 3 Mar 2016 22:37:18 +0800 Subject: [PATCH 2/2] Update formbinder.md --- guides/formats/formbinder.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/guides/formats/formbinder.md b/guides/formats/formbinder.md index 11d0442b..8fc944bd 100644 --- a/guides/formats/formbinder.md +++ b/guides/formats/formbinder.md @@ -21,12 +21,12 @@ val mappings = tmapping( "id" -> long(), "body" -> (expandJson() >-: tmapping( "email" -> (required() >+: text(email())), - "price" -> (omitLeft("$") >-: float()), - "count" -> number().verifying(min(3), max(10)) + "price" -> (omitLeft("$") >-: float()), + "count" -> number().verifying(min(3), max(10)) ).label("xx").verifying { case (label, (email, price, count), messages) => - if (price * count > 1000) { - Seq(s"$label: $price * $count = ${price * count}, too much!") - } else Nil + if (price * count > 1000) { + Seq(s"$label: $price * $count = ${price * count}, too much!") + } else Nil }) )