Chapter 6. Developing tasty views, forms, and layouts


In this chapter

  • How GSPs work
  • The common GSP tag libraries
  • Rendering and processing forms
  • Writing custom tag libraries
  • Creating stunning layouts
  • Adding visual effects and animation
  • Explore interactive Ajax tags and remoting

We’ve spent most of the book so far building the heart of Hubbub: processing incoming requests, interacting with the data model, calling business logic, and creating posts, users, and timelines. It’s been a lot of fun, but not visually satisfying. It’s time to leave the core functionality behind and do some work on the user interface (UI) of our web application.

A great-looking UI has all sorts of subtle impacts on the user. People think that a visually pleasing application is more robust, more performant, and more productive than a bare-bones application, even though none of that may be true.

In this chapter, we’ll focus on the frontend. We’ll cover the basics of putting forms together, and we’ll investigate how to support multiple browsers by using reusable layouts. We’ll also turn our attention to visual effects and implement some slick animations and Ajax interactions. By the time we’re done, Hubbub will sparkle.

We first need to get a good grasp of Grails’ primary view technology: Groovy Server Pages (GSP), so our UI adventure will begin with a tour of the core GSP form tags.

6.1. Understanding the core form tags

We’ve been making use of GSPs to handle our HTML output since chapter 1, but we haven’t given you a solid introduction to them. GSP is an evolution of view technology from Java Server Pages (JSP). The things that were difficult in JSP (particularly tag libraries) are much simplified and accessible in GSP. When you catch yourself developing custom taglibs while your application is running (and not requiring a restart), you’ll fall in love.

In this section, we’ll cover all the basic GSP tags you’ll use from day to day when designing forms and user interactions. Whether it’s flow control, iteration, or complex form management with error handling, you’ll find it all here. But it all starts with getting a feel for “if” tests.

6.1.1. A handful of essential tags

You’ll spend most of your time working with Grails views, using a few core GSP tags. It’s time to learn a few of the most common tags.

The first tags you need to learn are the logical and iteration tags. Every programmer loves a good if() test, so listing 6.1 introduces <g:if> being used to test usernames.

Listing 6.1. The basic if tag
<g:if test="${user?.name == 'Chuck Norris'}">
Roundhouse Kicks welcome here.
</g:if>
<g:elseif test="${user?.name == 'Jack Bauer'}">
Lock up your Presidents.
</g:elseif>
<g:else>
Take a number. We'll call you when we're ready.
</g:else>

The else and elseif blocks are optional. Use if, if ... else, or if ... elseif ... else in whatever combinations you want.

Another common tag is <g:each>, which iterates through a collection or array. It is often used when accessing a domain class member collection, such as iterating through followers:

<g:each var="nextUser" in="${following}">
<li>${nextUser.userId}</li>
</g:each>

The <g:if> and <g:each> tags are the bread and butter of select and iteration, and you’ll use them a lot. But you’ll also need to combine them with some basic link tags to keep your user moving through the application. Let’s look at how we can introduce some workflow with the versatile <g:link> tag.

6.1.2. A pocketful of link tags

Another common set of tags is the linking tags. These give you convenient ways to generate URLs that link to controller actions.

Here’s an example:

<g:link controller="post" action="global" >Back to Hubbub</g:link>

You can omit the action attribute if you’re linking to the default action.

Similarly, if you’re linking to another action in the current controller, you can omit the controller attribute. For example, if the previous action was /post/edit, you could link back to the timeline action (/post/timeline) with this link:

<g:link action="timeline" >Back to Timeline</g:link>

But sometimes you don’t want a full anchor tag—you want the target URL. This can be handy for Ajax, where you need to work in URL terms, but it’s also handy in generating <img> tags. When generating thumbnail tags for your followers, you could use something like this:

<img src="<g:createLink action="renderImage" controller="image"
id="${nextUser.userId}"/>" alt="${nextUser.userId}"/>

This will create a URL like /image/renderImage/glen. Remember that the last part of the URL forms the params.id attribute in your controller. All of the linking tags support action, controller, and id attributes, so you have a lot of flexibility.

Although <g:link> and <g:createLink> are the most common link tags, there is another one that you’ll use less frequently: <g:createLinkTo> (yes, the names are confusing). The <g:createLinkTo> tag is handy for generating links to files within your application, and its most common use is with CSS and static images. Here’s an example:

<link rel="stylesheet"
href="${createLinkTo(dir:'css',file:'hubbub.css')}" />

That’s not a tag; that’s a method call!

You can reference all tags using a method-style syntax—with attribute maps as an argument—rather than using the more classic JSP-style invocation. The preceding code line is equivalent to this:

<link rel="stylesheet" href="
<g:createLinkTo dir='css' file='hubbub.css'/>
"/>

Some people find this method-style invocation easier to read when nesting tags within other tags. In this example, it gets tricky to work out which /> belongs to which tag, but a good IDE goes a long way to making this clear.

The link tag names are similar, and this can be confusing. They’re summarized in table 6.1.

Table 6.1. Link-related tags

Tag

Description

link

Generates an <a href> around the enclosed content

createLink

Generates a URL for embedding in another tag

createLinkTo

Generates a URL to a local file


Tip

In chapter 5, we explored URL-mapping tricks with entries in UrlMappings.groovy. The good news is that the link tags are aware of your rewrite rules and will honor those mappings.


Our next core set of tags involves form handling. Let’s explore the flexibility available with the Grails form tags.

6.1.3. A tour of the form tags

Forms are the bread and butter of web interactivity. You’ll be spending a lot of time generating forms in GSPs, and processing their results in controller actions, so it’s important to understand how to use the HTML form-field tags in GSPs. You’re free to mix and match regular by-hand HTML form fields with Grails tags, but you’ll find that the form tags make things simpler and more maintainable.

At the end of the last chapter, we showed you how to use command objects to process a user registration, but we didn’t use any form tags in the registration form. Listing 6.2 shows a revised attempt at a registration form using the standard Grails form tags. We’ve introduced a few fake fields so we can demonstrate what is available.

Listing 6.2. Our new registration form demonstrates many of the core form tags.

That’s a lot of tags. We’ll be spending the rest of this section discussing these core tags, but this gives you a chance to see them in use first. Figure 6.1 shows how the form is rendered.

Figure 6.1. A registration form that uses the core form tags

