📜 ⬆️ ⬇️

We write the first project on the Play Framework 2.0

On March 13, the release of the second version of the scala / java-framework Play took place. On Habré already had a review of new features of Play 2.0 . In the same article, I want to fill the gap in the absence of manuals in Russian for this interesting framework using the example of creating a simple Java application consisting of a list of categories and related vacancies.

The article is intended for those who are not familiar with Play at all and would like to “touch” it without wasting a lot of time.

To work with Play 2.0 you need JDK 6 and higher . For my ubuntu 11.10, I installed JDK 7 .

Create a project


1. Download Play 2.0 and unpack it where we have rights to write and read, I have it /var/www/play20 .
')
2. Go to the directory where you keep the sites and run the script:

 /var/www/play20/play new jobs 


We leave the answer to the first question by default, on the second we choose “2 - Create a simple Java application”. For Windows, everything is the same, only you do not execute a shell script, but .bat.

3. Go to the created project, enter the play console and start the project:

 cd jobs /var/www/play20/play run 


4. Checking what we did: http: // localhost: 9000 . To run a project on another port, use “run port_number” (quotes are required).

5. Now to start development on Play 2.0, it remains to configure IDE. We stop the server and return to the console with the command CTRL + D and execute eclipsify or idea depending on your development environment. For netbeans, there is no automatic project creation yet.

To connect the sources (it is convenient to look at the source in the open declaration) and javadoc we execute “eclipsify with-source = true” (do not forget about the quotes).

6. Open the project, I use Eclipse : File> Import> General> Existing Projects into Workspace .

Category List


Create a model category app / models / Category.java :

 package models; import java.util.List; import javax.persistence.Entity; import javax.persistence.Id; import play.data.validation.*; import play.db.ebean.Model; @Entity public class Category extends Model { @Id public Long id; @Constraints.Required public String title; public static Finder<Long,Category> find = new Finder ( Long.class, Category.class ); public static List<Category> all() { return find.all(); } } 


In the views / index.scala.html homepage template, we display all categories:

 @(categories: List[Category]) @main("Jobs") { <ul> @for(category <- categories) { <li>@category.title</li> } </ul> } 


The templates in play 2.0 are html + Scala code blocks that start with the '@' character. Also note that the templates are similar to functions and have parameters that are described at the beginning of the file.

In order for the eclipse to work autocompletion for the newly created templates, the project must be run via a tilde: "~ run" , also in the Windows settings - Preferences - General / Workspace, uncheck the "Build automatically" checkbox, tick the "Refresh using native hooks or polling", "Refresh on access.

We transfer from the controller application app / controllers / Application.java to the template we edited above a list of categories:

 import models.Category; ... public class Application extends Controller { public static Result index() { return ok(index.render( Category.all())); } } 


For the beginning, we will store the data for simplicity just in memory, for this we uncomment the lines in conf / application.conf :

 db.default.driver=org.h2.Driver db.default.url="jdbc:h2:mem:play" ... ebean.default="models.*" 


Click F5 in the browser, we will be offered to execute a SQL query. Click on “Apply this script now!” And we should see an empty ul list: we don't have any categories yet.

Adding categories


Add a category adding form to the app / views / index.scala.html template:

 @(categories: List[Category], categoryForm: Form[Category]) @import helper._ @main("Jobs") { <ul> @for(category <- categories) { <li>@category.title</li> } </ul> @form(routes.Application.add()) { @inputText(categoryForm("title")) <input type="submit" value=""> } } 


In the template, we imply functions from helper._ : the form function creates an HTML form with the action and method fields filled in, the inputText function generates text input.

Register a route in conf / routes :

 POST /add controllers.Application.add() 


Add an action to the app / controllers / Application.java , which will create a new category using the data obtained from the form and update the template rendering call in the index action by adding the second parameter (form):

 import play.data.Form; ... public static Result index() { return ok(index.render(Category.all(), form(Category.class))); } public static Result add() { Form<Category> filledForm = form(Category.class).bindFromRequest(); if (filledForm.hasErrors()) { return badRequest(index.render(Category.find.all(), filledForm)); } Category category = filledForm.get(); category.save(); return redirect(routes.Application.index()); } 


Update http: // localhost: 9000 and try to add categories.

At this place my project broke down. To rebuild everything, exit the console, call / var / www / play20 / play clean-all and rerun .

Jobs


The one-to-many job model app / models / Job.java associated with categories:

 package models; import java.util.List; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToOne; import play.data.validation.*; import play.db.ebean.Model; import play.db.ebean.Model.Finder; @Entity public class Job extends Model { @Id public Long id; @Constraints.Required public String title; @ManyToOne public Category category; public static Finder<Long,Job> find = new Finder(Long.class, Job.class); } 


Add feedback to the app / models / Category.java category model:

 import javax.persistence.OneToMany; ... @OneToMany(mappedBy="category") public List<Job> jobs; 


We press F5, we apply new SQL.

Now we can create an output template for the category views / show.scala.html with all its vacancies:

 @(category: Category, jobForm: Form[Job]) @import helper._ @main("Jobs") { <h1>@category.title</h1> <h2>:</h2> <ul> @for(job <- category.jobs) { <li>@job.title</li> } </ul> <h2> </h2> @form(routes.Jobs.dd(category.id)) { @inputText(jobForm("title")) <input type="submit" value=""> } } 


We add the vacancy controller app / controllers / Jobs.java , which allows you to add a new vacancy, leave the vacancy output for later:

 package controllers; import java.util.List; import play.*; import play.data.Form; import play.mvc.*; import views.html.*; import models.*; public class Jobs extends Controller { public static Result add(Long categoryId) { Form<Job> filledForm = form(Job.class).bindFromRequest(); if (filledForm.hasErrors()) { Category category = Category.find.byId(categoryId); return badRequest(show.render(category, filledForm)); } Job job = filledForm.get(); job.category = Category.find.ref(categoryId); job.save(); return redirect(routes.Categories.show(categoryId)); } public static Result show(Long id) { return TODO; } } 


Refactor categories


It remains to implement the category output page and all its vacancies, at the same time we will add categories from the Application-controller.

Create a separate controller for the categories app / controllers / Categories.java :

 package controllers; import java.util.List; import play.*; import play.data.Form; import play.mvc.*; import views.html.*; import models.*; public class Categories extends Controller { public static Result add() { Form<Category> filledForm = form(Category.class).bindFromRequest(); if (filledForm.hasErrors()) { return badRequest(index.render(Category.find.all(), filledForm)); } Category category = filledForm.get(); category.save(); return redirect(routes.Application.index()); } public static Result show(Long id) { Category category = Category.find.byId(id); return ok(show.render(category, form(Job.class))); } } 


Do not forget to add routes for adding a vacancy, displaying a category, and changing the route for adding new categories to conf / routes :

 GET /category/:id controllers.Categories.show(id: Long) POST /category/add controllers.Categories.add() POST /job/add controllers.Jobs.add(categoryId: Long) 


In the views / index.scala.html template on the main page, we change the form function parameter, add links to categories:

 @(categories: List[Category], categoryForm: Form[Category]) @import helper._ @main("Jobs") { <ul> @for(category <- categories) { <li><a href="@routes.Categories.show(category.id)">@category.title</a></li> } </ul> @form(routes.Categories.add()) { @inputText(categoryForm("title")) <input type="submit" value=""> } } 


At this step, I once again rebuilt the project with the play clean-all command.

Resources for further study Play 2.0:

Source: https://habr.com/ru/post/141439/


All Articles