Build Your First Grails Project: A Grails-Powered Blog

xperienced web developers know well how many layers of conversion they have to go through to present persistent information to the user:

  1. Mapping web requests to executing code
  2. Converting objects to relational data
  3. Rendering markup from their object structures

Open source frameworks (particularly Spring and Hibernate) have become extremely good at easing the pain of these conversions, but that ease has come at a price: reams of XML configuration. On a typical web project using Spring and Hibernate, I spend a great deal of my time writing, updating, and debugging configuration files rather than implementing the valuable business logic I am paid to write.

Just imagine how much easier life would be if Spring knew where all your controllers were and Hibernate could find your domain objects all by themselves. Well, it turns out they can thanks to coding by convention, a development paradigm introduced by Ruby on Rails.

Coding by convention is at the heart of Grails, a rapid application development framework implemented in Groovy, a dynamic language that is syntactically similar to Java and runs in the Java Virtual Machine (JVM). Grails is implemented through a series of plugins. Each of these plugins is executed during application initialization and is able to register beans in the Spring ApplicationContext. There is a plugin to configure Hibernate, another plugin to tell Spring and Hibernate that all classes in the domain directory can be persisted to the database, another plugin to register all classes under the controllers directory as Spring controllers, and so on.

This article shows the power of Grails through the practical example of building a blog application. It does not cover Groovy in any depth, rather, it providing explanations only of the particular Groovy syntax that is used in the example. Simply put, Groovy can make calls to Java classes directly, so if you put your Groovy code in the right place, Grails does the rest.

Getting Started
Go to your development workspace and run this in the command prompt:

grails create-app groovypublish

This will create a folder called groovypublish and a grails-app directory under that, which contains the following directories:

  • conf
  • controllers
  • domain
  • i18n
  • services
  • taglib
  • utils
  • views

This article concentrates on the controllers, domain, and views folders. If you are familiar with the Model View Controller (MVC) pattern, you can figure out what goes in each of these directories, but they will be introduced in more detail as the example progresses.

Building the Blog, Domain First
Grails provides a coding-by-convention approach to Hibernate with an object-relational mapping (ORM) solution called the Grails Object-Relational Mapping (GORM). Through GORM, Groovy classes that are created in the domain directory are automatically picked up by Hibernate and can be persisted to and retrieved from the underlying database.

To build the blog application in Grails you need to start with a few simple domain objects. As the essence of a blog is a post, create a Post object first. Go to the command line in your project location and run this:

grails create-domain-class Post

You will notice that a Groovy class called Post.groovy has been created under the grails-appdomain directory. With your domain object created, you next need to add the necessary properties to it:

  • Title
  • Teaser
  • Content
  • Last modified
  • Published

Assuming that you also want to allow people to make comments on your post, create a Comment class:

grails create-domain-class Comment

You want each comment to have a Post that it relates to, a comment field, and the date it was created, so you can display comments in chronological date order. You also should capture who left the comment, so you will need a Commentator class to hold the details of the commentator:

grails create-domain-class Commentator

The next step in building your domain model is to link these classes so you can handle relationships between them. You do this by telling GORM that:

  • A Comment belongs to a Post.
  • A Post has many Comments.
  • A Comment has one Commentator.
  • A Commentator belongs to a Comment.

When you specify one class as belonging to another class you mean it cannot exist without the class to which it belongs. If a Post is deleted, then all its Comments will also be deleted. However, it is possible to delete a Comment without deleting the Post. To achieve the “belongs to” relationship, add a static property to the Comment class:

static belongsTo = Post

You need to create a bi-directional relationship between a Post and its Comments so you can view the comments for a particular post. To do this, add a static property to the Post class:

static hasMany = [comments:Comment]

This will dynamically create a property of type Set called comments on Post objects at run time. However, you want to guarantee the order of the Comment objects on the Post so you need to define your own property as a SortedSet:

SortedSet comments

To set up the relationship between a Comment and its Commentator you need to add a Commentator property on the Comment. You also need to create a relationship from Commentator back to Comment so that you can have the Commentator saved implicitly when a Comment is created. See Listing 1 for the initial domain classes with their relationships defined.

These domain classes define two conventions: the lastUpdated and dateCreated properties. If a domain object has these properties, the GORM will automatically populate the values when the save method is called.

Working with Your Domain Model
Now that you have the basics of your domain model, it’s time to work it. You can perform Create, Read, Update, and Delete (CRUD) operations very simply. Add the test case in Listing 2 to the PostTests class, which you will find in the test/integration folder. This class was generated when you created the Post domain class through the Grails command line tool.

Grails provides a constructor that takes named values when you create the Post object, allowing object construction to become much less verbose than in Java. Grails uses the Groovy Meta Object Protocol to inject dynamic methods into domain objects. The available methods are save, get, and delete:

  • The save method either creates or updates the object, depending on whether the object has already been created or not.
  • The get method will retrieve the object from the database, given the database identifier.
  • The delete method removes the object from the database.

