Sencha Inc. | HTML5 Apps

Blog

Ext GWT 3.0 XTemplate Redesign

May 18, 2011 | Darrell Meyer

XTemplates are are a powerful feature in Ext GWT. Prior to 3.0, XTemplates have been implemented using the same design and code as Ext JS. For 3.0, we decided we would like to replace the Ext JS JavaScript-based implementation with a solution more fitting with GWT and the features it offers. This article walks through the details of this redesign and gives some insight into the final design as well as a few code samples.

Ext GWT 2.0

GWT client side code does not support introspection. So given an object, you are not able to get and set values in a generic way. To get around this restriction, there are essentially two ways to deal with this.

First, the target object can implement a known interface that allows values to be retrieved and set. This is the approach we took with Ext GWT with the ModelData interface.

public interface ModelData {
    public <X> X get(String property);
    public Map<String, Object> getProperties();
    public Collection<String> getPropertyNames();
    public <X> X remove(String property);
    public <X> X set(String property, X value);
}

Ext GWT also provides a set of default implementations of the various model interfaces. To meet the requirements of the interface, the data stored within theses classes is stored in a map of values keyed by property name. Although this approach works, it forces users to adapt their data to the model interface or to use the Ext GWT base classes.

The second approach is to use GWT Deferred Binding to generate code at compile time that knows how to “talk” to a given object. This is the approach taken with the Ext GWT BeanModel API which allows Model instances to be created from regular Java Beans. Essentially, all the generic get and set calls are delegated to the wrapped Java Bean.

Ext GWT 3.0

We decided that we wanted to “rethink” the use of our Models and find a cleaner solution. The goal of 3.0 is to support any bean-like object with get and set methods (POJO) or AutoBean (a new GWT feature) anywhere we require data in the framework. This includes our loaders, stores, data widgets, and templates.

Ext GWT 2.0 XTemplates

Templates are powerful as they allow data to be applied to custom HTML fragments. Templates support features such as loop, sub-loops, conditionals, formatting, and many others. In Ext GWT 2.0, templates are implemented using JavaScript from Ext JS. As such, XTemplate expects its data as JavaScriptObjects. So, in order to use XTemplate, the date stored in Ext GWT models must first be converted to JavaScriptObjects. Since the properties and values can be determined, the library provides some utility methods that take the data in Models and creates new JavaScriptObjects with the data given data. This also works with child models and collections. The code that does the conversion does not know what properties it must deal with, so all properties and values are converted. Although this approach works, it does not take advantage of existing GWT features and is a little primitive in its design.

Ext GWT 3.0 XTemplates

In keeping with our 3.0 goals, XTemplates have been completely redesigned. The new XTemplate design uses GWT Deferred Binding to both process the template and generate new code to retrieve the data from any Java Bean. There is no use of Ext GWT Models, which are now replaced, and Java Beans or AutoBeans can be used. Furthermore, there is no need to “convert” the data to a JavaScriptObject. The new design supports virtually all of the old XTemplate features and functionality.

Let’s walk though an example of how the new code works. This example will illustrate the design and features.

The first step is to define an Interface that extends XTemplates. XTemplates is a marker interface that does not define any methods.

interface TemplateTest extends XTemplates {
}

The next step is to define a new method that accepts the data you would like applied to the template and returns a SafeHtml instance. The data can be any Java Bean or AutoBean.

Next, you add an XTemplate annotation to the method. Then, you need to supply the template value as a string. This can be done directly in the annotation or by pointing the annotation to an external file that has the template markup.

interface TemplateTest extends XTemplates {
	@XTemplate("<div><span>{name}</span></div>")
	SafeHtml renderStock(StockProxy stock);
 
	@XTemplate(source="template.html")
	SafeHtml renderStockExternal(StockProxy stock);
}

Next, we create an instance of the XTemplates used GWT.create().

TemplateTest template = GWT.create(TemplateTest.class);

Then we simply invoke our methods to get the results as a SafeHtml instance.

SafeHtml html = template.renderStock(stock);

This markup can then be used as needed. For example:

new HTML(html);

When using setInnerHTML there is the possibility of XSS security hacks. By having our XTemplates return SafeHtml instances, we guard against those types of vulnerabilities.

As with the old XTemplate, the new design supports loops, sub-loops, conditionals, formatting, etc. For example:

Name: {data.name}
Company: {data.company}
Location: {data.location}
Salary: {data.income}
Kids:
<tpl for="data.kids">
<tpl if="age < 100"><p>{#}. {parent.data.name}'s kid - {name} - {bday}</p></tpl>
</tpl>

We have not talked about how the data is retrieved from our models. At compile time, the template is parsed and the data properties names are gathered. Then, new code is generated that essentially “knows” how to retrieve the data from the model. This includes nested properties. The only code that is generated is code that deals with the properties the template uses.

XTemplate Usage

XTemplates can be used on their own, as needed. In addition, many parts of Ext GWT support the use of XTemplates. For example, XTemplates can be used with ListView to control how each item is rendered.

<tpl for=".">'
<div class="x-combo-list-item" qtip="{slogan}" qtitle="State Slogan">{name}</div>'
</tpl>

Summary

In summary, the new XTemplate design is a much improved design over the previous XTemplate. We are leveraging GWT Deferred Binding to provide a GWT like solution. Just as we can use Java Beans with XTemplates, Java Beans can also be used directly in our data store and data loading API.

There are 11 responses. Add yours.

Gary Eberhart

4 years ago

I love this idea. When will GXT 3.0 be available?

Stanislav Spiridonov

4 years ago

Great! What about better documentation for XTemplates? Will be possible to use Widgets/Components into XTemplate?

Robert Schreiber

4 years ago

Hi there,
I had the requirement to integrate Buttons within the items of a ListView.
So I enhanced ListView to work without XTemplates and use real Widgets.
May I contribute somehow?
Best regards from Munich, Robert

Frank Rousseau

4 years ago

Will ModelData be deprecated ? If yes, it would be a bad news, because we heavily use it for ArtForge.
Whatever, good job for the better integration of GWT features !

Gee

4 years ago

What a great friggin idea!

Marcos Ribeiro

4 years ago

When will GXT 3.0 be available?

Darrell Meyer Sencha Employee

4 years ago

We plan to have the first preview release of 3.0 the first week of June and to go final this summer.

@Stanislav Spiridonov
XTemplate will not support inserting widgets. The purpose of XTemplate is to generate static HTML. For inserting widgets, take a look at HtmlContainer which is in 2.X.

@Robert Schreiber
You can post your code in the forums and shoot me the link in a private message.

@Frank Rousseau
Models have been moved to a new legacy module. You will still be able to use models and we will provide some helper classes so you can use them in our new store and loaders.

Stanislav Spiridonov

4 years ago

Ok. I am also using a modified ListView (http://euve11681.server4you.net). But if the GXT will contain some standard component I will use it.

Ice

3 years ago

What a joy to find such clear thinking. Tankhs for posting!

Anton Alexeyev

3 years ago

I have a question about BaseModelData destiny. Will it be supported by GXT 3.0??

Jeanette

3 years ago

I have been so bewilerded in the past but now it all makes sense!

Comments are Gravatar enabled. Your email address will not be shown.

Commenting is not available in this channel entry.