Tuesday, October 27, 2009

RSS Builder in Grails in a Few minutes

As I planned to include RSS feeds into www.spenddaywithkids.com I needed possibility to create kind of RSS Builder. The good example of what I needed is IceRocket RSS Builder. So you are not generating RSS feeds directly from the data on your site but you are writing them manually. This way RSS feeds become kind of communication channel between the web site and users.

I would stay with IceRocket but I couldn’t find possibility to do even simple formatting for RSS items. So my thought was let see how it is complicated to do it in Grails. And it turned out that it takes only few minutes to get very similar functionality. So here is short example done almost step by step.

Note: As my site is currently running on Grails 1.0.3 maybe not everything will be compatible with 1.1 version out of the box.

So let go with implementation.

First create grails application and named it rssbuilder.

grails create-app rssbuilder
Then create two domain classes:
class RssChannel {
String name
String channelLink
String description

static constraints = {
name(blank:false, nullable:false, unique:true)
channelLink(blank:false, nullable:false, unique:false, url:true)
description(blank:true, nullable:true, maxSize:30000)
}
}


class RssItem {
String title
String itemLink
String summary
RssChannel rssChannel
Date dateCreated
Date lastUpdated

static constraints = {
title(blank:false, nullable:false, unique:false)
itemLink(blank:false, nullable:false, unique:false, url:true)
summary(blank:false, nullable:false, unique:false, maxSize:50000)
rssChannel(blank:false, nullable:false, unique:false)
}
}
Ah, don’t forget to install two plugins: Feeds Plugin and RichUI plugin.

Now we can generate controllers and views for two domain classes:
grails generate-all RssChannel
grails generate-all RssItem
Well now if you start application you are able to specify RSS channel and items for RSS channel. To provide possibility to specify better formatting for RssItem we can reuse <richui:richTextEditor tag from the RichUI plugin. In the create and edit view of the RssItem change summary and bind it to the richTextEditor. More or less you should input tag with the following:

<richui:richTextEditor name="summary" value="${rssItem?.summary}" width="525" height="525" />
Now to generate RSS feed we can reuse functionality of the Feed plugin. So create FeedController class with command grails create-controller Feed.

The code of the feed controller should be:

    def rss = {
if (!params.id) {
render "missing id in params"
return
}

RssChannel rssChannel = RssChannel.get(new Long(params.id))

if(!rssChannel) {
render "rss channel not found"
return
}


render(feedType:"rss", feedVersion:"2.0") {
title = rssChannel.name
link = rssChannel.channelLink
description = rssChannel.description
RssItem.findAllByRssChannel(rssChannel, [sort:"dateCreated", order:"desc"]).each() { item ->
entry(item.title) {
link=item.itemLink
item.summary
}
}
}
}
So now if you start application and create RSS channel and some items in that channel all you need to know is ID of that channel.

If the Id of the channel is e.g. 1 in the browser write http://localhost:8080/rssbuilder/feed/rss/1 and you will see your feed.

I believe this was really easy :)

As soon as I switch fun places to go with kids to the Grails 1.1 I will create plugin from this.

Monday, October 26, 2009

Grails scaffolding for domain classes in packages

While working on one simple subproject for spend day with kids I got one interesting issue. I don't use scaffolding too often but this time I needed to get proof of concept. And I came to something where I am not sure if it is a bug or feature. And just to be clear this is happening with Grails version 1.0.3 and I am not sure if it is reproducible in later versions.

Note: Having packages for domain classes is highly advisable and you should always use packages for all domain classes.
So let get to the point. I have create following domain class (please notice that package is defined).

com.jan.rssbuilder.domain.RssChannel
And after that I have created RssChannelController this way:
package com.jan.rssbuilder.domain

class RssChannelController {
def scaffold = true
}
After accessing this controller I got following exception:
java.lang.IllegalStateException: Scaffolder supports action [index] for controller [com.jan.rssbuilder.domain.RssChannelController] but getAction returned null!
After changing controller by specifying domain class everything worked fine:
package com.jan.rssbuilder.domain

class RssChannelController {
def scaffold = com.jan.rssbuilder.domain.RssChannel
}

Sunday, October 18, 2009

Tips for working with front-end in Grails

I have implemented few web projects with Grails and some techniques while working with Grails front-end turned out to be better than other. When I didn’t follow them later on I usually had to refactor the code and did it the correct way.

If you are reading this blog you noticed that I write very often about developing front-end with Grails. The reason is not that I am the best in the front-end but the reason is that I am the worst in the front-end. I am back-end developer and what I was missing in the majority of web frameworks was impossibility to make front-end more modular. In Grails this is easily to achieve thanks to Grails templates and tags. And then you are almost to code in the normal java code.

But come back to tips.

Tip 1: Always create one gsp page per state of the result.

Tip 2: Use templates and tags to make your pages more modular.

Tip 3: When ever it gives sense send custom model classes to the gsp page (not the domain classes).

Well tips are nothing without some example. As an example I will take my latest project fun things to do with kids.

In the first installment home page had following responsibilities:

  • As a starting point for visitors
  • To display found places to go with kids
  • To inform user that the city provided cannot be uniquely identified (there is more than one city with provided name)
  • To inform user that no attractions were found around provided city

As you can see that is obvious break of the SRP (single responsibility principle). Because of too much responsibilities the model I was sending to the page was quite complex and the page contained number of if blocks. And you must admit that having if blocks in the html page is not the best practice. Another side effect was that page had about 300 lines that is simply too much.