Validate the Domain
Once you have your basic domain model, you are going to need to add some validation rules to make sure the data is correct. You will define these rules for a Post:

  • Title is required.
  • Title must be less than 50 characters.
  • Teaser is optional.
  • Teaser must be less than 100 characters.
  • Content is required.
  • Published is required.

Domain constraints are specified in the class using the static constraints property. This property is a closure, which contains a number of Groovy builder nodes that represent each property in the Domain class. The Post class with your constraints specified will look like this:

class Post {    static hasMany = [comments:Comment]    String title    String teaser    String content    Date lastUpdated    Boolean published = false    SortedSet comments    static constraints = {        title(nullable:false, blank:false, length:1..50)        teaser(length:0..100)        content(nullable:false, blank:false)        lastUpdated(nullable:true)        published(nullable:false)    }}

To verify these constraints are working, go back to your PostTests class and add a test case to make sure the title validation is correct:

void testTitleIsRequired() {    Post post = new Post(teaser:"foo",            content:"bar",            published:false)    assertNull(post.save())    post.title = "my title"    assertNotNull(post.save())}

Grails provides a number of default constraints, including URL and email validation. You will need to use these constraints for your Commentator class:

class Commentator {    static belongsTo = Comment    String name    String url    String email    Comment comment    static constraints = {        name(nullable:false, blank:false)        url(nullable:true, blank:true, url:true)        email(nullable:true, blank:true, email:true)            }}

Driving the Domain
The next step is to expose your domain objects to users through some controllers and views. This will allow you to manipulate your domain objects through a user interface. To create the controllers for your domain, go back to the command line and run the following commands:

grails create-controller Postgrails create-controller Comment

These will create two new classes in the grails-app/controllers directory called PostController and CommentController, respectively. If you take a look at the PostController, you will see there is not much to it?simply one closure called index:

class PostController {  def index = { }}

Grails uses a RESTful approach to mapping URL requests to controllers. You will employ this approach by adding a ‘Hello World’ output to the generated controller and accessing it once the application is running. The following simple controller example helps explain how to access a Grails controller from a URL:

class PostController {    def index = {        render("Hello world")    }}

A closure represents an action on a controller and is directly accessible through a URL request. The index closure is the default action. You can override that by defining the defaultAction property on the controller. (See “Sidebar 1. The Render Method” for more on the render method beyond this simple example.)

You can now run the Grails application by going to the command line in your project directory and executing the following:

grails run-app

See Figure 1 for the output of calling the default action on the PostController.

 
Figure 1. Hello World Example: This page shows the output of calling the default action on the PostController.

You should now be able to access your index action via the URL http://localhost:8080/groovypublish/post/. That is, Grails starts up a Jetty server that listens on port 8080; groovypublish is the name of the project and the web application context; and post maps directly to the PostController. Because nothing else is specified, the default action will be executed.

To see how you can access named actions in a controller, update your PostController to contain a goodbye closure:

class PostController {    def index = {        render("Hello world")    }    def goodbye = {        render("Goodbye world")    }}

It’s that easy to add a new action to an existing controller.

Next, go to the URL http://localhost:8080/groovypublish/post/goodbye. You should see the message ‘Goodbye world’ displayed. Notice that the application was not restarted between these changes. Grails allows you to make changes to the code in your development environment on the fly.

Now that you have seen the basics of controllers and actions, you need to modify your controller to provide access to the data in your domain:

class PostController {	def defaultAction = 'list'def edit = {    def post = Post.get(params.id)    if(!post) {        post = new Post()    }    render(view:'edit', model:[post:post])}def list = {    render(            view:'list',            model:[posts:Post.list(                    sort:'lastUpdated',                    order:'desc')])}}

The above code shows the edit and list actions on the PostController and makes the list action the default. The edit action loads an individual Post from the ID parameter (if the Post cannot be found, you create a new Post), puts the Post in the model, and renders the edit view. The list action loads all of the posts in order by the last updated date with the most recent first, puts it in the model, and then renders the list view.

Let the Users In
Now that you have a way of controlling access to your domain, you need to put some views on top so the users of your application can create and view posts. Under the grails-app/views/post folder, create the Groovy Server Page list.gsp with the following code:

<%@ page contentType="text/html;charset=UTF-8" %>        My Posts      

My Posts

${post.title}

${post.teaser}

Last Updated: ${post.lastUpdated}

This listing shows the list Groovy Server Page that you use to render the posts supplied by the PostController list action. The code iterates over the posts in the model and displays the title and teaser text.

You are almost ready to display your posts now. The next step is to load some test data when you start the application to verify that you can see the posts. Grails provides a BootStrap Groovy class in the grails-app/conf directory. This class has an init closure that is executed when the application starts up. If you put some initialization data in this closure it will be available to your application. The following code shows how to use the Grails BootStrap class to load data into the application before start up:

def init = { servletContext ->   new Post(title:"First Grails Project",           teaser:"Clearing out the clutter",           content:"The full content of the article",           published:true).save()   new Post(title:"Getting Ready for Go Live",           teaser:"The follow up on some real world issues.",           content:"The full content of the article",           published:false).save()}

