CHAPTER 5

Understanding Views

View technologies for web applications in the open source world appear to be a rather popular topic with the seemingly endless number of them available for Java. There always appears to be a newer, better one to learn if you grow tired of the incumbent JSP. JSP, however, remains the most popular view technology; produced by Sun to compete with Microsoft's Active Server Pages (ASP), JSP has become the industry standard, and there is a high level of developer knowledge surrounding JSP.

JSP allows developers to mix traditional markup languages such as HTML with Java code (called scriptlets) to produce dynamic output. On the downside, this facility is extremely open to abuse; therefore, there are custom tag libraries that add the ability to abstract logic from a JSP page via tags. JSP has been augmented with two missing ingredients, the JSP Standard Tag Library (JSTL) and an expression language (EL), to bring it up to speed with some of its open source competitors.

So, given JSP's maturity, robustness, and familiarity within the industry, why on Earth would you need yet another view technology for Grails with Groovy Server Pages (GSP)? The answer lies with the Groovy runtime environment:

  • To fully take advantage of Grails, the view technology requires knowledge of Groovy's runtime environment and associated dynamic method dispatching.
  • Groovy provides a far more powerful expression language, including GPath expressions, Groovy bean notation, and overridable operators.
  • Other Groovy features such as regular expression support, GStrings, and an expressive syntax for maps and lists make it perfect for a view technology.

Of course, for any new view technology, it is important not to fall into the same traps that JSP fell into in its early iterations. Mixing scriptlets and markup code is most definitely recognized as a bad thing, and to this end, GSP provides a mechanism for creating custom tags just as JSP does but without sacrificing any agility.

The Basics

You've already been exposed to GSP at various points throughout the book, and we're sure you are verging on the expert level already. Regardless, it will no doubt prove invaluable to discuss the basics of GSP to help you fully grasp all the concepts within it.

It is important to note that GSP is actually remarkably similar to JSP, and you will know from experience that with JSP, by default, a number of objects are simply available. These include the request, response, and session objects—the same ones you saw in Chapter 4, which discussed controllers. If you recall, that particular discussion mentioned that a few additional objects are available to controllers, including the flash object. Well, you'll be pleased to know these can also be accessed from GSP views, as can an additional out attribute, which is a java.io.Writer instance representing the response output. Table 5-1 describes the GSP attributes available.

Table 5-1. GSP Attributes

Attribute Description
application The ServletContext instance
flash The flash object for working with flash scope, as discussed in Chapter 7
out The response Writer instance
params A map of request parameters
request The HttpServletRequest instance
response The HttpServletResponse instance
session The HttpSession instance

You already know how to get to these from controllers, but what about in views? Well, unsurprisingly, GSP supports the same constructs available in JSP as well as a few additional ones. This may start to look a little like a JSP 101 tutorial in the next few examples, but don't be confused; you're definitely dealing with Groovy, not Java.

Understanding the Model

One of the fundamental activities in any MVC pattern, such as that which Grails employs, is to pass information (the model) to the view for rendering. In Chapter 4 you saw this in action, but just to recap, Listing 5-1 shows an example of how you can achieve this in Grails.

Listing 5-1. Creating the Model

package com.g2one.gtunes

class StoreController {

    def shop = {
        def genreList = Album.withCriteria {
            projections {
                distinct "genre"
            }
        }
        [genres:genreList.sort()]
    }
}

In the previous listing (the shop action of the StoreController), the result is a map with one element, the key for which is a string with the value genres. This key (and its value) is then placed in a GSP's model (or binding for those more familiar with Groovy lingo), which means it is accessible as a variable in the same way as the page attributes you saw earlier in Table 5-1.

In the following sections, you will see examples of a genres variable being referenced. Just remember that this variable didn't appear by magic. It is passed to the view via the controller in code like in the previous listing.

Page Directives

GSP supports a limited subset of the page directives available in JSP. A page directive is an instruction that appears at the top of a GSP that performs an action that the page relies on. As an example, it could set the content type, perform an import, or set a page property, which could even be container-specific.

One of the more useful of these is the contentType directive, which allows you to set the content type of the response. This is useful in that it allows you to use GSP to output formats other than HTML markup, such as XML or plain text. Using the directive is identical to JSP, with the directive appearing at the top of the page and starting with <%@.

Listing 5-2 sets the content type to text/xml, which allows you to output XML; this can be useful when working with technologies such as Ajax.

Listing 5-2. The contentType Page Directive

<%@ page contentType="text/xml; charset=UTF-8" %>

Another page directive available is the import directive, which is analogous to the import statement in a Java or Groovy class. However, because Groovy imports many classes by default and Grails encourages an MVC architecture, where much of the logic should be placed in a controller and not the view, the usage of import is not too common. Nevertheless, Listing 5-3 shows an example of importing the Time class from the java.sql.* package.

Listing 5-3. The import Page Directive

<%@ page import="java.sql.Time" %>

Note Groovy imports the java.lang, java.util, java.io, java.net, groovy.lang, and groovy.util packages by default.


Groovy Scriptlets

GSP tries to stay as true to JSP as possible, and therefore it supports traditional JSP scriptlet blocks using the <%...%> syntax. Essentially, as soon as you type the opening <% declaration, you have entered the world of Groovy and can type whatever Groovy code you so choose up until the closing %> declaration.

What this means is that you can use scriptlets to perform loops and logical if statements merely by combining scriptlet declarations, as shown in Listing 5-4.

Listing 5-4. Scriptlets in Action

<html>
      <body>
      <% 3.times { %>
          <p>I'm printed three times!</p>
     <% } %>
      </body>
</html>

This type of syntax will be familiar to users of Rails, because it bears a striking resemblance to Rails' view technology RHTML (and indeed many other view technologies). However, you should note that scriptlets are available more to align the syntax with JSP and, in practice, are discouraged in favor of GSP tags, which you will see in the section "Built-in Grails Tags."

Although the previous syntax allows arbitrary code to be inserted between the opening and closing declarations, it doesn't actually explicitly output anything when inside the scriptlet block. In other words, as with the previous example, you have to use a closing %> bracket to close the scriptlet expression in order to define what you want repeated three times. You can, however, use the out attribute mentioned earlier to output to the response:

<% out << "print me!" %>

The previous code will print the text "print me!" to the response using the out attribute. As you can imagine, having all these out << statements all over the place can get a little tedious, so GSP supports another syntax inherited from JSP through the <%=...%> statement (note the equal sign directly after the opening declaration). Essentially, the following example is equivalent to what you saw in the previous code:

<%= "print me!" %>

Here the = sign after the opening scriptlet bracket ensures that the result of whatever follows is printed to the response. The response in general is a mix of markup and code that results in some text being sent to the browser or client. Now that you've seen GSP's similarities with JSP, let's look at a feature you won't find in JSP: embedded GStrings.

GSP as GStrings

In recent times, since the introduction of JSTL, using scriptlets and declarations such as those shown in the previous section has been looked down on a bit. Instead, there is an expression language in JSP that you can use in combination with the <c:out> standard tag to output values, as shown in Listing 5-5.