The form needs some layout work, but functionality-wise we’re progressing well. That’s a pretty comprehensive survey of all the basic form tags. Let’s take a look at them each in turn.

The Basic Form Tag

All Grails forms start with a <g:form> or <g:uploadForm>, depending on whether you’re supporting file uploads or not. You configure the form tags with an optional action and controller name:

<g:form controller="user" action="register">

As with the <g:link> tag we discussed earlier, you can usually rely on conventions. For instance, if you’re inside another User action (such as /user/list), you can describe your form in terms of the target action, and it will default to the current controller:

<g:form action="register">

If you want the form to submit to the current action, you can even omit the action name.

Basic Textfields, Textareas, and Passwordfields

The cornerstone of web form development is making use of text fields. The three basic variants include <g:textField> (single line), <g:textArea> (multiline), and <g:passwordField> (single line with asterisk placeholders).

Our registration form uses the single-line versions:

<g:textField name="userId" value="${newuser?.userId}"/>
<g:passwordField name="password" value="${newuser?.password}"/>

The name attribute refers to the name of the field in the params object being submitted to the target action. In this example, we’ll have params.userId and params.password holding the values.

All form fields support a value element that represents the prepopulated value of the form. In the preceding example, we use the safe dereference operator (?.) to keep our values null-safe for the initial form display.

Although we didn’t use a textArea in listing 6.2, they follow the same basic format as the other text-based fields:

<g:textArea name="bio" value="${newuser.bio}" rows="10" cols="60"/>

This will render a textArea with the specified size, prebound to the target value of newuser.bio.


How can I pass custom HTML attributes to Grails taglibs?

The textArea tag only explicitly supports name and value attributes, but it passes through unknown attributes to the generated HTML tag. This means you can use the standard rows and cols attributes of HTML TextAreas.

This passthrough mechanism exists for all Grails tags, so if there are specific HTML attributes you want rendered in the final tag output (perhaps a class attribute for CSS styling), just add them to the tag’s attributes and they will be passed through.


The Drop-Down Joy of Select

One of the most complex (and sophisticated) Grails form tags is <g:select>. The select tag lets you generate drop-down boxes populated from backend data sources or embedded lists and ranges.

The tag expects the from attribute to contain a list of objects (or a range if you prefer). You then supply an optionKey and optionValue that represent the property on each object that should be used to generate the drop-down list.

Let’s revisit our registration example from listing 6.2:

<g:select name="referrer"
from="${com.grailsinaction.Profile.list()}"
optionKey="id"
optionValue="fullName"
noSelection="${['null':'Please Choose...']}" />

The from attribute retrieves a list of profiles from a backend domain class. The optionKey attribute represents the Profile object’s id field, and it is the value that will be submitted for the referrer parameter. The optionValue attribute represents the string that will be displayed in the drop-down list itself—it displays the Profile object’s fullName field.

The special case in which nothing is selected is handled by the noSelection attribute, which takes a map with a key of 'null' (the string, not the value).

The from field is a piece of Groovy code, so you can use any sort of dynamic finder you like to generate the list, or you can provide a static list if that makes sense:

<g:select from="['Groovy', 'Java', 'Python']" name="preferredLanguage"/>

If you don’t supply optionKey and optionValue, the tag does a toString() on each element in the list for both the key and the value, which is perfect for when you need a static list.

Check Boxes and Radio Buttons

Check boxes are supported through a simple tag that consists of a name and a value representing the checked status:

<g:checkBox name="spamMe" value="${newuser.spamMe}"/>

Radio buttons give you a little more flexibility. The most common way to work with radio buttons is via a radioGroup. In listing 6.2, we implemented emailFormat using the radioGroup tag:

<g:radioGroup name="emailFormat"
labels="['Plain','HTML']"
values="['P', 'H']"
value="H">
${it.label} ${it.radio}
</g:radioGroup>

Notice that you have to supply both labels and values for the buttons.

The radioGroup tag is also a little different from checkBox in that the tag iterates through its contents once for each entry. That’s why we need to supply those ${it.label} and ${it.radio} elements, which get rendered once for each radio button. This iterating approach gives you a lot of flexibility in how the radio buttons are marked up, but it’s a bit of a corner case amongst the Grails form taglibs.

Grails also provides a <g:radio> tag for cases when you want to generate your radio buttons without iteration, but you have to set the same name attribute for each button in the group. For this reason, it’s often safer to go the radioGroup approach.

Hidden Fields

Although we didn’t demonstrate hidden fields in listing 6.2, they’re a special case of a <g:textField> that doesn’t display in the browser. Here’s an example:

<g:hiddenField name="dateRendered" value="${new Date()}" />

You’re free to put whatever text values you like in a hiddenField, and they will end up in the params map when the form is submitted.

Handling Multiple Submit Buttons

Having multiple buttons on one form can make form handling awkward. Traditionally, you had to submit the form to one controller, then have a big switch statement to route to the appropriate action based on which button was clicked.

Grails provides the <g:actionSubmit> button, which makes it easy to send the form to the right action, handling the messy routing stuff for you. Here’s an example:

<g:actionSubmit value="Register" />
<g:actionSubmit value="Cancel" action="cancelRegister" />

You’ll notice that we’ve specified the action on one button and not the other. If you don’t specify an action name, Grails will assume the action is the lowercased name of the button (/user/register for the first button). If you use a different convention, you’re free to specify the action name (as we did in the second line, which submits to /user/cancelRegister).

Handling Date Selections

One of the least-documented Grails tags is the datePicker. This tag creates a series of controls that allow the user to select a date value.

The tag renders a series of combo boxes for the user to select the day of the month, month name, and year (and optionally values for hours, minutes, and seconds) making it ideal for applications that take care of things like hotel booking or flight dates. When the user submits the form, the Grails data binder turns the collection of controls into a Java Date object, making date-handling very straightforward.

Creating a datePicker is very straightforward:

<g:datePicker name="arrivalDate"
value="${myBooking.arrivalDate}"
precision="day"/>

The precision field specifies which fields you want the user to be able to enter. In the preceding example, the value of day will provide fields for the day, month, and year. Setting the precision to minute would create additional fields for both hours and minutes in the datePicker. See the Grails reference guide for a complete set of configuration options.

