shidh / blog-with-play-framework

Blog application using Play! framework, deployed on playapps cloud (http://www.playapps.net). Currently on pause, I am on holiday ;)

Home Page:http://92.243.31.11/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Grab Play! framework @ playframework.org, and unzip it somewhere. On Unix, making a link to the play executable is useful. It should be something like "ln -s /home/dev/where-you-unzip-it/play /usr/local/bin/play".

The first step is to choose a cool name for your new application, let's rock for "blog-app". The next few steps are fast and will create a nice development environment.

Generate project sources and files structure :
 x play new blog-app

A new directory "blog-app" has been created, containing many files :

	|-- app
	|   |-- controllers
	|   |-- models
	|   `-- views
	|       |-- Application
	|       `-- errors
	|-- conf
	|-- eclipse
	|   `-- classes
	|       |-- controllers
	|       `-- models
	|-- lib
	|-- logs
	|-- public
	|   |-- images
	|   |-- javascripts
	|   `-- stylesheets
	`-- test


It is always preferable to keep your files on a version control system. As Git is powerful and Github.com provides a very nice support of Git, I could not recommend more to manage your sources with it. For those who already have a github account, just create a new repository. For this tutorial, I have created a repository named "blog-with-play-framework". In one minute, the project will be managed by Git.

x cd blog-app
x git init
x git remote add origin http://github.com/ipingu/blog-with-play-framework
x git add *
x git commit -m "Project skeleton"
x git push origin master

Your newly created files are now copied on a distant place. Good to feel in security, no ? Github offers a web access on those files at http://github.com/ipingu/blog-with-play-framework.

Play provides a nice integration with Eclipse IDE, as with Netbeans or IDEA. Depends on your prefered IDE, use one of those three commands line :
x play eclipsify
x play idealize
x play netbeansify

Then, import your project on your IDE and it shoulds works perfectly. For Eclipse, three launchers are created (one for development environment, one for debug and the last for launching all tests).
I don't know for others IDE. As I don't want to rely on any IDE for this tutorial, I will only [command play]

Checking everything works well ?

This command will launch the server environment, and deploy your app on it. By default, port 9000 on localhost is used. If a green page with an heart for favicon is accessible, then it's well working, congratulations !

x play run

Ok ! We now have a working development and execution environment, time has come to finally customize our application ! Next step is to use the design layer we have build when we were learning HTML 5.

First, take a look at app/views/Application/index.html. We are gonna tweak this file.

Play templates supports inheritance and inclusion: it allows to separate content in multiple files for the sake of clarity and reusability. Typically, a webpage could be divided in four parts (at least in our example) :
 - a header -> header.html
 - a footer -> footer.html
 - a sidebar -> sidebar.html
 - a content area -> content.html

Each part will be a distinct template, and a root template (main.html) will compose our four templates. The template tag #{include 'name.html' /} is used for template inclusion.

In main.html, there is special tag : {doLayout /}. When used, this tag allows inheritance. Each template which inherits main.html will have its content display in place of the doLayout tag. To inherit a template, use #{extends 'main.html' /} at the top of the template file.

For an exhaustive list of existing tags, take a look at http://www.playframework.org/documentation/1.0.3/tags. And for what you can do in Java in templates files, it is @ http://www.playframework.org/documentation/1.0.3/javaextensions.

The design is now basically integrated, it is sufficient for now. You will discover more on templates development in next lines.


Next target ? Google App Engine. How to deploy a fresh Play! application on GAE and use the datastore engine ?

----

Many modules are available for Play! framework to enhance its abilities. Fortunately, module for deploying on GAE exists and you will see it is very easy and handy to benefits of GAE cloud.

The command play list-modules displays registered modules on the play "marketplace". With the command play install, it comes very easy to add new features to your application.

x play list-modules

Two modules interests us :

~ [gae]
~   Google App Engine
~   http://www.playframework.org/modules/gae
~   Versions: 1.0, 1.0.1, 1.0.2

~ [siena]
~   Siena
~   http://www.playframework.org/modules/siena
~   Versions: 1.0, 1.1

Let's install them.

x play install gae 1.0.2
x play install siena 1.1

When a module is installed, it is installed in where-you-decompressed-play-framework/modules/ folder. By default, a new project don't use any additionnal module. It is necessary to configure your project so your execution environment will [prendre en compte]. This is done in the conf/application.conf file.

Add those two lines (one for each installed modules)

module.gae=${play.path}/modules/gae-1.0.2
module.siena=${play.path}/modules/siena-1.1

Now, when you'll try to launch your application, you should see activated modules :

Module siena is available (/home/mad/coding/libs/play-1.0.3/modules/siena-1.1)
Module gae is available (/home/mad/coding/libs/play-1.0.3/modules/gae-1.0.2)

At the first application launch with GAE module, a blank appengine-web.xml has been created in the war/WEB-INF directory. Configure it regarding your GAE account. In this tutorial case, this is the result.

An application deployment on GAE required you precompile classes, otherwise you will get some "Uncaught exception from servlet java.lang.RuntimeException : Cannot load precompiled template" exceptions.
The command play precompile will compile controllers, models and templates files to the precompiled repository. To precompile classes before deployement is also a good option to do if you want a faster startup of your application.

play precompile

To build a war that will works a servlet container or on GAE environment, the command play war exists. The -o option stands for the output destination file.

play war -o /tmp/blog-app.war

The appcfg.sh script is present in bin repository of the GAE SDK. Download it if not done yet.

appcfg.sh update /tmp/blog-app.war

Update : play gae:deploy --gae /path-to-gae-sdk

Check your application at the url given by GAE, in our case http://play-elsewhere.appspot.com/. (GAE offers the ability to see previous version of your deployed application: the application at this stage of tutorial may be accessible at http://1.latest.play-elsewhere.appspot.com/). If you see the message Your application is ready!, the deployement worked ! 

Time to commit !

git add war/WEB-INF/appengine-web.xml
git commit -m "deployment on GAE works"

Time has come to start Java development : the first module we are gonna build is the post & comments functionnality. It will be really easy as you will see. As I planned to use Disqus.com to manage comments, I just want a system to manage categories and posts.

So let's start by coding the model, two basic classes are needed, Category and Post. Take care of using annotations from siena package, and not from javax.api.
When Siena is used with Play!, it is required to extend Siena.Model class, as Play will perform a search for classes extending this class at persistence manager installation. But when not used with Play!, extending this class offers you facilities to manage entities (method update, save, insert are inherited). Otherwise, you would use the entity manager to do those actions.
GAE only supports Long attribute for entities identifiers.
With thoses classes added in models package, next time you run the application a directory will be created in war/WEB-INF/appengine-generated. I hope so, I add problems for generating my schema...
To insert data in the DDB, we create a Job class which will be called at the application start phase.

Create a class named LoadDataset which extends Play.jobs.Job class and annotate it with @OnApplicationStart. Override the doJob() method, instanciates some objects and save them using insert() method on those objects.

We are ready for the first development iteration :
 x when I click to the banner, I want to display all of my blog posts.
 x modify the template to add a link to @{Blog.all}, where blog is the name of the controller, and all the name of the method.
 x refresh your page, an error occurs : the controller Blog does not exists. In package controllers, create a class name Blog which extends Controller.
 x refresh your page, an error occurs : the method all() does not exists. In class Blog, create a empty static method named all() that returns void. Every controller methods should have this signature, only the method name and parameters can change.
 x refresh your page, and click on the banner. An empty page is displayed. It is normal, the method all() does not specify which view to display after execution. In the body method, just add a call to method render(). This method is inherited from Controller class and renders the default method view, which in this case would be a file named all.html in the folder views/Blog.
 x refresh your page, and click on the banner. An error occurs : the page views/Blog/all.html does not exist. Create it, make it extends main.html so when rendered, this template will also display the header, fooder and sidebar.
 x refresh your page, and click on the banner. Cool, no errors, but still no posts. That is because we never query the datastore. Add List<Post> allPosts = Post.all().fetch(); before rendering. To make this list available to the template, pass in the render arguments : renderArgs.put("posts", allPosts);. Then, tweak the template to iterate over this list :
	#{list items:posts, as:'post'}
		<div class="box" class="content">
			<h2>${post.title}</h2>
			<span>${post.content}</span>
			
			<hr class="space" />
		</div>
	#{/list}
 x refresh your page, you can now smile.

Shame on me, I have skipped unit testing. I will cover this in the next module development, the picture manager. I just want this blog functionnality developped as fast as possible, so this tutorial could be online in less time.



 - add http://disqus.com/ support to offer post commenting abilities.
 - large content storing on GAE datastore for pictures book module.
 - take a diserved break.


About

Blog application using Play! framework, deployed on playapps cloud (http://www.playapps.net). Currently on pause, I am on holiday ;)

http://92.243.31.11/