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()
) 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 = "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.
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.