One common gotcha when working with the datePicker is that your controller must use Grails’ data binding mechanism (either a bindData() or a properties assignment) in order for the conversion of the datePicker controls to work. In practice, that means you must not use Groovy-style property binding to do your initial save. For example, new Booking(params) .save() won’t work when processing forms containing datePickers. Also, don’t expect params.arrivalDate to return a date—the actual date is built up during data binding from the several HTML controls that the datePicker tag generates.

Tag Summary

We have covered a lot of ground so far, and introduced many of the common tags that you’re likely to use. Tables 6.2 and 6.3 summarize both the common and less common tags that you’ll encounter when developing with Grails.

Table 6.2. Summary of basic form tags

Tag

Description

g:form

Creates a standard HTML form element

g:uploadForm

Creates a form that supports nested file upload elements

g:textField

Creates a single-line text field

g:passwordField

Creates a single-line text field with opaque characters

g:textArea

Creates a multiline text field

g:checkbox

Creates a check box that returns a true or false value

g:radio and g:radioGroup

Creates a radio button that can nested in a radio group for scenarios where only one option can be selected

g:select

Creates a drop-down box with prepopulated elements

g:hiddenField

Creates a field that isn’t visible in the browser

g:actionSubmit

Creates a button that submits the form to a particular controller action

Table 6.3. Less-common UI-related form tags

Tag

Description

g:datePicker

Creates a series of drop-down lists for current time and date selection

g:currencySelect

Displays a user-selectable list of currencies

g:paginate

Displays a series of page navigation links for multipage datasets

g:timezoneSelect

Displays a user-selectable list of Java time zones

g:countrySelect

Displays a user-selectable list of countries

g:message

Displays a message from a message-bundle

g:hasErrors

Tests whether an object has validation errors

g:renderErrors

Renders all validation errors on an object as a list

g:javascript

Embeds a JavaScript inline or a link to a JavaScript file or library


Tip

Grails lets you use legacy JSP taglibs in GSPs. If you have existing validation or utility taglibs, there’s no need to rewrite them—just add a <% @taglib %> directive to your GSP. Check out the online docs at http://grails.org/doc/1.1.x/ for examples.


That completes our whirlwind tour of the core Grails form tags. We’ll spend the rest of the book applying those tags, so don’t feel too overwhelmed—you’ll get plenty of practice!

There’s one other tag that deserves special consideration because it implements the tricky concept of pagination—datasets that you can browse through over multiple pages. In the next section we’ll use it to add pagination to Hubbub’s timeline feature.

6.1.4. Adding pagination to the timeline

One of the most unusual and useful core tags is <g:paginate>. It renders a series of navigation links so you can move through multiple pages of results.

Our global timeline in Hubbub will have entries for all the posts in the system, so it’s going to grow rapidly. Adding a <g:paginate> tag allows us to add navigation links to older posts, as shown in figure 6.2.

Figure 6.2. The <g:paginate> tag in action

Provided that your controller has populated a count of the entries that can be paginated, using the tag is as simple as passing on this total. You can also tell it how many results you want displayed per page using the max parameter (max is optional, and it defaults to 10).

<g:paginate total="${postCount}" max="25" />

The tag divides the total number of entries by the maximum per page and creates links for each page. Each page link is sneakily marked up to point to the current controller, with max and offset values (for example, max=25, offset = 50). When you click on the link for the third page in the timeline, you’ll navigate to /post/global?max=25&offset=50.

Dynamic finders know about the max and offset variables, so when an action like the following one executes, the params collection passes max and offset values to Post.list():

def posts = Post.list(params)
def postCount = Post.count()
[ posts, postCount ]

This means list() will honor those values in the query, offsetting the query result list and returning the next “page” of posts. Try out the paginate tag in the Hubbub global timeline so you can see the magic at work (and understand exactly what’s happening).

You now have a good grasp of all the core Grails form UI elements. But there are situations when none of the standard tags will do, and you need to write your own. We’ll look at that next.

6.2. Extending views with your own tags

We’ve used a lot of the standard Grails tags for form elements, conditional branching, error handling, and even iteration. But what about when the built-in options aren’t specific enough? There are options for developing your own tags, so let’s write a few of our own.

Grails supports three different types of custom tags, as listed in table 6.4.

Table 6.4. Types of custom tags supported by Grails

Type

Description

Example

Simple Tags

Outputs HTML

<g:button>

Logical Tags

Performs a conditional output based on a test

<g:if test="">

Iterative Tags

Iterates through a collection, rendering content for each element

<g:each in="">

The good news is that you can write whatever simple, logical, and iterative tags you need. We’ll write one of each type to give you some ideas.

6.2.1. Simple tags

Our Hubbub timeline could use a date upgrade. Most Web 2.0 apps support those “5 minutes ago” dates, which look cool and solve time-zone issues. Let’s implement a dateFromNow tag that will take a date and output a nice format.

It will come as no surprise that we start with a template:

grails create-tag-lib date

This will generate the shell of a taglib in /grails-app/taglib/DateTagLib.groovy. Implementing simple tags involves processing the attrs parameter and rendering HTML to the output stream.

We’ll invoke our tag like this:

<g:dateFromNow date="${post.created}"/>

Implementing the dateFromNow tag in the DateTagLib class involves creating a closure called dateFromNow and processing the date attribute. Listing 6.3 shows a first draft of the implementation.

Listing 6.3. Creating a custom dateFromNow tag

We access date using attrs.date, and pass it to our getNiceDate() method to turn it into “x minutes ago” format, and then we output the result to the stream. Groovy overloads the << operator for streaming objects to perform a write(), so there’s nothing more to do than implement our getNiceDate() business logic, as shown in listing 6.4.

Listing 6.4. Implementing a much nicer date format for Hubbub
static String getNiceDate(Date date) {

def now = new Date()

def diff = Math.abs(now.time - date.time)
static final long second = 1000
static final long minute = second * 60
static final long hour = minute * 60
static final long day = hour * 24

def niceTime = ""

long calc = 0;

calc = Math.floor(diff / day)
if (calc) {
niceTime += calc + " day" + (calc > 1 ? "s " : " ")
diff %= day
}

calc = Math.floor(diff / hour)
if (calc) {
niceTime += calc + " hour" + (calc > 1 ? "s " : " ")
diff %= hour
}
calc = Math.floor(diff / minute)
if (calc) {
niceTime += calc + " minute" + (calc > 1 ? "s " : " ")
diff %= minute
}

if (!niceTime) {
niceTime = "Right now"
} else {
niceTime += (date.time > now.time) ? "from now" : "ago"
}

return niceTime
}

