Reference Manual for Gracelets - 2.0.0.RC2SourceForge.net Logo
1.5 - Introduction : How it Works : View Scripts
When a request comes in for a JSF page (based off your web.xml configuration), usually determined by the requested resource ending in the URL pattern you have setup in your web.xml for the FacesServlet, Gracelets looks to see if there is a corresponding .groovy file/view to handle the request. If there is, Gracelet's steps in and builds the JSF view off the view script.

So if you had a request URL like http://localhost:8080/index.jsf and in the root of your web application there is a file called index.groovy, Gracelets will detect that and intervene to allow the view script to build the view. View scripts take precedence over normal XHTML source files, so if in the example mentioned you also had a file called index.xhtml, it would get ignored since index.groovy exists.

A view script normally builds a view by means of the use of special Groovy Builder's. Each instance of these special Groovy Builders, or gracelet builders, represents a Facelet tag library. Most of the common tag libraries are automatically available to the view script, like the Facelet UI Tag Library, JSF Core Tag Library, JSF HTML Tag Library. A special builder is also available to easily output normal XML/XHTML markup.

The following is a complete list of the basic set of libraries and the bound variable you can use to reference them:

Automatically available Tag Libraries Namespace Aliases
Bound Variable Name/AliasTag Library NamespaceShipped with Gracelets
fhttp://java.sun.com/jsf/coreYes
ghttp://gracelets/taglibYes
hhttp://java.sun.com/jsf/htmlYes
jqhttp://gracelets/jqueryYes
uhttp://java.sun.com/jsf/faceletsYes
xhhttp://www.w3.org/1999/xhtmlYes
To clarify, what we mean by "automatically available" is that you simple do not have to define the namespace in your gracelet script. What it does not mean is that all these libraries are availabe simply by using Gracelets. Above, the libraries that that say "Yes" under the "Shipped with Gracelets" column, truly are available and ready to use libraries. But the ones that say no simply mean that if you have those libraries on your classpath, you don't have to define the namespace in order to use them, they are automatically ready to be used by simply using the variable mentioned above. Also if you are using extensions or Gracelet Component Libraries from a third party or that you have defined yourself, other automatically available aliases can also be instantly available to your Gracelet views.

Everything you are used to accessing in XHTML scripts is available via the builders. Instead of referencing the XML Namespace aliases you define at the top of XHTML views you reference bound builders (if they do not have an automatic alias available) in Gracelet views. Each method called on a particular bound builder is really a direct call to make the tag that has the same name as the method call. The map of parameters passed to the method call become the tag attributes. If you pass a single parameter as well it will be automatically linked to the 'value' attribute.

Having these tag libraries automatically available to each view script means there is much less namespace declarations as there is in normal XHTML source files. You will normally only have to import other third party tag libraries that may not be made to work directly with Gracelets view library aliases.

Comparing a XHTML source view file to a practically identical Gracelet view script will help to understand this:
XHTML Source View
Toggle Line Numbers
1 <html xmlns:ui="http://java.sun.com/jsf/facelets" 
2             xmlns:jsf="http://java.sun.com/jsf/core" 
3             xmlns:html="http://java.sun.com/jsf/html"> 
4  
5     <head> 
6         <title>Some Title</title> 
7         <link rel="stylesheet" type="text/css" href="style.css"/> 
8     </head> 
9  
10     <body> 
11          
12         <table width="100%" cellspacing="0" cellpadding="0"> 
13          
14             <caption class="header"><ui:insert name="header">Default Header</ui:insert></caption> 
15              
16             <tr> 
17                 <td valign="top" class="sidebar"> 
18                     <ui:insert name="sidebar"> 
19                             <html:form> 
20                                 <html:selectOneMenu value="#{someMainBean.value}" onchange="this.form.submit();"> 
21                                     <jsf:selectItems value="#{dummmyList}"/> 
22                                 </html:selectOneMenu> 
23                             </html:form> 
24                     </ui:insert> 
25                 </td> 
26                 <td valign="top" class="content"> 
27                     <ui:insert name="content"/> 
28                 </td> 
29             </tr> 
30          
31         </table> 
32          
33     </body> 
34  
35 </html> 
Toggle Line Numbers
1 xh.html () { 
2     xh.head { 
3         xh.title { 
4             print "Some Title" 
5         } 
6         xh.link (rel: "stylesheet", type: "text/css", href: "style.css") 
7     } 
8     xh.body { 
9         xh.table (width: "100%", cellspacing: "0", cellpadding: "0") { 
10             xh.caption (class: "header") { 
11                 u.insert (name: "header") { 
12                     print "Default Header" 
13                 } 
14             } 
15             xh.tr { 
16                 xh.td (valign: "top", class: "sidebar") { 
17                     u.insert (name: "sidebar") { 
18                         h.form { 
19                             h.selectOneMenu (value: "#{someMainBean.value}", onchange: "this.form.submit();") { 
20                                 j.selectItems (value: "#{dummmyList}") 
21                             } 
22                         } 
23                     } 
24                 } 
25                 xh.td (valign: "top", class: "content") { 
26                     u.insert (name: "content") 
27                 } 
28             } 
29         } 
30     } 
31 } 
It is easy to import other libraries. The following example shows how:
Toggle Line Numbers
1 mtl = ns."http://mytaglib/namespace" 
After declaring the mtl variable like above , all calls to the mtl variable will participate in the view building process and use the tag library set referenced by the namespace.