So what I did? Well, of course I did some refactoring.

I have created one page per responsibility and depending on result controller decide which page to display and provides correct data model (is this maybe kind of strategy pattern?). This way it is much easier to understand what pages are doing. And now they are up to 30 lines long.

But if you check pages you can see they are quite similar:

To see home page navigate to: spend day with kids
To see page with results navigate to: things to do with kids in Nottingham
To see page where there are multiple cities e.g. search for Malinovo. Select Malinovo, Slovakia to see places to visit nearby my home :)
To see page where there are no results check e.g. for Belgrade.

If you checked all these pages you can notice that they are very similar but little bit different. So how do you solve similarities. Very easy. Use templates and tags.

And the last but not the least, it is obvious that the data models delivered to the pages can be quite different and even some cases need not to contain any domain classes.

So I hope that those tips will help you while working on your own grails projects.

Saturday, October 17, 2009

New features on spend day with kids

I have finally found some free time so I decided to implement some new features on spend day with kids.

So far all searches have been performed with the same default parameters. The defaults were distance is 100 kms and the sorting of attractions was by type.

Very soon after the launch of the site I got mail from Jeff where he proposed that results should be displayed in the order of proximity from the provided city. I liked the idea immediately and now this feature is supported.

So now you can provide city or even address and specify the distance of places to be searched and additionally to select ordering type. Possible ordering types are of course by distance and by city.

As you probably know spend day with kids site helps you find great family days out and is implemented with Grails. While developing this site, so far I didn't hit any special interesting features that could be worth for blogging about. But if you have any ideas just let me know

Saturday, October 10, 2009

Hope to have more material for blogging

I am aware that last few weeks I was quite lazy with blogging but as I was changing employer so lot of responsibilities have been in front of me. Of course, important part was knowledge transfer. From the October I am in my new company.

First I would like to thanks my previous company for having a chance to work on interesting and exciting projects.

In the new company I am coming to the position of Head of Software Development. It is a small start up company and we are working on the green field project. Yes, you see it right, its green field :)

As my future work will include some new technologies and different market I hope that I will have lot of materials for blogging. We will mainly work with affiliate networks and mobile web development. As this is quite new field for me I believe I will be able to share a lot of interesting discoveries.

As the field we will be working in is very dynamic we are of course on Scrum and agile software development. Dynamic projects and agile software development create great combination. I am very sure we will have lot of fun.

Wednesday, October 7, 2009

Software books reviews down - permanently (so far)

It has been some time as I planned to take down software books reviews. Although I don't think that the idea was bad it takes time to make the site grow and support from the community was not so good.
As running site takes some money, lot of time and I have two other sites online too: grails tutorials and things to do with kids I have to choose which one to take down.
So my decision was to take down the software books reviews.

Now I want to be able to concentrate on my new work and to try to extend functionality of the spend day with kids site. I promised few months ago that I will open source grails tutorials and I still plan to do that. The problem is that I need few days of additional work before I open source it and I am not able to find those day.

So for all that were visiting software books reviews, sorry but I had to take it down.

Sunday, September 27, 2009

Getting data into Grails tags and templates

In the post describing how to create and use grails templates and tags I made short example that showed how gsp pages can be readable if you are using tags and templates. One of the questions asked in comments was how do I get data into tag and/or template. Instead writing answer as comment I decided to write the whole post.

Scoped variables
Common way to get data into tag and template is using Grails scoped variables like application, session, request. This means that both, tags and templates, have access to those variables so you can use them.

Templates
To send data into templates you can and should use standard approach with the grails model.

For example if you are rendering template from tag or from controller (or some groovy code) you should use construct like this one:

render(template:"/templates/common/messageBoxTemplate", model:[title:"hello world"])

If you are rendering template from gsp page you should use construct like this one (actually taken from grails documentation):

<g:render template="displaybook" model="['book':book,'author':author]" />

To be honest I try to avoid using <g:render... from gsp pages because if you are using tags it is easier to read the gsp page. Another advantage of using tags is that it is easier to refactor the gsp pages. So when you find yourself writing <g:render template.... in the gsp page, introduce grails tag for that.

Tags

The advantage of tags is that they have access to the GORM classes and you can inject any grails service into tag. So if you need to perform some calculation that needs to be displayed on the gsp page tag is the right place for that.

Another way to send data into grails is via attrs map. Each tag is specified in the file ending with TagLib and the format of the tag is:

def messageBox = {attrs, body ->
out << render(template:"/templates/common/messageBoxTemplate", model:[title:attrs.title, body:body()])
}

So tag is closure with two variables: attrs and body. Using attrs you can access any custom data sent to the tag.

So how do we send that data?

When displaying tag from the gsp page you are using construct like this one:

<g:messageBox title="Register, it takes only seconds">

In this case the title is custom data sent to the tag.

To execute given tag from the controller or some other groovy code you can use construct like this one:

g.messageBox(title:"Register, it takes only seconds") {
//body to be displayed
}

So for example, to display number of registered users on the grails and groovy tutorials page I am using direct access to database from the tag and then sending those data to the model. But I could also create e.g. application scoped variable for this and gain some performance. So currently the code in the tag looks like this:

def dataInfo = {attrs, body ->
def postsCount = TutorialLink.count()
def userCount = User.count()
out << render(template:"/templates/common/statsTemplate", model:[userCount:userCount, postsCount:postsCount])
}