We now have a reusable tag we can use wherever we need to render a date in “x minutes ago” format. We’ve used a single attribute (date) for our example, but your tags can have multiple attributes.


What’s the g:? Using custom namespaces

All our sample tags have taken the form <g:tagName>. The g: prefix is referred to as the tag’s namespace. If you don’t specify a custom namespace for your taglibs, they will use the <g:> prefix. How do you customize this? Add a new declaration to your DateTagLib.groovy file:

static namespace = "hubbub"

If you do this, you can refer to your tags as <hubbub:dateFromNow ...>. It’s best to use short namespaces to reduce typing, so let’s use a namespace of “h” for Hubbub tags so we can specify <h:dateFromNow>.

You should always declare a namespace for your tags so they’re less likely to collide with other tags—particularly with future Grails built-ins.


Now that we’ve implemented a simple tag, let’s explore Grails’ support for building logical tags.

6.2.2. Logical tags

Sometimes you want to display a block of content conditionally. Let’s say we only want to display certain content to Internet Explorer users. We might do something like this:

<h:lameBrowser userAgent="MSIE">
<p>Dude, Firefox really is better. No, really. </p>
</h:lameBrowser>

We want IE users to see this message, but all other browsers will pass on by. Let’s implement a UtilTagLib as shown in listing 6.5.

Listing 6.5. A lameBrowser tag demonstrating logical tags in action

Notice that logical tags take two arguments: attrs, which you’ve already seen, and body, which contains the content block inside the tag. If the test evaluates to true, we render the body() to the output stream; otherwise we send nothing.

This sort of tag is common for security scenarios. For example, when using the JSecurity plugin, you’ll often employ convenience tags like isLoggedIn for conditional output :

<jsec:isLoggedIn>
<div>Logged in as: <jsec:principal/>
(<g:link controller="auth" action="signOut">
sign out
</g:link>)</div>
</jsec:isLoggedIn>

Notice that the contents of your logical tags may themselves be complex GSP fragments that call other tags in other taglibs.

With our exploration of logical tags complete, let’s turn to the last style of custom tags Grails supports: iteration tags.

6.2.3. Iteration tags

The most complex of the custom tag types is the iteration tag. This type of tag performs multiple invocations of its body() with different input values for each iteration.

The Hubbub sidebar should contain images for the friends that we’re following. We could implement it as a standard <g:each> tag, like this:

<!-- People I am following -->
<div id="friendsThumbnails">
<g:each var="followUser" in="${following}">
<img src="
<g:createLink action="tiny" controller="image"
id="${followUser.userId}"/>
"alt="${followUser.userId}"/>
</g:each>
</div>

An eachFollower tag, on the other hand, would give us a more visually pleasing approach and let us do something like this:

<h:eachFollower in="${following}">
<img src="
<g:createLink action="tiny" controller="image"
id="${followUser.userId}"/>
" alt="${followUser.userId}"/>
</h:eachFollower>

The eachFollower tag can be implemented with an iterating call to the body method:

def eachFollower = { attrs, body ->

def followers = attrs.followers
followers?.each { follower ->

body(followUser: follower)

}

}

But that’s a lot of work to replicate the standard behavior of <g:each>. To be honest, we can’t think of too many scenarios where you’re not better off using the more explicit semantics of <g:each>. A smarter use of your time would be implementing a tag for user thumbnails, which we’ll explore next.

6.2.4. Calling one tag from another

When you’re developing your own custom tags, you often want to reuse standard Grails tags from within your own implementation. For example, if you were building a custom tag that incorporated links to a standard controller action, you’d probably want to take advantage of the existing createLink tag.

Let’s apply that thinking to a new custom tag so you can see this reuse in action. Take the example of generating URLs for those tiny follower images. As you saw in the last section, we’re currently doing this in HTML with dynamic URL construction:

<img src="
<g:createLink action="tiny" controller="image"
id="${followUser.userId}"/>
" alt="${followUser.userId}"/>

It would be much nicer to be able to hide that all in a custom tinyThumbnail tag, like this:

<h:tinyThumbnail userId="${followUser.userId}"/>

When we implement our tinyThumbnail tag, we want to be able to reuse the functionality built into the standard g:createLink tag. And we can! Here’s our custom implementation:

As we saw earlier, you can invoke an existing tag using method-style invocation. The namespace must be used as the object of the method call (“g” for the standard taglibs, as shown previously).

Now that you’ve learned how to create your own custom tags, the next step is to learn how to improve application layouts.

6.3. Adding delicious layouts

We’ve spent plenty of time implementing functionality for Hubbub, but we’ve spent none on its appearance. Grails doesn’t just make implementing features fast, it also enables you to make your application look and feel good. At the heart of look-and-feel matters is Grails’ support for layouts.

