Create a data-model

In simple cases you can build data-models using java.lang and java.util classes and custom JavaBeans:

  • Use java.lang.String for strings.

  • Use java.lang.Number descents for numbers.

  • Use java.lang.Boolean for boolean values.

  • Use java.util.List or Java arrays for sequences.

  • Use java.util.Map for hashes.

  • Use your custom bean class for hashes where the items correspond to the bean properties. For example the price property (getProperty()) of product can be get as product.price. (The actions of the beans can be exposed as well; see much later here)

For example, let's build the data-model of the first example of the Template Author's Guide. For convenience, here it is again:

(root)
  |
  +- user = "Big Joe"
  |
  +- latestProduct
      |
      +- url = "products/greenmouse.html"
      |
      +- name = "green mouse"

This Java code fragment that builds this data-model:

// Create the root hash
Map<String, Object> root = new HashMap<>();
// Put string ``user'' into the root
root.put("user", "Big Joe");
// Create the hash for ``latestProduct''
Map<String, Object> latest = new HashMap<>();
// and put it into the root
root.put("latestProduct", latest);
// put ``url'' and ``name'' into latest
latest.put("url", "products/greenmouse.html");
latest.put("name", "green mouse");

In real applications, instead of Map-s, you will often use application-specific classes that has getXxx/isXxx methods as prescribed by the JavaBeans specification. Like you have a class similar to this:

public class Product {

    private String url;
    private String name;
    ...
    
    // As per the JavaBeans spec., this defines the "url" bean property
    public String getUrl() {
        return url;
    }
    
    // As per the JavaBean spec., this defines the "name" bean property
    public String getName() {
        return name;
    }
    
    ...
    
}

and you add an instance of it to the data-model somehow like this:

Product latestProducts = getLatestProductFromDatabaseOrSomething();
root.put("latestProduct", latestProduct);

The template will be the same as if latestProduct was a Map, like ${latestProduct.name} works in both cases.

The root itself need not be a Map either. It could be an object with getUser() and getLastestProduct() methods too.

Note:

The behavior described here only stands if the value of the object_wrapper configuration setting is something that's used in almost all real world setups anyway. Anything that the ObjectWrapper wraps to be a hash can be used as the root, and can be traversed in templates with the dot and [] operators. Something that it doesn't wrap to be a hash can't be used as the root or be traversed like that.