Restart the running Grails application, go to the post index page at http://localhost:8080/groovypublish/post, and you can see the two posts you have created, listed in the order you created them in the bootstrap (see Figure 2).

 
Figure 2. List Posts Page: The two posts created in the BootStrap class should be displayed.

Create a New Post
To allow users to create a post, you need to provide a link from the list page, create the GSP input form, and create a new action to save the data to your database. So far, you have used your first Grails tag to create a link to the edit Post action (by default, Grails tags are defined in the g namespace). Now define the controller and the action that the link should send the user to as follows:

    Create a new post

Remember that you have already defined the edit action. What you don’t have is an edit page to render the form that allows posts to be created or edited. Grails provides a number of tag libraries for rendering forms, input fields, and validation errors that occur from a form submission:

  • The tag displays the validation errors from your submission as an HTML list.
  • The tag renders an HTML form that submits?using the post method by default?the data to the specified action on the controller.
  • The and tags render the HTML for a text area input field and a text input field, respectively.

Listing 3 contains code for the Groovy server page that allows users to edit or create a Post. The edit.gsp code needs to go in the same location as your list.gsp: grails-app/views/post.

You can see from the tag in Listing 3 that you need to create an action called save on the PostController to handle the form submission:

def save = {    def post = loadPost(params.id)    post.properties = params    if(post.save()) {        redirect(action:'list')    } else {        render(view:'edit', model:[post:post])    }}private loadPost(id) {    def post = new Post();    if(id) {        post = Post.get(id)    }    return post}

To enable the save action to both create a new post and update an existing post, the first thing you do is load the post. You refactored out the logic in your edit action earlier to a private method that can be reused by this action. Once you have the post, you need to update the properties so it can be saved. Grails provides all the values you submitted from the form as a Map called params and also provides a properties property on each domain object to expose all the properties of the object as named values in a Map. This allows you to set all the values you have sent from the form directly onto the domain object by assigning the request params to the domain objects properties field.

The validation is performed when you try to save the post. If the validation succeeds, you send the user back to the list page to view the post. If it fails, you render the edit page again and put the updated post object in the model.

Edit a Post
To allow a user to edit a post, add a link to the edit action in the PostController:

  Edit this post

This is almost the same as the link to create a new post, but in this case you specify the identifier of the post. This will allow the edit action to load the post to be edited from the database and display it.

View a Post
You now can allow users to view the full text of a post. Create a view action on the PostController:

def view = {    render(view:'view', model:[post:Post.get(params.id)])}

Next, create a view GSP in the grails-app/views/post directory:

<%@ page contentType="text/html;charset=UTF-8" %>    ${post.title}

${post.title}

${post.teaser}

${post.content}

This listing shows the Groovy server page used to render the details of a post.

Finally, add the link to the post list page to allow a post to be viewed:

  View this post

Add Comments
The last thing you need to do for your basic blog is to allow people to add comments. To do this you will need to:

  • Update your CommentController.
  • Create an edit.gsp in the grails-app/views/comment directory.
  • Display comments on the view post page.

The CommentController needs to have only edit and save actions, as comments will be viewed in the context of a post. The Controller in Listing 4 provides a new Comment to the edit form and then saves the comment once it is submitted.

The CommentController contains two new items of interest. The first is the content of the params object when a new Comment is created. This params object will contain value key pairs with the following structure:

  • comment: the users comment
  • who.name: the name of the person leaving the comment
  • who.email: the email of the commentator
  • who.url: the website address of the commentator

This structure will populate the fields of the Comment and its Commentator object. Be aware that you are saving only the comment object and the commentator is being implicitly saved because it belongs to the comment.

The comment edit page is again very basic (see Listing 5).

Finally, you need to add some code to the view.gsp for Posts to allow the comments for a post to be displayed:

    

${comment.comment}

Made by: ${comment.who.name} on ${comment.dateCreated}

You now have a simple functional blog application, written in under 250 lines of code. In fact, the source code is about 120 lines, including the HTML. This line count does not include any configuration files, because there aren’t any. This is the power of Grails. It leverages the coding by convention paradigm to give you access to robust and mature Java open source frameworks such as Spring and Hibernate.

Now that you understand the basics of Grails, be on the lookout for the follow-up article: a look at some more Groovy Grails features, along with instructions for preparing the application for a production environment.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

The Latest

Top 5 B2B SaaS Marketing Agencies for 2023

In recent years, the software-as-a-service (SaaS) sector has experienced exponential growth as more and more companies choose cloud-based solutions. Any SaaS company hoping to stay ahead of the curve in this quickly changing industry needs to invest in effective marketing. So selecting the best marketing agency can mean the difference

technology leadership

Why the World Needs More Technology Leadership

As a fact, technology has touched every single aspect of our lives. And there are some technology giants in today’s world which have been frequently opined to have a strong influence on recent overall technological influence. Moreover, those tech giants have popular technology leaders leading the companies toward achieving greatness.

iOS app development

The Future of iOS App Development: Trends to Watch

When it launched in 2008, the Apple App Store only had 500 apps available. By the first quarter of 2022, the store had about 2.18 million iOS-exclusive apps. Average monthly app releases for the platform reached 34,000 in the first half of 2022, indicating rapid growth in iOS app development.