Listing 5-5. JSP c:out Tag

<%-- Output the album title --%>
<p><c:out value="${album.title}" /></p>

Tip The previous JSP example uses the syntax <%--...--%> for comments that should not be present in the rendered response. These comments are also supported in GSP using the same syntax.


In addition to the previous rather verbose tag, you would also need to import the tag library, which contains the <c:out> tag using a page directive at the top of the JSP. All this amounts to a lot of effort just to use a tag that lets you render values to the response. Luckily, with GSP it is a little bit simpler, because of its support for embedded GString values:

<p>${album.title}</p>

A GSP, if you think about it, is essentially one big GString, thus allowing the same ${...} expressions nested within it as found in JSP. The expressions allowed within the GStrings are not, thankfully, limited to simply referencing properties. The full capability Groovy offers in terms of navigating object graphs is at your fingertips, which often becomes useful when iterating, as you will see in the next section.

Built-in Grails Tags

GSP has a number of built-in tags for performing basic operations such as looping, switching, and using logical if statements. In general, tags are preferable to embedding scriptlets because they promote a cleaner separation of concerns and allow you to create well-formed markup.

Each GSP tag requires the prefix g: before the tag name so that it is recognized as being a GSP tag. Unlike JSP, which requires directives to import tag libraries, no additional page directive is needed.


Note GSP also supports JSP custom tag libraries that can be imported with the standard JSP taglib directive.


In the next few sections, you'll see the tags that are built in to Grails. These tags are there by default and require no extra work by the developer.

Setting Variables with Tags

Occasionally, it is useful to set the value of a variable or define a new variable within the scope (commonly referred to as the page context) of a GSP. Both use cases can be achieved via the <g:set> tag, which will set or define a variable in the page context regardless of whether it already exists. The <g:set> tag takes two attributes: the var attribute, which defines the name of the variable to set, and a value attribute, which is generally an expression:

<g:set var="albumTitle" value="${album.title}" />

By default, variables set with <g:set> are assumed to be within the page scope. Having said that, you can set a variable in the session scope simply by using the scope attribute:

<g:set scope="session" var="user" value="${user}" />

In addition to the session scope, a number of other scopes are available:

  • application: Stores variables for the scope of the whole application
  • session: Stores variables for the scope of the user session
  • flash: Stores variables for the current request and the next request only
  • request: Stores variables for the scope of the current request
  • page: Stores variables for the scope of the rendering page

Another fairly basic requirement, along with setting variables, is the ability to conditionally display information. In the next section, you'll see how you can achieve this.

Logical Tags

As previously mentioned, it is often useful to display information based on a condition. At the most basic level, it is useful to have basic programming constructs in the view such as if and else to facilitate this. GSP has the aptly named <g:if>, <g:elseif>, and <g:else> tags that, as with any regular programming construct, are used in conjunction with one another to conditionally display output.

The <g:if> and <g:elseif> tags take an attribute called test whose value can be in expression language (that is, statements surrounded by ${..}), as shown in Listing 5-6.

Listing 5-6. Usage of Logical Blocks

<g:if test="${album?.year < 1980 && album?.genre == 'Rock'}">
       Classic rock
</g:if>
<g:elseif test="${album?.year >= 1980 && album?.genre == 'Rock'}">
       Modern Rock
</g:elseif>
<g:else>
       Other
</g:else>

An interesting aspect of the previous code is the usage of Groovy's safe dereference operator, ?.. The operator really comes into its own when used in views, because it is often useful to navigate an object graph and display information only if all elements navigated through don't evaluate to null. If you look at the views generated during scaffolding, you will observe a lot of this in action. Yet another useful feature of the method is that it allows the optional execution of methods. For example, you may for some reason want the title of the album in uppercase, in which case you would use an expression like the following:

${album.title.toUpperCase()}

Unfortunately, if either the album or title of the album in the previous code is null, a horrid NullPointerException will be thrown. To circumvent this, the safe dereference operator comes to the rescue:

${album?.title?.toUpperCase()}

Here the toUpperCase method is executed only if it can be reached; otherwise, the entire expression evaluates to null. This is useful because null in GSP results in an empty string being printed to the response.

That's it for now on logical tags, although you will see their usage popping up throughout the book.

Iterative Tags

Iterating over collections of objects is one of the more common tasks when working with any view technology, GSP being no exception. Again, scriptlets could be used to achieve iteration, but why would you? You have GSP tags, which allow for a much cleaner transition between code and markup.

The first tag we'll cover is the <g:each> tag, which is essentially the tag equivalent of the Groovy each method and in fact simply delegates to this method internally, as shown in Listing 5-7.

Listing 5-7. Iterating with <g:each>

<g:each in="${album.songs?}">
    <span class="tag">${it.title}</span>
</g:each>

Tip You can also use the safe dereference operator at the end of expressions as in the previous example, which will not iterate if the songs property is null.


Like its closely related JSTL cousin, the <g:each> tag allows you to optionally specify the name of the object within the current iteration. The name of the object, as with closures, defaults to an argument called it, as shown in Listing 5-7. When using nested tags, however, it is good practice to name the variable being iterated over, which you can do with the var attribute, as shown in Listing 5-8.


Listing 5-8. Iterating with <g:each> and a Named Variable

<g:each var="song" in="${album.songs?}">
    <span class="song">${song.title}</span>
</g:each>

GSP tags are, at their roots, just closures, and in Groovy the variable it refers to the default argument of the innermost closure. If you use the <g:each> tag without declaring a var attribute and try to reference the default it variable within a nested GSP tag, this will result in evaluating it to the current innermost tag and not the surrounding <g:each> tag. By naming the variable used by <g:each> using the var attribute, you circumvent any conflicts such as this. If you remember that GSP tags are closures, you will have no issue at all adapting to the mind-set.

The next iterative tag GSP provides is the <g:while> tag that behaves like the traditional while loop by waiting for the expression specified within the test attribute to evaluate to false. As with any while loop, the condition should always end up evaluating to false at some point; otherwise, you will end up in a never-ending loop. Listing 5-9 shows an example that loops while the variable i is greater than zero.


Listing 5-9. The <g:while> Tag

<g:set var="i" expr="${album.songs?.size()}" />
<g:while test="${i > 0}">
      <g:set var="i" expr="${i-1}" />
</g:while>

Here you get the total number of songs from the album and store them in the variable i. You then start a <g:while> loop that will decrement the i variable on each iteration. The loop will continue until i reaches zero. The loop is equivalent to the following Groovy code:

while(i > 0) i=i-1

Using <g:each> and <g:while> are not the only way to loop over a collection. In the next section, you'll see constructs that provide the powerful combination of filtering and iteration.

Filtering and Iteration

With some of the new methods that accept closures in Groovy that provide the powerful ability to filter and search collections (such as collect, findAll, and grep), it would seem a shame if that power were not extended into GSP tags. Fear not—there are tag equivalents of these three that allow some pretty powerful filtering capabilities.

The collect Tag

The <g:collect> tag allows you to iterate over and collect properties of objects within a collection. Say, for example, you want the titles of all albums; you can achieve this simply with <g:collect>, as shown in Listing 5-10.

Listing 5-10. Using <g:collect> to Collect Values

<ol>
    <g:collect in="${albums}" expr="${it.title}">
           <li>${it}</li>
    </g:collect>
</ol>

In the previous example, an HTML list of album titles is created by passing a collection of albums to the in attribute via the ${...} syntax. The second attribute, the expr attribute, contains an expression that is used to specify what should be collected (in this case the title property). Again, you use the default it argument within the expression the same way as you would in a closure. In fact, the previous code is equivalent to the scriptlet code in Listing 5-11.

Listing 5-11. Equivalent Scriptlet Using a Closure

<ol>
     <% albums.collect{ it.title }.each { %>
              <li>${it}</li>
     <%}%>
</ol>

As you can see, the expression equates to what is found within the curly braces of the collect closure. Whatever you can place in there can also be placed inside the expr attribute.

Of course, you could also do this with a GPath expression. If you recall what you learned about GPath so far, if you reference the title property and use the dereference operator on a list of albums, it will produce a list of titles, as shown in Listing 5-12.

Listing 5-12. Using GPath to Iterate Over Album Titles

<ol>
    <g:each in="${albums.title}" >
           <li>${it}</li>
    </g:each>
</ol>

The <g:collect> tag does, however, give you another option and allows the logic within the expr attribute to be in your control.

The findAll Tag

Collecting properties from a collection via the object graph is handy, but sometimes you want to iterate over only those values that meet a certain criteria. This is often achieved by iterating over all elements and having nested if statements. However, using <g:findAll>, as shown in Listing 5-13, is far more elegant.

Listing 5-13. Using <g:findAll> to Locate Specific Elements

<g:findAll in="${albums}" expr="${it.songs?.title.contains('Love')}">
      <li>
          ${it.title}
      </li>
</g:findAll>

This is an interesting example because it is another demonstration of the power of GPath, Groovy's expression language. The expression in bold references the default argument it, which is the current Album instance being iterated over, and then uses GPath to retrieve a collection of all the names of the songs.

The songs property itself is in fact a collection too (a java.util.Set to be specific) and does not have a title property, but GPath recognizes that the reference to the title property is an attempt to retrieve a collection of name properties from the contained elements within the songs property.

Since the result is a collection, you can invoke the regular JDK contains method to look up all albums that have the world Love in their title. The result is far more readable than a bunch of nested if statements and is another case where you can see how a Groovy view technology like GSP just makes a remarkable amount of sense.

You've seen quite a few options to perform different kinds of logical statements and iteration. Controlling the logical flow of a view is not, however, the only task you have when writing the view. One common activity is linking between controllers and actions, which you will look at next; but before that, there is something important to note. This marks the end of the builtin tags. The tags you've seen so far are internally handled and optimized by GSP. The next section shifts focus to Grails dynamic tags and how they differ from the built-in tags.

Grails Dynamic Tags

Dynamic tags in Grails are those provided through classes called tag libraries, which can be found within the grails-app/taglib directory of any Grails project. Grails provides a number of tag libraries out of the box that you will see in the next few sections; then you will explore how to create your own tag libraries.

First you need to understand what makes dynamic tags different from other tags besides the fact that they are provided by these libraries. Fundamentally, they can be used the same way as any other tag. For example, you can use the <g:link> tag like the built-in tags you saw previously without requiring any import directive.

More interestingly, dynamic tags can also be invoked as methods from scriptlets and GString expressions. Why is this useful? To maintain a clean syntax and valid XML, it is best to avoid nesting tags within tag attributes. In JSP you often see code like in Listing 5-14 that becomes difficult to read and is not well-formed markup.

Listing 5-14. Unattractive JSP Example

<a href="<c:out value="${application.contextPath}" />/show.jsp">A dynamic link</a>

Clearly, because of GSP's rather JSP-like nature, this problem could have been inherited if it were not for the dynamic nature of Groovy. So, how would you invoke a GSP tag as a method call? Observe the example in Listing 5-15.

Listing 5-15. An Example of a GSP Tag as a Method Call

<!-- With a regular tag -->
<a href="<g:createLink action="list" />">A dynamic link</a>

<!-- As a method call -->
<a href="${createLink(action:'list')}">A dynamic link</a>

The two previous examples produce the same result. They call a tag called createLink, which creates a link to the list action. The second example is notably cleaner and produces well-formed markup. In addition, the body of the tag can be provided as the last argument to the method call.

You can see an example of this in action in the create and edit views generated by scaffolding. As part of form validation, these views highlight the problematic field by surrounding the offender with a red box. You achieve this through the hasErrors tags, which will evaluate if a particular bean field has any validation errors and will set a CSS class, the name of which is the last argument on the surrounding div element if the field does contain errors, as shown in Listing 5-16.

Listing 5-1. Field Validation Example

<div class="${hasErrors(bean:album,field:'title','errors')}">
      ...
</div>

These are just a few examples; as you'll see in a moment, you can create your own tags that can be invoked in the same manner. First, however, let's take a tour through the tags that are already available to you, starting with linking.

Linking Tags

With all these controllers and actions that end up being created, it may become a bit challenging to remember the URL patterns to link to them. Also, the context path of your application could change depending which environment you deploy to. So, how can you make sure you are always linking to the right place in a consistent manner? Well, luckily Grails provides a number of tags to handle linking in an elegant way, the first of which is the aptly named <g:link>.

The Link Tag

The <g:link> tag will essentially create a simple HTML anchor tag based on the supplied attributes, which include the following:

  • controller: The controller name to link to
  • action: The action name to link to
  • id: The identifier to append to the end of the URI
  • params: Any parameters to pass as a map

One of either the controller attribute or the action attribute is required. If the controller attribute is specified but no action attribute is specified, the tag will link to the default action of the controller. If, on the other hand, an action attribute is specified but no controller attribute is specified, the currently executing controller will be linked to.

Beyond the previous attributes, the <g:link> tag also supports all attributes that the regular HTML anchor tag supports, which can be added as required.

It's time for some examples. Using <g:link> is pretty trivial and intuitive, and of course the values of the attributes could just as well be expressions of the ${...} kind if dynamic linking is required, as shown in Listing 5-17.

Listing 5-17. Basic Linking with <g:link>

<g:link controller="album" action="list">List Albums</g:link>
<g:link action="show" id="1">Show album with id 1</g:link>

Of interest may be the params attribute, which takes a map of request parameters to pass via the link. In fact, the current request parameters can even be passed from one action to the other by using this attribute in combination with the params object, which if you recall is an instance of java.util.Map, as shown in Listing 5-18.

Listing 5-18. Using Parameters with <g:link>

<g:link controller="album"
           action="list"
           params="[max:10,order:'title']">Show first ten ordered by Title</g:link>

<g:link action="create"
           params="${params}">Pass parameters from this action to next</g:link>

The first example uses the params attribute in conjunction with a map of parameters and provides your first exposure to another feature of GSP tags: attributes can be specified as maps with the [key:value] syntax. This allows for composite attribute values and minimizes the need for messy nested tags.

Finally, the second example demonstrates what was mentioned previously. Instead of specifying a map explicitly, you provide a reference to the params object via the ${...} expression syntax, which then allows passing parameters from the current page to the linked page. Next you'll see how to create links to other resources.


Note Grails' linking tags automatically rewrite the links based on the URL mappings you have defined. URL mappings will be covered in more detail in Chapter 6.


The createLink and createLinkTo Tags

The <g:createLink> tag has already been seen in action and probably needs less of an introduction. Simply put, if it's not clear from the examples, <g:createLink> takes the same arguments as the <g:link> tag except it produces just the textual link and not an HTML anchor tag. In fact, the <g:link> tag actually delegates to <g:createLink> when creating its href attribute.

So, what is this useful for? You could use it within a regular anchor tag or possibly as a value for a JavaScript variable, as shown in Listing 5-19.

Another tag, similar in both name and usage to <g:createLink>, is the <g:createLinkTo> tag, which allows convenient linking to resources within the web application's context path.

This tag is most commonly used for linking to images and style sheets and again can be seen in action in the views generated by scaffolding:

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

As is apparent from the previous examples and in Listing 5-19, both tags tend to be used via method calls as opposed to markup, because the values produced by them are usually nested within attributes of other tags.

Now that we've covered linking, another common activity is to create forms so that users can enter data to be captured by server-side code. In the following section, you'll see how Grails makes this easier.

Creating Forms and Fields

A form is most commonly a collection of fields that a user populates with data, although occasionally you find forms that consist entirely of hidden fields and no user interaction whatsoever. Nevertheless, how this is achieved depends on the type of field; in other words, the user interacts differently depending on whether it is a text field, a drop-down select, or a radio button.

Clearly, certain fields map nicely onto existing Java (and hence Groovy) types. Check boxes are great for Boolean values, text fields are good for strings, and selects are good when you have strings that can be contained only within a certain list of values (such as enums in Java 5).

To this end, most Java web frameworks provide some mechanism to make form elements (or fields) interoperate smoothly with Java types, Grails being no different. Before you get too deeply involved in looking at the different kinds of fields, let's take care of the basics by looking at how Grails helps in defining forms.

The form Tag

Building on what you have seen in linking, the first tag you are going to look at is the <g:form> tag, which is equivalent to the standard HTML <form> tag, except it allows the same arguments as those shown with the <g:link> tag to allow easy submission to a specific controller and/or action, as shown in Listing 5-20.

Listing 5-20. An Example Form Tag from grails-app/views/user/register.gsp

<g:form action="register" name="registerForm">
        ...
</g:form>

By default, the <g:form> tag uses the POST method for form submissions, meaning the previous example is roughly equivalent to the HTML definition (minus the closing tag):


<form action="/gTunes/user/register" method="POST" name="registerForm">
    ...
</form>

As an alternative to Listing 5-20, you can define the <g:form> tag using a single url attribute that uses the key:value map syntax to define the controller and action combination, as shown in Listing 5-21.

Listing 5-21. A <g:form> Tag with url Attribute

<g:form url="[controller:'user', action:'register']">
      ...
</g:form>

Of course, a form is of little use without some fields, the first of which to be discussed is the text field. In HTML, most fields are handled by the <input> tag, which has a type attribute to change its behavior and appearance. The downside of this approach is that it is not clear what its purpose is from simply looking at the tag.

Grails provides a number of wrapper tags that encapsulate the different types of HTML inputs into more meaningful tags.

The textField Tag

First up is the <g:textField> tag that, unsurprisingly, handles entry of textual values. The <g:textField> tag takes a name attribute, representing the name of the parameter to send as part of the form submission, along with the associated value attribute, as shown in Listing 5-22.

Listing 5-22. Example <g:textField> Usage

<g:form action="register" name="registerForm">
    ...
    <g:textField name="login" value="${user?.login}"></g:textField>
    ...
</g:form>

The previous <g:textField> definition will result in HTML input such as the following:


<input type="text" name="login" value="A Login Name" />
Check Boxes and Radio Buttons

Check boxes are often used as a representation of Boolean values from a domain model. Unfortunately, many frameworks place a lot of burden on the developer both to render check boxes in their correct state and to handle the server-side processing as to whether the check boxes are checked.

Grails, on the other hand, provides a <g:checkBox> tag that accepts a Boolean value attribute and will render the tag in its correct state. In addition, Grails transparently handles check box processing through its automatic type conversion and data binding facility (discussed in Chapter 7), as shown in Listing 5-23.

Listing 5-23. Example <g:checkBox> Tag

<g:checkBox name="aBooleanValue" value="${true}" />

Closely related to check boxes are radio buttons, which are used in groups, because they represent a one-from-many interaction. For example, two radio buttons must each be given the same name to be placed in the same group, and only one button can be selected at any one time.

Grails has a <g:radio> tag that provides a convenient way to define radio buttons and also to calculate that one has been checked.

In Listing 5-24, two radio buttons are defined in the same group. The one that has been checked is calculated using the hypothetical someValue variable.

Listing 5-24. Example <g:radio> Tags

<p>
    <g:radio name="myGroup" value="1" checked="${someValue == 1}" /> Radio 1
</p>
<p>
    <g:radio name="myGroup" value="2" checked="${someValue == 2}" /> Radio 2
</p>
Handling Lists of Values

When dealing with enumerated values (those that can be only a specific set of values), it is often useful to constrain what the user can enter by presenting an HTML select box as opposed to a free text-entry field.

To make creating selects much simpler, Grails provides a <g:select> tag that accepts a list or range of values via a from attribute. The currently selected value can be set with the value attribute.

The example in Listing 5-25 creates a select to choose a genre.

Listing 5-25. Example <g:select> Usage

<g:select name="genre" from="${['Rock', 'Blues', 'Jazz']}"
             value="${album.genre}" />

The following is the resulting HTML select, given an album with a genre of Rock:


<select name="genre">
    <option value="Rock" selected="selected">Rock</option>
    <option value="Blues">Blues</option>
    <option value="Jazz">Jazz</option>
</select>

Clearly, just going by the two examples, using the <g:select> tag can save you from writing a few lines of code. Its usefulness extends beyond this thanks to two additional attributes that allow <g:select> to be used in combination with object graphs and relationships.

The first is the optionKey attribute, which allows customization of the value attribute within each option tag of an HTML select. This may seem a little odd that an optionKey attribute customizes an attribute called value, but if you think of each <option> element as a key/value pair, it begins to make sense. The optionValue attribute, on the other hand, allows customization of the value that appears within the body of each option tag.

Using these two in combination can, for example, allow you to create a select from a list of domain object instances, as shown in Listing 5-26.

Listing 5-26. Using <g:select> on a List of Domain Objects

<g:select name="album.id" from="${Album.list()}"
                optionKey="id" optionValue="title"/>

The previous example takes a list of albums and creates an HTML select where the value attribute within the option tag is the id of the Album and the value within the body of each option is the title property of each Album. The result will resemble something like the following:


<select name="album.id">
      <option value="1">Undertow</option>
      ...
</select>

In addition to the general-purpose <g:select> tag, Grails provides a few others that may come in handy. The <g:currencySelect>, <g:localeSelect>, and <g:timeZoneSelect> tags are convenience tags for working with java.util.Currency, java.util.Locale, and java.util.TimeZone instances, respectively.

Unlike the <g:select> tag, each of these takes only two attributes: a name attribute for the name of the select and a value attribute, which takes an instance of one of the aforementioned classes, as shown in Listing 5-27.

Listing 5-27. Currency, Locale, and Time Zone Selects

<%-- Sets the currency to the currency of the Locale within the request --%>
<g:currencySelect
               name="myCurrency"
               value="${ Currency.getInstance(request.locale) }" />

<%-- Sets the locale to the locale of the request --%>
<g:localeSelect name="myLocale" value="${ request.locale }" />

<%-- Sets value to default time zone --%>
<g:timeZoneSelect name="myTimeZone" value="${ TimeZone.getDefault() }" />
Working with Dates

Dates can be represented in a number of ways, from drop-down selects to advanced JavaScript calendars. One of the more common ways, because of its nonreliance on JavaScript, is to use a combination of HTML select boxes to specify the date or time, with each select representing a unit of time: year, month, day, minute, hour, and second.

Grails provides support for creating such fields (and automatically performing type conversion onto date instances) using the <g:datePicker> tag, as shown in Listing 5-28.

Listing 5-28. A Basic Date Picker

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

At its most basic level, the <g:datePicker> tag takes a name attribute and a value attribute as a java.util.Date instance. In the previous example, it creates a <g:datePicker> for the current time, which consists of selects for the year, month, day, minute, hour, and second.

Clearly, it is not always useful to have that level of precision, so the <g:datePicker> tag provides the aptly named precision attribute for changing how many selects it renders. For example, to render only the year, month, and day selects, the following will suffice:

<g:datePicker name="myDate" value="${new Date()}" precision="day" />

All in all, Grails provides quite a few tools in your toolbox for simplifying the creation of forms. Given that forms allow users to enter data, often in a free-form fashion, implementing form handling is often one of the most challenging and error-prone activities in web application development.

To ensure data integrity, form validation is necessary and can be achieved on the client side using JavaScript. However, client-side validation should only ever be seen as a usability enhancement and not a replacement for server-side validation. Luckily, Grails provides solid support for performing validation with specialized validation and error-handling tags.

Validation and Error Handling

Having learned how to apply constraints to your domain model in Chapter 3, clearly it becomes useful at some point to display validation errors in the view when they occur. Of course, you could use scriptlets to iterate over the errors of a domain object and output them explicitly, but that's an awful lot of work that Grails can do for you. Just to recap how validation works, take a look at the state diagram shown in Figure 5-1.

image

Figure 5-1. Validation state diagram

The hasErrors Tag

It is often useful to conditionally display information depending on whether there is an error. To this end, Grails provides a <g:hasErrors> tag that supports the following attributes:

  • bean: A bean instance to inspect for errors
  • field: The name of the field to check for errors
  • model: An alternative to specifying a bean; an entire model (map) can be checked

If you recall, you have already seen the <g:hasErrors> tag used as a method, but it is also equally applicable as a tag. Interestingly, if no attributes are specified whatsoever, the tag will scan the entire request scope for beans and check each object found for errors. Since the <g:hasErrors> tag is often used in conjunction with <g:eachError>, we'll cover that next, followed by an example.

The eachError Tag

If a bean instance does have errors, it is useful to iterate over them and display each in turn. This can be done simply with the <g:eachError> tag, which takes attributes identical to those expected by the <g:hasErrors> tag.

Listing 5-29 demonstrates how to use the hasErrors and eachError tags to generate a list of error messages for an Album instance.

Listing 5-29. Displaying Errors

<g:hasErrors bean="${album}">
    <ul class="errors">
        <g:eachError bean="${album}">
              <li>${it.defaultMessage}</li>
         </g:eachError>
     >/ul>
</g:hasErrors>

In this instance, <g:hasErrors> checks whether there are any errors in the first place and, if there are, creates an HTML list. These errors are then iterated over via the <g:eachError> tag, which creates the list bullets using the default message. The default messages for validation errors can be found in the grails-app/i18n/message.properties message bundle.

If a list is all that is required, Grails makes it even easier to display errors via the <g:renderErrors> tag, which encapsulates everything you've just seen. Essentially, it takes the same arguments as the <g:eachError> tag, as well as an optional as attribute, which allows you to specify what to render the errors as. Listing 5-29 shows how to render the errors as a simple HTML list:

<g:renderErrors bean="${album}" as="list" />

As noted previously, the examples shown so far use the default message. Clearly, the default message is not always what is desired, and it is often useful to provide specific messages for each property within a domain class. This is where the <g:message> tag comes into play with Grails' support for internationalization (i18n). Internationalization is covered in detail in Chapter 7.

Paginating Views

Rendering lists of data in a web application is a common thing to do. Grails provides an easy-to-use mechanism for retrieving data from the database (GORM) and simple mechanisms for rendering the data (GSPs and GSP tags).

Web applications often serve as a front end to a database that may contain large volumes of data. The application may need to provide mechanisms for the user to manage navigating through those large volumes of data. For example, the gTunes application may contain thousands of artists, albums, and songs. A page that lists all the albums may be overwhelming and difficult for the user to work with, as shown in Figure 5-2.

image

Figure 5-2. A long list of albums

Figure 5-2 represents what the user might see if they requested a list of all the albums in the system that belong to the Rock genre. As you can see from the scrollbar on the right, this is a very long page. The page includes several hundred albums. An argument could be made that this is too much data to display on a single page. What if there were thousands of albums? What if there were hundreds of thousands of albums? Clearly, it would not make sense to present all those albums to the user on a single page.

The gTunes application needs to be smart about presenting manageable lists of data to the user. Instead of displaying hundreds or thousands of albums in a single list, maybe the application should display only five or ten. If the application displays only five or ten albums on the page, then the application also needs to provide a mechanism for the user to navigate around the larger virtual list to view the rest of the albums five or ten at a time.

Figure 5-3 represents a much more manageable interface.

image

Figure 5-3. A paginated list of albums

The list in Figure 5-3 includes only ten albums. The view provides mechanisms for navigating over the larger virtual list, which includes all the albums in this genre. This approach yields a much better user experience, especially for scenarios where the user may be overwhelmed with large sets of data.

Some complexity is involved in generating pagination controls like this. The application needs to retrieve smaller amounts of data from the database for each view. The application needs to provide support for requesting the batch of records that fall immediately before the current batch or immediately after the current batch. The application needs to provide a mechanism for jumping straight to an area of the list, as opposed to navigating through the larger list a single page at a time. The application needs to know the total number of records in the larger list. All of that would normally involve writing a lot of code.

The good news is that Grails provides a really simple mechanism for managing all that. That mechanism is a GSP tag called paginate. The paginate tag manages a lot of the tedious work that would otherwise be required in order to provide UI elements for navigating over large lists of data.

The GSP responsible for rendering this list is in grails-app/views/store/genre.gsp. That page includes the markup shown in Listing 5-30.

Listing 5-30. The genre.gsp

<h1>Online Store</h1>

<h2>Genre: ${genre.encodeAsHTML()}</h2>
<table border="0" class="albumsTable">
  <tr>
    <th>Artist</th>
    <th>Album</th>
    <th>Year</th>
  </tr>
  <g:each var="album" in="${albums}">
    <tr>
      <td>${album.artist.name}</td>
      <td><g:link action="show"
                  controller="album"
                  id="${album.id}">${album.title}</g:link>
      </td>
      <td>${album.year}</td>
    </tr>
  </g:each>

</table>
<div class="paginateButtons">
  <g:paginate controller="store"
              action="genre"
              params="[name:genre]"
              total="${totalAlbums}" />
</div>

The markup represented there renders an HTML table containing a header row and a row for each of the elements in the albums collection. Notice the use of the paginate tag at the bottom of Listing 5-30. That is all the code required in the GSP to render the pagination controls. The paginate tag takes care of all the tedious work involved in generating the "Previous" and "Next" links, all of the links that supporting jumping to a particular page, and all of the appropriate request parameters associated with each of those links. All of that is being handled by this single call to a GSP tag—the whole thing could barely be any simpler!

The paginate tag is generating a number of links. The controller and action parameters tell the paginate tag where each of those links should submit. In this particular case, all the links submit to the genre action in the StoreController. If all the links reference the same controller action, you might wonder how the application knows the difference between the user clicking one link vs. another. The answer has to do with the fact that the paginate tag is tacking a number of request parameters on the end of each link and those request parameters are used by the controller action. For example, the "7" link points to the URL /store/genre?offset=60&max=10&name=Rock. The "8" link points to the URL /store/genre?offset=70&max=10&name=Rock. Notice that each of those links includes the same value for the max and name parameters, but they include a different value for the offset parameter. That offset parameter is an important part of the request because that is how the controller will know what page of data should be returned when the user clicks one of those links. Let's take a look at the relevant controller action.

Listing 5-31 includes the code that is in the genre action in the StoreController.

Listing 5-31. The genre action

def genre = {
    def max = Math.min(params.max?.toInteger() ?: 10, 100)
    def offset = params.offset?.toInteger() ?: 0

    def total = Album.countByGenre(params.name)
    def albumList = Album.withCriteria {
      eq 'genre', params.name
      projections {
        artist {
          order 'name'
        }
      }
      maxResults max
      firstResult offset
    }
    return [albums:albumList,
                   totalAlbums:total,
                   genre:params.name]
  }

Note The previously shown query uses the Hibernate Criteria API. We'll describe the general behavior of the query next. The Criteria API is discussed in detail in the "Criteria Queries" section of Chapter 10.


The name request parameter is being used in both of the previous queries. The first query is necessary to count the number of albums in the database that belong to a certain genre. The second query is actually retrieving a list of albums. That second query is not retrieving all the albums that belong to a certain genre but is retrieving a subset of at most ten of those albums.

For example, imagine there is a list of 1,000 albums and each of those albums has an index associated with it starting with 0 and running up through 999. When a request is sent to the /store/genre?offset=60&max=10&name=Rock URL, the call to the Album.withCriteria(...) method will return ten of those albums starting with the Album at index 60. The max parameter represents the maximum number of albums that should be returned.

Notice that the first line in the genre action is assigning a default value of 10 to max if no max request parameter is found. If a max request parameter is found and the value is greater than 100, the system is falling back to a max of 10. Displaying more than 100 albums per page would defeat the purpose of having the pagination support in place.

The offset parameter represents what point in the larger list should this list of ten begin. If no offset request parameter is supplied, the system is defaulting the value to 0 or the beginning of the list.

The map of data being returned by the genre action includes not only the list of albums but also includes values for totalAlbums and genre, each of which are used in genre.gsp as parameters to the paginate tag. All of this needs to be kept in sync as part of the interaction between the controller action and the GSP.

The paginate tag supports a number of arguments. Table 5-2 lists those arguments.

Table5-2. Arguments Supported by the paginate Tag

Argument Description
total Total number of elements in the larger list
controller Name of the controller to link to
action Name of the action to invoke
params Map of request parameters
offset Offset to be used if params.offset is not specified
max Maximum number of elements per page
prev Text for the "Previous" link
next Text for the "Next" link
id ID to use in links
maxsteps Number of steps displayed for pagination (the default is 10)

All of the parameters supported by the paginate tag are optional except for the total parameter.

The default scaffolded list views in a Grails application include support for paginating the list. Define a simple domain class like the Car class shown in Listing 5-32.

Listing 5-32. A Car Domain Class

class Car {
  String make
  String model
}

Generate scaffolding for the Car class, and you will see that the default list action in the CarController and the default grails-app/view/car/list.gsp include support for paginating the list of cars. Listing 5-33 shows the relevant part of the GSP.

Listing 5-33. grails-app/view/car/list.gsp

<div class="list">
  <table>
    <thead>
      <tr>
        <g:sortableColumn property="id" title="Id" />
        <g:sortableColumn property="make" title="Make" />
        <g:sortableColumn property="model" title="Model" />
      </tr>
    </thead>
    <tbody>
      <g:each in="${carInstanceList}" status="i" var="carInstance">
        <tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
          <td>
            <g:link action="show"
                    id="${carInstance.id}"
                >${fieldValue(bean:carInstance, field:'id')}
            </g:link>
          </td>
          <td>${fieldValue(bean:carInstance, field:'make')}</td>
          <td>${fieldValue(bean:carInstance, field:'model')}</td>
        </tr>
      </g:each>
    </tbody>
  </table>
</div>
<div class="paginateButtons">
  <g:paginate total="${Car.count()}" />
</div>

The only attribute specified in this call to the paginate tag is the required total attribute. Notice that in this case the value of the total attribute is simply the total number of cars in the database. This is a little bit different from the example shown earlier where the value of the total attribute was not necessarily all the number of albums in the database but was the number of albums in the database that belong to a particular genre.

Listing 5-34 shows the list action in the CarController.

Listing 5-34. Pagination Support in the CarController

class CarController {
def list = {
    if(!params.max) params.max = 10
    [ carInstanceList: Car.list( params ) ]
  }

  ...
}

The default list action in the CarController will assign a value of 10 to the max request parameter if a value is not supplied.

The application may take control over the order of the cars using any number of techniques supported by GORM. The simplest solution for this particular case is to include the order clause in the dynamic method, as shown in Listing 5-35.

Listing 5-35. Ordering Cars By Model

class CarController {

  def list = {
    if(!params.max) params.max = 10
    [ carInstanceList: Car.listOrderByModel ( params ) ]
  }

  ...
}

With all of that in place, if the database includes more than ten cars, then the pagination support in the view will kick in, as shown in Figure 5-4.

image

Figure 5-4. Paginating a list of cars

Rendering GSP Templates

A GSP template is a special GSP file that contains only a fragment of a page. A GSP template can contain markup that is rendered from various places in an application in which case the template would facilitate reuse. A template can be extracted from a page to simplify the containing page by breaking it down into smaller, more manageable pieces. Whatever the reason for isolating part of a page into a reusable template, Grails provides a really simple mechanism for rendering the template.

A template can contain just about anything that might appear in a normal GSP. One thing that makes a template special is its file name. GSP templates must be defined in a file whose name begins with an underscore. For example, a template that represents a list of albums might be defined in grails-app/views/album/_albumList.gsp.

The render tag can be used in a GSP to render a GSP template. The render tag accepts an attribute called template that represents the name of the template to be rendered. For example, to render the template in the grails-app/views/album/_albumList.gsp file, you would specify /album/albumList as the value of the template attribute when calling the render tag, as shown in Listing 5-36.

Listing 5-36. Rendering the albumList Template

<div id="artists">
  <g:render template="/artist/artistList"/>
</div>

Notice that the template file name contains an underscore, but the name of the template does not.

Rendering a template in a GSP is very much like taking the contents of the GSP template and putting them inline in the containing GSP in place of calling the render tag.

Figure 5-5 shows an updated version of the gTunes application.

image

Figure 5-5. Updated gTunes

Notice the three boxes on the right of the screen representing the latest albums, latest songs, and newest artists. The markup required to generate each of those boxes would clutter the GSP. Rather than embedding the markup for those boxes in the views/store/shop.gsp file, you can pull all of that out into a series of templates and render those templates from shop.gsp. Using templates to handle this will yield an easier-to-maintain application compared to an application with monolithic unmodular GSPs.

Listing 5-37 shows what those templates might look like.

Listing 5-37. GSP Templates for the Top Five Lists

<!-- grails-app/views/artist/_artistList.gsp -->
<ul>
  <g:each in="${artists}" var="artist">
    <li>${artist?.name}</li>
  </g:each>
</ul>


<!-- grails-app/views/album/_albumList.gsp -->
<ul>
  <g:each in="${albums}" var="album">
    <li>${album.title}</li>
  </g:each>
</ul>
<!-- grails-app/views/song/_songList.gsp -->
<ul>
  <g:each in="${songs}" var="song">
    <li>${song.title}</li>
  </g:each>
</ul>

Note For now these are very simple templates that render unordered lists of strings. In Chapter 8 you will evolve these templates to contain some really slick Ajax-driven behavior. At that point, the value of having isolated this markup into templates will be even greater.


Notice that each of those templates is iterating over a different collection (artists, albums, and songs). Those collections are data that must be passed into the template when the template is rendered. The way to pass data into a GSP template is to specify an attribute called model when calling the render tag. The value of the model attribute should be a map containing all the data that is being passed in to the template. Listing 5-38 shows each of those templates being rendered from the grails-app/views/store/shop.gsp and the appropriate data being passed to each of the templates.

Listing 5-38. Rendering Templates from shop.gsp

<div id="top5Panel" class="top5Panel">
  <h2>Latest Albums</h2>
  <div id="albums" class="top5Item">
    <g:render template="/album/albumList"
              model="[albums: top5Albums]"/>
  </div>
  <h2>Latest Songs</h2>
  <div id="songs" class="top5Item">
<g:render template="/song/songList"
              model="[songs: top5Songs]"/>
  </div>
  <h2>Newest Artists</h2>
  <div id="artists" class="top5Item">
    <g:render template="/artist/artistList"
              model="[artists: top5Artists]"/>
  </div>
</div>

The templates being rendered here are /album/albumList, /song/songList, and /artist/ artistList. Each of those is a fully qualified reference to a template. When a template name is fully qualified like that, the root refers to the grails-app/views/ directory, so /artist/ artistList refers to the template defined in the grails-app/views/artist/_artistList.gsp file. Template references may be defined with a relative path as well. Relative template paths are paths that do not begin with a forward slash.

For example, if instead of referring to /artist/artistList the shop.gsp referred to the relative artistList template, then Grails would look for the template in the same directory where shop.gsp lives. Relative references can also include a directory structure. If the artistList template were defined in grails-app/views/store/myTemplates/_artistList.gsp, then the grails-app/views/store/shop.gsp page could refer to the template as myTemplates/artistList since the myTemplates directory is in the same directory as shop.gsp.

Each of the calls to the earlier render tag includes a map of data being passed as the model attribute. For shop.gsp to have that data, the controller action that rendered shop.gsp needs to supply those values. In this case, the controller action is the shop action in StoreController, as shown in Listing 5-39.

Listing 5-39. The shop Action in StoreController

package com.g2one.gtunes

class StoreController {

  def shop = {
    def genreList = Album.withCriteria {
      projections {
        distinct "genre"
      }
    }

    [top5Albums: Album.list(max:5, sort:"dateCreated", order:"desc"),
     top5Songs: Song.list(max:5, sort:"dateCreated", order:"desc"),
     top5Artists: Artist.list(max:5, sort:"dateCreated", order:"desc"),
     genres: genreList.sort()]
  }

  // ...
}

Notice that the controller action is returning values for albums, songs, and artists. The values are lists containing the five most recently created albums, songs, and artists.

These templates have been defined to render these "Top 5" lists in the shop.gsp, but they are reusable templates that can be used anywhere that the application needs to render lists of albums, artists, or songs. It is commonplace for web applications to render the same pieces of information on a lot of pages. When you see the same elements showing up in multiple places, consider pulling that markup out of your GSPs and putting it in a reusable template.

Creating Custom Tags

Custom tags in JSP are a wonderfully powerful feature. They provide the ability to cleanly separate concerns between the view and controller logic. In MVC terms, you can think of them as view helpers. Unfortunately, for all their wonderful attributes they are tremendously complicated to develop. The reasons for this are understandable, because JSP tags attempt to account for every possible tag creation scenario including the following:

  • Simple tags that have attributes only and no body
  • Body tags that have both attributes and a body
  • Tags that have parent-child relationships between one another
  • Nested tags and a complete API for finding tag ancestors

The implication, however, is that the API for creating JSP custom tags is robust, to say the least. To compound matters, additional information is required about the tag in a tag library descriptor (TLD) file that is loaded on application startup. This makes tags difficult to reload without a server restart, because the application server utilizes this file to configure the tag library. As you can imagine, all this is not very agile and is rather a complete contradiction to the code-by-convention approach.

From a user's perspective, developers rarely go to the effort of creating tags themselves, and typically the ones used tend to be those provided by the frameworks and specifications, such as JSTL. This is rather a shame, because the concept is sound, though the implementation is not.

So, what can Grails and, more specifically, GSP provide to make creating tags simpler? Clearly, supporting every tag type under the sun would result in a complicated API, much like that in JSP. In reality, the most commonly used tags can be broken down into three categories:

  • Simple tags: Tags that have attributes but no body
  • Logical tags: Those that have a body that executes conditionally
  • Iterative tags: Tags that loop and execute the body of the tag one or more times

You will find that the majority of tags you come across fall into one of the previous categories. Since Grails is all about making the common cases simple, creating a simplified API for these tag types seems only logical. The question is, why create a new API at all? This is where Groovy and the power of closures start to shine.

Creating a Tag Library

Having already seen quite a few Grails tags throughout this discussion, it may well be that you've already browsed the source and have become familiar with what a Grails tag is all about. Regardless, it is important to understand how to create a tag library from scratch.

It is generally good practice to place tags inside a library that encapsulate their general function, kind of like a package does in Java.

A tag library is quite simply a class that ends with the convention TagLib in the class name and resides snugly in the grails-app/taglib directory. Like the other Grails artifacts you've seen, a convenience target exists for creating tag libraries. To create a new tag library for the gTunes application, you can run the grails create-taglib target and type gtunes, as shown in Listing 5-40.

Listing 5-40. Creating the Gtunes Tag Library

$ grails create-taglib

init-props:

create-taglib:
    [input] Enter tag library name:
Gtunes
     [copy] Copying 1 file to /Developer/grails-apps/gtunes/grails-app/taglib
     [echo] Created taglib: grails-app/taglib/GtunesTagLib.groovy

BUILD SUCCESSFUL
Total time: 8 seconds

The result will resemble something like the following:


class GtunesTagLib {

}

To see how to go about making a tag library, in the next section you'll look at a basic tag and then build some snazzy functionality into the gTunes application for rendering album cover art.

Custom Tag Basics

First let's look at the basics. A tag is essentially a closure property that takes two arguments: the tag attributes as a java.util.Map and the body of the tag as a closure, as shown in Listing 5-41.

Listing 5-41. An Example Tag

class GtunesTagLib {

  def repeat = { attrs, body ->
    attrs.times?.toInteger().times { n ->
      body(n)
    }
  }
}

In the example, we've defined a tag called repeat that looks for an attribute called times, which it attempts to convert to an integer, and then uses Groovy's built-in times method to execute the body multiple times.

As mentioned previously, the body is a closure and therefore can be invoked like a method. In addition, you pass the number of the current iteration, as the variable n, to the body as the first argument to the closure call. Why is this useful? It means that the number is available as the default it argument in the tag's body. As an example, let's try the new tag in a GSP view as in Listing 5-42. Note that the name of the tag in the markup matches the property name defined in the library shown in Listing 5-41.

Listing 5-42. Using the repeat Tag

<g:repeat times="3">
       Hello number ${it}
</g:repeat>

As you can see, the tag uses the default it argument to reference the value passed when the tag calls the body closure. The resulting output will be the following:


Hello number 1
Hello number 2
Hello number 3

All the tags that are bundled with Grails are defined in the g namespace. By default, all your own custom tags are also put in the g namespace. To avoid naming conflicts with built-in tags and with tags that may be installed into a project as part of a plugin, you should define a namespace for your own tag libraries. Defining a namespace for a tag library is as simple as declaring a static property called namespace in the taglib class and assigning that property a String value, as shown in Listing 5-43.

Listing 5-43. Defining a Custom Namespace for a Tag Library

class GtunesTagLib {

  static namespace = 'gt'

  def repeat = { attrs, body ->
    attrs.times?.toInteger().times { n ->
      body(n)
    }
  }
}

With that namespace property in place, all the tags defined in the GTunesTagLib are now in the gt namespace. Instead of referring to <g:repeat/>, GSPs should now refer to <gt:repeat/>.

Not only are Grails tags amazingly concise when compared to their JSP brethren, but it is important to note that all changes to tags can be reloaded at runtime just like with controllers; there's no need to configure tag library descriptors or restart servers, which makes Grails tags a far more interesting and agile proposition.

Testing a Custom Tag

Like most of your code in a Grails application, the code in custom tag libraries should be tested. Testing tag libraries can be tricky. The test needs a way to invoke a tag, provide parameters, provide a body, and inspect the effect of invoking the tag. Fortunately, Grails provides a really slick mechanism for managing all of that. Unit tests for custom tag libraries should extend from the grails.test.TagLibUnitTestCase class. Listing 5-44 contains a unit test for the GtunesTagLib class defined earlier.

Listing 5-44. Testing GtunesTagLib

// test/unit/GtunesTagLibTests.groovy

import grails.test.*

class GtunesTagLibTests extends TagLibUnitTestCase {

  void testRepeat() {
    tagLib.repeat(times: '2') {
      'output<br/>'
    }
    assertEquals 'output<br/>output<br/>', tagLib.out.toString()
  }
}

The testRepeat() method here is invoking the repeat tag and supplying a map of parameters and a closure as arguments. In this case, the map contains a single parameter (times), but the map may contain any number of parameters. The closure being passed to the tag method represents the body of the tag. In this case, the closure returns a String. If the tag is behaving correctly, the body of the tag should be rendered twice since the value of the times parameter is 2. The assertion at the bottom of the test method is checking that this did in fact happen.

This test is interacting primarily with the tagLib property. This property is not defined in the test class but is inherited from TagLibUnitTestCase. This property will be an instance of the tag library that is being tested. All the tags defined in this tag library are accessible as method calls on the tagLib property.

A common thing to be asserting when testing a tag is that the tag rendered the expected text. The out property on tagLib contains whatever the tag rendered, so inspecting that property after invoking the tag is the simplest way to make that assertion.

The GtunesTagLibTests class does not define what tag library class is being tested here. How does Grails know where to find the repeat tag? By default, Grails will infer the name of the tag being tested by removing Tests from the end of the test class name. Since this class is called GtunesTagLibTests, Grails assumes that this is a test for the GtunesTagLib tag library. If your test does not follow this naming convention, you can be explicit about what tag library is being tested by overriding the default constructor and passing the tag library class as an argument to the superclass constructor. Listing 5-45 shows how to do this.

Listing 5-45. Being Explicit About Which Tag Library Is Being Tested

// test/unit/MyTagLibTests.groovy

import grails.test.*

class MyTagLibTests extends TagLibUnitTestCase {

  MyTagLibTests() {
    super(GtunesTagLib)
  }

  void testRepeat() {
    tagLib.repeat(times: '2') {
      'output<br/>'
    }
    assertEquals 'output<br/>output<br/>', tagLib.out.toString()
  }
}

Summary

You have learned quite a bit in this chapter. You learned about Grails' advanced view technology, GSP, and the array of powerful tags that come packaged with it. You also learned how to build and test your own GSP tags, and you further extended your knowledge of Groovy mocking in the process. We covered a lot of ground, and you should now have a clear idea of how powerful GSP is. Thanks to GPath, an expression language, and dynamic tag libraries, GSP has a lot to offer to increase your productivity and enjoyment.

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

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