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
subclasses for numbers. -
Use
java.lang.Boolean
for boolean values. -
Use
java.util.Date
and its subclasses for date/time values -
Use
java.util.List
or Java arrays for sequences. -
Use
java.util.Map
withString
keys for hashes. -
Use your custom bean class for hashes where the items correspond to the bean properties. For example the
price
property (getPrice()
) ofproduct
can be get asproduct.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 = "projects.html" | +- name = "green mouse"
This Java code fragment that builds this data-model:
// Create the root hash. We use a Map here, but it could be a JavaBean too. Map<String, Object> root = new HashMap<>(); // Put string "user" into the root root.put("user", "Big Joe"); // Create the "latestProduct" hash. We use a JavaBean here, but it could be a Map too. Product latest = new Product(); latest.setUrl("projects.html"); latest.setName("green mouse"); // and put it into the root root.put("latestProduct", latest);
As demonstrated above, for hashes (something that stores other
named items) you can use either a Map
or any kind
of public class that has public
getXxx
/isXxx
methods as prescribed by the JavaBeans specification. Like the above
Product
class could be something like:
/** * Product bean; note that it must be a public class! */ public class Product { private String url; private String name; // As per the JavaBeans spec., this defines the "url" bean property // It must be public! public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } // As per the JavaBean spec., this defines the "name" bean property // It must be public! public String getName() { return name; } public void setName(String name) { this.name = name; } }
Regardless if latestProduct
is a
Map
that contains the "name"
and
"url"
keys, or it's a JavaBean as shown above, in
the template you can use ${latestProduct.name}
. The
root itself need not be a Map
either; it could be
an object with getUser()
and
getLastestProduct()
methods too.
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 (something
that implements the TemplateHashModel
interface)
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.