Browse DevX
Sign up for e-mail newsletters from DevX


View Rendering in Java: Templates Out, Groovy Builders In : Page 3

Template engines have long been the de-facto standard for rendering views in Java web development. Learn why templates are far from ideal and how Groovy builders provide a literate solution for bringing view rendering back into your code.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Extracting Page Components
So far, you have some expressive code that can generate XHTML, and you can test the presentation logic. However, the page you are working with is still extremely simple and trivial. If the page gets much bigger, your test is going to become cumbersome, as it has to set the expectations for each section of the page. Using the "zebra table" from the example, the following listings show how easy it is to extract page components now that you are using code to render the view.

To enable reuse and simplify future tests, you can extract the generation of the table to another class:

package viewbuilder class ZebraTable { def render(builder, rows) { builder.table { rows.eachWithIndex {row, i -> tr('class': (i.mod(2) == 0) ? 'highlight' : '') { td("col1") td("col2") } } } } }

You can move the tests for determining whether the rows are styled correctly to the table component (see Listing 5).

You can simplify the table page to use the table component:

package viewbuilder class ZebraTablePage { def render(builder, rows) { builder.html { head { title("My Page") } body { p("Put the table here:") new ZebraTable().render(builder, rows) } } } }

You can see from the code listings above that it is extremely simple to extract the presentation logic still further into reusable components. The real benefit of this approach over the usual template 'include' approach is that these components are easy to test independently.

Flexible Design
The other benefit of using code for view rendering is that you are not restricted to any single presentation design pattern. This provides you the flexibility to implement views using whichever design patterns you choose, rather than being constrained to the patterns enforced by your template engine.

For example, it is just as easy to implement a decorator pattern as it is to create presentation components. With the code in Listing 6, you can define a layout class (MainLayout) to decorate page classes with a common page layout and title structure.

You can see that the MainLayout class defines the common layout elements for your site:

  • Title prefix
  • Primary navigation
  • Main content pane
  • Footer

A home page class can then use the layout class as its decorator and provide page details for the title and body content:

package viewbuilder.decoratorexample import viewbuilder.ZebraTable class HomePage extends MainLayout { def render(rows) { builder.html { head { title("Home") } body { new ZebraTable().render(builder, rows) } } } }

The page defines its layout by extending a layout class. The page starts using the builder and passes off construction of the majority of the page to its layout through the title and body method calls.

The implementation of your individual pages now starts to become very simple. You can separate presentation logic out into components, the layout handles common page elements, and the page needs to handle only very specific page details.

For testing, you can test the home page class in the code examples above using the same approach as defined previously (see Listing 7).

Thanks for your registration, follow us on our social networks to keep up-to-date