So if the 'http://mytaglib/namespace' library mentioned above had a defined tag called coolOutput, you could reference it like so:
Toggle Line Numbers
1 mtl.coolOutput() 
Any attributes passed to the builder method call become tag attributes. So if the tag mentioned above uses an attribute called style, you could define it like so:
Toggle Line Numbers
1 mtl.coolOutput(style: "some value") 
If you pass a single value somewhere in the method argument list, it will be automatically wired to the 'value' attribute. So for example, if the coolOutput tag accepted a 'value' attribute, you could specify it as follows:
Toggle Line Numbers
1 mtl.coolOutput("Some Value") 

View Script Dynamics

At this point you might be wondering what other benefits there are to using Gracelets other than avoiding alot of xml and namespace declarations.

Something that should be obvious is that you can now run arbitrary groovy/java code, maybe complicated view logic, right inside the view, thus not having to put view logic code inside of a controller bean, where many times it does not belong. This makes it as flexible as JSP pages. So if you want to do some arbitrary loop and create multiple of the same tag or even different tags depending on each loop values, you could do that without the use of complicated tags and facelet handlers.

For example, you could do the following to generate a menu on some template:
Toggle Line Numbers
1 def options =  
2     [ 
3      one: "Option One", 
4      two: "Option Two", 
5      three: "Option Three" 
6     ] 
7  
8 h.html { 
9      
10     head { title ("Looping Example") } 
11      
12     body { 
13          
14         table { 
15              
16             tr { 
17                 td(valign: "top", width: 200) { 
18                     options.each { o -> a(o.value, href: "#${o.key}"); br(); } 
19                 } 
20                 td(valign: "top") { 
21                     u.insert(name: "content") { 
22                         print "Default Content" 
23                     } 
24                 } 
25             } 
26              
27         } 
28          
29     } 
30      
31 } 
Click here to see the output of this example

This last example where we show the use of groovy code loops being used is somewhat of a static-dynamic feature. Since view scripts are only ran once, the loop is only done once. For some things, this is actually good, and efficient. This allows one to build static parts of the page based off of some source in the system that does not change very often. This could be like an enum, or a table that is rather static between deployments.

This may not be useful to many, but it is important to understand the difference between the this type of 'dynamic' page and the dynamic features we will be considering next.

One feature of gracelets that allows your page to be more dynamic is the render {} tag, that allows you to write render time code. With the render {} tag you can create truly dynamic parts of the view (each page access wil be dynamically rendered).

The following example is a redo of the previous example in order to make it dynamic every time the page is rendered:

Toggle Line Numbers
1 def options =  
2     [ 
3      one: "Option One", 
4      two: "Option Two", 
5      three: "Option Three" 
6     ] 
7  
8 h.html { 
9      
10     head { title ("Looping Example") } 
11      
12     body { 
13          
14         table { 
15              
16             tr { 
17                 td(valign: "top", width: 200) { 
18                     render { cmp ->  
19                         options.each { o -> 
20                             def x = cmp.builder 
21                             x.a(o.value, href: "#${o.key}"); 
22                             x.br();  
23                         }  
24                     } 
25                 } 
26                 td(valign: "top") { 
27                     u.insert(name: "content") { 
28                         print "Default Content" 
29                     } 
30                 } 
31             } 
32              
33         } 
34          
35     } 
36      
37 } 
The above example shows the render {} tag accepting 1 closures, which is a renderer closure.

The renderer closure is a RENDER time closure. This means that it is ran every time the page is rendered/accessed. This also means that you do not have access inside this closure to the builders mentioned above. Remember that Facelets/Gracelets view building is done prior to the component tree rendering. So by the time this closure is ran the component tree has already been constructed by Gracelets. To make rendering code alot more compact and easier, a special builder is automatically available via the builder getter on the component. You can call it as many times as you want to get a markup builder to easily produce XML compliant markup. All methods called on the builder are translated into regular markup and sent to the ResponseWriter. With this example our problem of being truly dynamic in the previous example has been solved.

Now, what about accessing all the tags that JSF and Facelets give us. Well a second closure can contain the children of the render {} tag. The render {} tag can render its children as many times as it wants. So if you wanted to use the JSF 'outputLink' tag instead of the regular XHTML 'a' tag, you could do what is shown in the following example:
Toggle Line Numbers
1 def options =  
2     [ 
3      one: "Option One", 
4      two: "Option Two", 
5      three: "Option Three" 
6     ] 
7  
8 h.html { 
9      
10     head { title ("Looping Example") } 
11      
12     body { 
13          
14         table { 
15              
16             tr { 
17                 td(valign: "top", width: 200) { 
18                     render ({ cmp, ctx, atts -> 
19                         options.each { o ->  
20                             link = o.key; 
21                             label = o.value; 
22                             cmp.renderChildren() 
23                         }  
24                     }) { 
25                         h.outputLink(value: { link }) { print { label } } 
26                         xh.br() 
27                     } 
28                      
29                 } 
30                 td(valign: "top") { 
31                     u.insert(name: "content") { 
32                         print "Default Content" 
33                     } 
34                 } 
35             } 
36              
37         } 
38          
39     } 
40      
41 } 
As can be seen in the above example, you can also accept three parameters for your renderer closure. The first is the JSF UIComponent instance, the second is the FacesContext instance and the third a quick reference to the attributes of the UIComponent.

The UIComponent instance has some special methods which make it easy to render the children components. A method called renderChildren() can be called as many times as desired to have the children defined in the second closure rendered.

With this last render {} tag example, we see that we can have truly dynamic pages that can be as dynamic as is needed or desired.

EL, closures and variable resolution

Another powerful dynamic part of view scripts is the option to use closures extensively. These closures make an otherwise static view script more dynamic. You may have noticed above that there were some EL expressions used to reference certain beans. While this is perfectly fine, you could actually use closures instead. For example in the first converted example above, on line 20, you could do the following instead:
Toggle Line Numbers
20                     j.selectItems(value: { dummyList }) 
Here we are using a closure to provide the list of select items instead of EL, which means if we wanted or needed to we could write the code to actually produce the list right here in the script. This is great for prototyping or for production bug fixes. There is alot more to be seen in this regards, but at least this begins to show how closures can take the place of EL expressions, which gives you the power to put any type of arbitrary groovy code and thus make it much more powerful than the limited expression language.

You may be wondering about variable resolution at this point. In the above examples we have referred to variables that were not directly declared, and we have even assigned values to them. This manifests part of Gracelets Variable Context solution. When you reference from or assign to a variable that has not been declared somewhere in your script, Gracelets tries to resolve it via the variable contexts (view, request, conversation, session, application) Also a set of useful variables is available for accessing common parts of the JSF or Servlet environment, these are mentioned in the Appendix : Variables.

When you reference a variable it will search each different context in ascending order. When you assign to a variable that does not exist in any context, it will use the current scoped context (which can be set) and which defaults to Conversation scope in the default implementation and when using the JBoss Seam extension. Thus if you assign to a non-declared variable and that also does not currently exist in any variable context, and you have not changed scope, it will "outject" as it were, the value you set to the conversation scoped variable that you are assigning to. This allows you to interact with the variable contexts without any need for declaration, dependancies or injection/outjection.

Thus in the code snippet above, where we reference the 'dummyList' variable, it will actually search the variable context's and resolve it. Since variable contexts are tied to the JSF bean model as well and the basic Request, Session and Application scoped framework in JSF, all managed beans and really anything that can be accessed in a regular EL expression can be acessed as variables in your view script.

Together with the use of closures you can begin to develop very powerful solutions in a compact single view script.

You can easily create special value binding closures with a method that is automatically available to view scripts. This method is called Value(). It takes two different argument sets as is listed below:
  1. Value( { } )
  2. Value(setter: {}, getter: {})
The first on can be used to reference beans similiar to in EL. Notice the following example:
Toggle Line Numbers
1 h.inputText(value: Value({ myBean.someProperty })) 
In the above example, it makes the 'someProperty' property of the myBean bean the value binding of the 'inputText' tag, it will make it possible for the inputText component to set and get the value from the specified property.

In the next example, we see the second way you can define a value closure, which allows you to put in special logic for getting and setting:
Toggle Line Numbers
1 h.inputText(value: Value(getter: { myBean.someProperty }, setter: { myBean.someProperty = it }) 
In this example we achieve practically the same thing as the previous example, but we are using two different closures for the two operations, getting and setting. We could put any code in there doing special operations each time the value is retreive or set. More about this is covered in the tutorial, in the Closure Bindings section

Instead of using regular EL or action bindings, you can use action closures. Notice this in the following code:
Toggle Line Numbers
1 h.commandButton("Save Changes", action: { someBean.save(selectedEntity); facesMessages.add("Changes saved"); }) 
Here we can call the someBean, which takes care of persistence, passing it the selectedEntity object. Then we can take care of UI messages here instead of in the bean controller. Since the facesMessages bean is directly available (with or without JBoss Seam extension) we can simply reference and call the add() method in order to pop a faces message on the stack.

Tags and Templates

In reality there is little difference between Gracelet Pages and Gracelet Tags and Templates. Everything mentioned above applies equally to Tags and Templates. Templates of course are normally stored in a directory off the WEB-INF directory where they cannot be directly referenced as page. Tags are normally referenced in a Facelet Tag Library definition file (a file ending in .taglib.xml, please see the Facelets Developer Documentation for more information on the use and definition of Tag Libraries). Just as you can specify an XHTML source file in a Tag Library file, so you can reference a Gracelet Tag script. Below is a fragment from a Tag Library where we define a Gracelet Tag script:
Toggle Line Numbers
1  
2         <tag> 
3             <tag-name>someTag</tag-name> 
4             <source>tags/someTag.groovy</source> 
5         </tag> 
6          
Of course, you may prefer writing Gracelet Component Libraries, which is covered later in the tutorial.