We’ve been using templates since chapter 4 (and we even touched on them in chapter 1), but we never explained how they work. All of the heavy lifting for layout functionality in Grails is done via a popular Java layout library called SiteMesh (http://www.opensymphony.com/sitemesh/). You may not have been exposed to SiteMesh before, so let’s take a look at it.

6.3.1. Introducing SiteMesh

SiteMesh operates as a page decorator. You render plain HTML for your page, and it is passed through a SiteMesh decorator (to add the header, footer, sidebars, and so on), and the final merged page is rendered to the browser. You might like to think of it as shown in figure 6.3.

Figure 6.3. SiteMesh in operation merging pages

One of the most powerful and sophisticated features of SiteMesh is merging elements from your target page into your decorator. This will make more sense with an example, so let’s explore how SiteMesh is used to implement Hubbub’s common look and feel.

Exploring the Merging Process

Let’s review our template from chapter 4—a simple layout that adds a title field and a basic footer. We placed our layouts in /grails-app/views/layouts, but because we want our template to apply to our scaffolding code too, we edited the standard template, called /grails-app/views/layouts/main.gsp. Listing 6.6 reproduces that template.

Listing 6.6. A basic custom template for Hubbub

We start by laying out the title. We prefix all title elements with “Hubbub >>”, followed by the title value from the target page . If the target page doesn’t have a custom <title> element, we display “Welcome”. This gives us a convenient way of changing all our titles in one place.

We use the SiteMesh <g:layoutHead> tag to merge any content from our target page’s <head> element, and the <g:layoutBody> tag to merge in the contents of our target page’s <body> element.

Once all those tags fire, our target view page will be merged with our layout template to give us a consistent layout throughout the application. This approach to markup offers a double win. Your content pages become simple and uncluttered, and your layout pages make it easy to change the look and feel of your application with a single edit.


Displaying application versions in footers

The <g:meta> tag gives you access to all the entries in your Grails application.properties file in the root directory of your project. It’s often convenient to display the version of your application in the footer, for reporting issues against, and to confirm that a new version has deployed successfully. You might display your current application and Grails version in a footer using code like this:

Version <g:meta name="app.version"/>
on Grails <g:meta name="app.grails.version"/>

You can change the version of your application at any time by using the grails set-version command from the command line, or by editing the application.properties file directly. The version number of your application affects the naming of your target WAR file, so it can be handy to bump the number with each deployed version, so you can keep old copies of WAR artifacts around for an immediate rollback if things go bad. (This isn’t a substitute for version control, but it’s a cheap rollback option nonetheless.)


Applying Layouts by Convention

In chapter 1, we introduced you to a simple way of applying layouts by convention. It’s time to review the options and dig deeper into some applications of them.

For example, if we were dealing with the Post controller, we could control its decoration with the techniques listed in table 6.5.

Table 6.5. Conventions for applying layout templates

Apply template to ...

Example of convention or technique

All actions in a controller

Create layout in /layouts/post.gsp

A specific action in a controller

Create layout in /layouts/post/list.gsp

A portion of a target page

Include tag in target page:

<g:applyLayout name="postFragment">Hi</
g:applyLayout>

Override any conventions explicitly for a single page

Include tag in target page:

<meta name="layout" content="vanilla"/>

Using conventions eliminates the need to specify the <meta> tag and makes your application more maintainable at the same time. When we open a GSP file and don’t see any meta magic, we know exactly where to look for a decorator (/views/layouts/<controllerName>), which makes maintenance a lot more straightforward.

While we’re on the subject of real-world approaches to page layouts, it’s time to explore other ways to make them simpler.

6.3.2. Standardizing page layouts

If you’ve done any work laying out multicolumn web applications, you already know how complex a standard CSS layout can be. Some browsers won’t float the divs correctly to give you the right gutter, it’s hard to get some sections of your page to grow while others stay static, there are all sorts of font-size issues, and the page never looks good in Internet Explorer.

You need to address all of these issues in your application layouts, and it’s time we showed you the best way to go about it. First, let’s sketch out how we want Hubbub to look. Figure 6.4 shows a rough sketch for the app.

Figure 6.4. A mockup of our Hubbub UI

As you can see, we’ve got a top header followed by a tabbed area with a right sidebar, followed by a full-width footer. If you were coding this by hand, you’d be in for a shock. These kind of CSS layouts involve a massive amount of work and are very difficult to keep consistent across browsers. In Grails, the smartest way to handle CSS layouts is with YUI Grids.

YUI Grids gives you a simple CSS-based mechanism for fine-grained control of browser layouts. It’s a 4 KB CSS file that you can add to your application and that will solve your cross-browser layout dramas for good.

You can download the CSS file and view comprehensive documentation from the YUI Grids page (http://developer.yahoo.com/yui/grids/), where you’ll also find the YUI Grids Builder. You can even use the online builder to generate your basic template layout for you. Figure 6.5 shows a sample of the YUI Grids Builder in action, building our layout from the sketch above.

Figure 6.5. The YUI Grids Builder makes cross-browser CSS layouts easy.

Once you’ve got the layout you want, click the Show Code button and you’ll be presented with your template ready to customize. Listing 6.7 shows the YUI code generated from the layout in figure 6.5.

Listing 6.7. The YUI-generated code
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>YUI Base Page</title>
<link rel="stylesheet"
href="http://yui.yahooapis.com/2.5.1/build/reset-fonts-grids/reset-fonts-grids.css" type="text/css">
</head>
<body>
<div id="doc3" class="yui-t4">
<div id="hd"><h1>Hubbub Logo</h1></div>
<div id="bd">
<div id="yui-main">
<div class="yui-b"><div class="yui-g">
<!-- YOUR DATA GOES HERE -->
</div>
</div>
</div>
<div class="yui-b"><!-- YOUR NAVIGATION GOES HERE --></div>

</div>
<div id="ft">Hubbub - Social Networking on Grails</div>
</div>
</body>
</html>

With a few tagged YUI divs, we have a cross-browser, safely degrading CSS layout that will look the same on any browser. All we need to do now is incorporate our <g:layout> tags to merge in the head and body, and add some CSS styling to give us a better idea of what it might look like.

You’ll notice that there are some portions of our layout that we’ll want to reuse in several places. For example, our sidebar on the right should display for several of the tabs, and it might be useful elsewhere in the app as well. Rather than encode that stuff directly in the layout, we can take advantage of Grails templates.

6.3.3. Fragment layouts with templates

When you want to reuse portions of your application layout throughout your application, you have a candidate for a template. Templates encapsulate fragments of GSP functionality and can be incorporated in your pages using the <g:render> tag.

Take the example of the static login fragment shown in listing 6.8.

Listing 6.8. A sidebar fragment to include
<div id="sidebar">

<h3>Login</h3>
<div id="loginForm">
<g:form controller="login">

<ul>
<li>User Id: <g:textField name="userId" size="12"/></li>
<li>Password:
<g:passwordField name="password" size="12"/>
</li>
<li><g:submitButton name="login" value="Login"/></li>
</ul>

</g:form>
</div>

</div>

There may be several pages in your application that require this small piece of content. If you save the fragment in /views/_sidebar.gsp (note the underscore), you can reference it in your GSP pages or layouts with this tag:

<g:render template="/sidebar"/>

Better still, the templates themselves can contain model references that you can pass by using the model attribute:

<g:render template="/sidebar" model="[defaultUser: 'name-here']"/>

This makes templates great self-contained pieces of view functionality. You can even use templates in controllers when rendering Ajax fragments—we’ll get into that in section 6.4.

With our standard layouts now in place, it’s time to let the user choose their own look and feel for Hubbub. This is called skinning, and Grails makes it easy to implement.

6.3.4. Adding skinning

Hubbub looks great with its standard blue and grey design. But social-networking sites generally let users skin their own timelines. Let’s add skinning to Hubbub.

First, we’ll need a way to select a preferred skin, and for that we’ll need to add a new optional field to the Profile object:


Note

You’ll want to update the profile-editing screens to support the new skin types, but we’ll leave that as an exercise for you (or you can grab the example source from github).


With the skin in place, we need to customize the user’s timeline page to take advantage of it. If the user has a skin for their timeline, we’ll apply it using CSS. Listing 6.9 shows an extract of the updated timeline.gsp file.

Listing 6.9. Applying a skin via CSS

The updated timeline checks to see if the user has a skin configured, and, if so, it adds a link to the appropriate stylesheet from the CSS directory. The CSS skin files work by overriding the background colors of body elements and heading styles. For skinning to work well, it’s important that you make good use of CSS classes and IDs to mark up your view pages.

Figure 6.6 shows our “nighttime” skin in action. If you need to support skinning site-wide rather than for individual pages, you’re better off making use of filters, which we introduced in chapter 5. Set up your skin name in a filter and pass it using a session-scoped variable. Then configure the CSS skin in your main layout page, and you’re set.

Figure 6.6. The nighttime theme in action

6.3.5. Implementing navigation tabs

With the skinning in place, it’s time to turn our attention to navigation. Which UI elements will we provide to allow the user to navigate around the application? The most recognizable option is to display a series of navigation tabs at the top of the page.

In the early days of Grails, all of this tab-style navigation was done by hand. Typically you would write a tag to generate menu items, and do the hard work of highlighting the appropriate tab based on the current controller action. Things got messy quickly.

But since Marc Palmer’s Navigation plugin came on the scene, generating navigation tabs has become straightforward. We’re going to cover third-party plugins in depth in chapter 8, but for now we’ll walk you through the basics of installing and using the Navigation plugin.

To install the Navigation plugin, change to the root directory of your project and run the following command:

grails install-plugin navigation

Grails will inform you that it’s downloading the plugin and installing it into your application.

Once the plugin is installed, you can mark your controller classes with a new navigation property and tell the plugin which actions from your controller to display in your menu. We want to generate a menu for Hubbub that looks something like figure 6.7.

Figure 6.7. Our planned navigation menu

Although that looks like a lot of work, the Navigation plugin makes generating the menu straightforward. Listing 6.10 shows extracts of the updated UserController and PostController with new navigation blocks that specify what to include in the menu.

Listing 6.10. Defining menu options in your controller
class PostController {

static navigation = [
[group:'tabs', action:'timeline', title: 'My Timeline', order: 0],
[action: 'global', title: 'Global Timeline', order: 1]
]
// ... other code omitted
}

class UserController {

static navigation = [
[group:'tabs', action:'search', order: 90],
[action: 'advSearch', title: 'Advanced Search', order: 95],
[action: 'register', order: 99, isVisible: { true }]
]
// ... other code omitted
}

For each navigation block, you provide a series of maps, each representing one item in the menu. In each map, you provide the action that should fire when the menu is clicked, along with an optional title. If you don’t specify a title, the plugin will use a nicely formatted name of the action (register becomes “Register” and advSearch would default to “Adv Search”).

You can use the order property to control where in the menu your items are positioned. (In the future, third-party plugins might make use of this field to include their own items in your menus automatically.) You can even supply an isVisible property that will be tested when the menu is rendered. For example, you might control the register menu to only show if the user isn’t logged in.

Now that our menu blocks are all defined, we have to make two entries in our template to display the menu. In the head element of our main layout, we’ll add a <nav:resources/> element:

<head>
<nav:resources/>
</head>

This will incorporate the menu CSS elements. (You can override them all with your own styling, but the defaults look great.)

In the body of our layout, we’ll position the menu in the page with a <nav:render/> tag specifying the group attribute that appeared in our navigation block:

<div id="bd"><!-- start body -->
<nav:render group="tabs"/>
<g:layoutBody/>
</div>

With those two changes, our menu is ready to roll. Figure 6.8 shows the new menu in operation.

Figure 6.8. The Navigation plugin painlessly handles all your menu needs.

With our menu looking slick, it’s time to explore some other ways to raise our UI to the next level. One obvious way is to use Ajax to update the user’s timeline in-place when they add a new post. But before we get started, you need to learn a little about how Grails integrates Ajax.

6.4. Applying Ajax tags

We’ve done a lot of UI work so far, but we’ve saved the best for last. In this section, we’ll use Ajax to take the Hubbub UI experience to a whole new level. We’ll get a taste for dynamically changing our Hubbub page in-place using remote calls to backend code. Then we’ll create some visual sizzle with JavaScript animation and effects.

But first we need to lay the foundation by choosing a JavaScript library to do the heavy lifting for us.

6.4.1. Choosing a JavaScript library

Grails implements all of its built-in Ajax functionality through adaptive tag libraries. That means that all of the standard Ajax tags can be backed by whatever JavaScript library you prefer and still expose the same API to the client and server. Prototype is supported out of the box, and Dojo, YUI, and jQuery are supported using plugins. That means you’re free to start with one library, and change to a different one as your application fills out.

Not all JavaScript libraries play nicely together, so if some of your GSPs use a particular library, it makes sense to use that for your Ajax implementation too. For instance, if you’re planning on doing any animation effects with Scriptaculous, it makes sense to choose Prototype (because that’s what Scriptaculous uses under the hood). If you’re planning on using YUI autocomplete, you might as well use YUI for your Ajax remoting too (because you’ve already burned the page-load time bootstrapping the YUI infrastructure).

Prototype seems to be the most widely used by Grails developers (though jQuery is starting to develop a big following for its unobtrusiveness and great effects library), so we’ll use Prototype for our examples.

6.4.2. Essential Ajax form remoting

It’s time to get to work on our user’s timeline action to apply a little Ajax style. We’ll restyle our posting form to submit post contents using Ajax, then update our timeline with the latest entries.

The first step in using an Ajax call is importing your preferred library. We’ll start by updating our timeline.gsp head element to tell Grails that we want to use Prototype as our remoting library. Using the library attribute of the javascript tag generates HTML tags for the multiple source JavaScript files that comprise the specified library:

<head>
<title>Timeline for ${user.profile.fullName}</title>
<meta name="layout" content="main"/>
<g:javascript library="prototype"/>
</head>

With our library selected, we can now update the posting form to submit the Post contents remotely. Grails provides the <g:submitToRemote> tag to bundle up the contents of a form and send it via Ajax to a backend service. Listing 6.11 shows the updated form definition.

Listing 6.11. Adding a new Post via Ajax

The <g:form> and <g:textField> tags remain unchanged. Only a <g:submitToRemote> tag has been introduced . Its only required attribute is url, which is a map with controller and action values . We’ll add a new addPostAjax() action in the PostController to handle the new submission.

If the update attribute is specified , it should be the id of the div to be updated when the call is complete. In our case, the addPostAjax() call will return the updated HTML for the timeline, which is in a div with id allPosts.

If the onSuccess attribute is specified , it should contain the JavaScript function that should be called once the form submission has finished successfully (no backend 404s or other errors). Whatever function you supply to onSuccess should take an argument (e) that is the XMLHTTPResponse that represents the backend call. In our case, we use clearPost to clear the textArea when the user has successfully posted the new item.

Finally, onLoading and onComplete are called before and after the Ajax call, which we take advantage of to show and hide an animated spinner image .

If you’re curious about those clearPost and showSpinner JavaScript calls, there’s no magic in them—just a few lines of Prototype to keep the UI responsive. It’s always good to show and hide an image when doing Ajax calls, so the user knows that something is happening. Listing 6.12 shows the JavaScript we’re using to keep the user up to date.

Listing 6.12. Keeping the user updated with JavaScript
<g:javascript>
function clearPost(e) {
$('postContent').value='';
}
function showSpinner(visible) {
$('spinner').style.display = visible ? "inline" : "none";
}
</g:javascript>

With our client interface implemented, we need to implement the addPostAjax() action in PostController. Listing 6.13 shows the backend code we’ll need.

Listing 6.13. Implementing the addPostAjax() backend

Because we did the hard work of abstracting the PostService in chapter 5, we can reuse it for our Ajax implementation here . After we create our new Post, we retrieve the latest posts to send back to the timeline . Then it’s a matter of reusing the postentries template we developed earlier and passing it our collection of recent posts . This will send the HTML of the timeline body back to the client for updating the allPosts div.

If an error happens in the process, we’ll use the markup builder (discussed in chapter 2, section 2.4.4) version of render to send back a div with the error message (styled as an error, so the big pink warning box is displayed).

Figure 6.9 shows our Ajax timeline in progress with our stylish Ajax spinner giving the user feedback to indicate that things are underway.

Figure 6.9. Our Ajax spinner in action

The submitToRemote tag we used in listing 6.11 has other options that we haven’t explored yet, including the ability to handle server response codes such as on404 and other event options. It can also handle JSON return values, and we’ll use this later in the chapter. For full coverage of its capabilities, check out the Grails online docs at http://grails.org/doc/1.1.x/.

With our basic Ajax functionality in place, it’s time to explore how we can use animation libraries to make the whole app more visually stunning.

6.4.3. Sizzle++: going further with animation and effects

We’ve already given Hubbub quite a makeover in this chapter, but it’s time to go the whole nine yards and add some animation effects for true Web 2.0 sizzle. If the last time you used JavaScript effect libraries was doing marquees in the late ’90s, there’s good news: things have come a long way.

Through libraries like Scriptaculous, YUI, and jQuery, visually stunning and cross-browser JavaScript has become a reality. A whole new level of engineering has created reusable libraries that degrade gracefully and integrate unobtrusively into your application.

We’ll be using Scriptaculous for our visual effects. It comes with Grails, so there’s nothing to install, and you can get straight to business. It also has lots of effects that can usually be implemented as one-liners.

Introducing Scriptaculous

Scriptaculous is a JavaScript library for adding impressive visual effects to your application. Fading, appearing, flashing, resizing, and animating are all common UI interactions that Scriptaculous offers.

If you’ve never used a JavaScript animation library before, you might be intimidated by the thought of complex animation coding. Be comforted: Scriptaculous provides good defaults for an incredible amount of behavior, making everything look great, even for the artistically challenged.

The first step in using the library is to include it in your page header:

<head>
<title>Timeline for ${session.user.userId}</title>
<g:javascript library="scriptaculous" />
</head>

Because Scriptaculous already includes Prototype, there’s no need to import both.

With the library imported, using animation effects is a simple matter of invoking one of the numerous Scriptaculous Effect methods (for example, Effect.Fade ('myDiv')). Let’s take it for a test drive by adding aTinyURL bar to Hubbub.

Slick Fades on Tinyurls

If you’ve ever used Twitter, you’ll notice that any URLs you place in your messages are automatically compressed via URL shrinking sites like TinyURL.com. Because URLs can get quite long, this URL-shrinking process helps keep posts that incorporate URLs under the 140-character limit that Twitter imposes. It’s high time we added a TinyURL feature to Hubbub. And while we’re at it, we’ll add some JavaScript effect know-how to make it look slick.

We want to make it easy for users to add URLs to their posts, so we’ll add a TinyURL entry box to the posting form. But users don’t need a TinyURL entry box onscreen all the time—just when they want to include a URL in their post. So let’s make a div to hold the TinyURL entry form, but have it fade in and dissolve out as required.

First, we’ll make the div invisible by default, using a display: none; CSS tag:

<div id="tinyUrl" style="display:none;">
<g:form>
TinyUrl: <g:textField name="fullUrl"/>
<g:submitToRemote action="tinyurl" onSuccess="addTinyUrl(e)"
value="Make Tiny"/>
</g:form>
</div>

Then we’ll add a JavaScript link on our form to fade the div in and out as required. A simple link next to the Post button will be fine:

<a href="#" id="showHideUrl" onClick="return toggleTinyUrl()">
Show TinyURL
</a>

Then we need a little JavaScript to implement the appearing and dissolving:

<g:javascript>

function toggleTinyUrl() {
var tinyUrlDisplay = $('tinyUrl').style.display;
var toggleText = $('showHideUrl'),
if (tinyUrlDisplay == 'none' ) {
new Effect.BlindDown('tinyUrl', { duration: 0.5 });
toggleText.innerText = 'Hide TinyURL';
} else {
new Effect.BlindUp('tinyUrl', { duration: 0.5 });
toggleText.innerText = 'Show TinyURL';
}
}
</g:javascript>

The Scriptaculous calls are one-liners, Effect.BlindDown() and Effect.BlindUp(), passing the div id of our TinyURL form. This effect pair causes the TinyURL bar to smoothly appear and disappear from the top down.

You can also customize the time it takes for the effects to complete. We like to keep effects fairly quick to ensure they don’t distract from the workflow. For example, we tuned the BlindDown() to take half the default time like this:

new Effect.BlindDown('tinyUrl', { duration: 0.5 })

Consult the Scriptaculous documentation (http://script.aculo.us/) for the details of the effect parameters. There’s also a fantastic showcase page that gives you a chance to play with each of the available effects and see what they look like in a browser (http://wiki.github.com/madrobby/scriptaculous/combination-effects-demo).

Scriptaculous has shortcuts for most of the common UI features you’ll want to animate. For example, now that you know how effects work, let’s refactor our example with a one-liner:

<a href="#" id="showHideUrl"
onclick="Effect.toggle('tinyUrl', 'blind', { duration: 0.5 }); return false;">
TinyURL Bar
</a>

Effect.toggle() does all of the appear and fade work we implemented in our custom JavaScript, and it even gives you a variety of mechanisms for toggling (slide, blind, appear). Notice that we explicitly return false from onclick to ensure the browser doesn’t follow the “#” link.

Handling Json Return Values

It’s all very well to have ourTinyURL bar fading in and out, but what about when the user wants to use it? We’d like them to be able to enter a URL, click the Make Tiny button, and have the post field automatically append the tiny URL to the current post textArea.

To implement that, we’re going to need a way to do the following:

1.  

Bundle up the current full URL from the text field and send it to the backend via Ajax.

2.  

Calculate theTinyURL in some backend controller action, and return the value.

3.  

Catch the return value in our view, and append it to the textArea of the post.

The easiest way to implement the first step is by defining a submitToRemote button. This will bundle up the form values and submit them to a backend controller using Ajax. Here’s what it would look like in our /views/posts/list.gsp file:

<g:form>
TinyUrl: <g:textField name="fullUrl"/>
<g:submitToRemote action="tinyurl"
onSuccess="addTinyUrl(e)" value="Make Tiny"/>
</g:form>

The <g:submitToRemote> tag will invoke the tinyurl() action on the PostController, passing it a params object with all the form fields in it. In our case, we only have one parameter (fullUrl), which we have to shrink. When the remote call completes, the onSuccess attribute contains the JavaScript function to be called on success.

The gee-whiz aspect is that the onSuccess target gets passed the result of the remote action. If our action returns text, xml, or JSON, we can use it in our client-side JavaScript function.

Let’s now implement our controller—listing 6.14 shows our TinyURL implementation. We take the fullUrl the user passes in, and hand it off to the TinyURL website for shrinking.

Listing 6.14. A TinyURL action to shrink URLs via JSON
def tinyurl = {
def origUrl = params.fullUrl?.encodeAsURL()
def tinyUrl =
new URL("http://tinyurl.com/api-create.php?url=${origUrl}").text
render(contentType:"application/json") {
urls(small: tinyUrl, full: params.fullUrl)
}
}

A Groovy enhancement to the URL class lets you access the contents of a URL by calling on the text property. In listing 6.14, we call the TinyURL endpoint, which returns a compressed version of the incoming ${origUrl} value. Once we have the compressed URL, we take advantage of the versatile render() method to return a small piece of JSON. The returned JSON will contain properties for both large and small versions of the URL. We’re only interested in the small version for display, but we wanted to demonstrate how to return multiple values.

Let’s complete the picture by implementing the client-side JavaScript to process the returned JSON in our addTinyUrl(e) callback. Listing 6.15 shows the JavaScript for our handler.

Listing 6.15. Implementing a callback to handle the JSON return values
<g:javascript>

function addTinyUrl(e) {
var tinyUrl = e.responseJSON.urls.small;
$("postContent").value += tinyUrl;
updateCounter();
toggleTinyUrl();
}

</g:javascript>

When the backend returns a content type of application/JSON, Prototype automatically evals() the return value into a native JavaScript object. From there, we can access the small property value we returned from our controller in listing 6.14 to display our tiny URL. Figure 6.10 shows the new feature in operation.

Figure 6.10. Our TinyURL feature in action

We’ve now got a good handle on Scriptaculous eye candy, and we’ve even combined it with some funky backend Ajax and JSON magic.

That completes our tour of Grails’ Ajax functionality. We’ve covered an incredible amount about Grails UI features in this chapter, so let’s wrap up.

6.5. Summary and best practices

We started this chapter by touring the basic Grails form tags and learned about more form tags than you’ll probably ever need to use in one application. We also looked at how to develop our own custom tags for situations where the standard tags don’t provide enough flexibility.

We then toured all the different options Grails gives you for layouts and templates, and we even implemented our own skins and navigation menus.

Finally, we explored some advanced Grails Ajax concepts, implementing a dynamic timeline and aTinyURL codec that uses JSON to communicate with backend services. Along the way, we picked up some JavaScript animation skills to make it all sizzle.

We learned a lot and developed a few best practices:

  • Apply pagination. Paginating large datasets creates a much better user experience and it’s easy to implement.
  • Develop custom tags. Take the time to develop reusable tag components for common parts of your UI. It will save you time, simplify maintenance, and enable you to reuse them in future projects.
  • Use convention-based layout. Favor convention-based layouts over explicit meta tags. Often a specific layout for one particular action can make things much more maintainable than doing meta-magic branching. Take advantage of meta tag styles when you need to style a subset of pages for a controller, but use convention layouts for the rest.
  • Layout smarter. Handle basic flash message display in your layout rather than repeating it for each view. Use templates for common HTML fragments, passing in explicit model elements. Inside Ajax calls, resist the urge to render HTML directly, and do any rendering via a template call.
  • Pick a JavaScript library. Gain an appreciation of the strengths and weaknesses of the various JavaScript libraries. They all have different approaches and are worth exploring. Choose an Ajax library that makes sense for the rest of your app. It takes time to download libraries, so minimize the number of libraries in play.
  • Use a layout library. When developing complex CSS layouts, use YUI Grids. It will save you time and look great on all browsers.

We’ve now learned a lot of core Grails concepts, but there’s one important area that we really haven’t given much consideration to: testing. In the next chapter, we’ll dive deep into Grails support for testing controllers, validators, taglibs, and more.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset