BTL, or Bean Transformation Language, is a template language that transforms JavaBean input into documents in numerous formats, such as XML, HTML, XHTML, XSL-FO, RTF or PDF (see Figure 1).
BTL can be thought of as a mix of JSTL and XSLT. It combines the XML/output-oriented features of XSLT with JavaBean-oriented tags of JSTL. In BTL, you will find most of the XSLT constructs fused with those from JSTL.
JavaBean and template part of the schema in Figure 1 are rather common components of any template language. What separates BTL from other languages is presence of the renderer layer. This layer is responsible for adopting BTL output to the target format, much like output methods do in XSLT.
Below is the list of problems that BTL strives to solve. Most of the solutions are borrowed from the XSLT and adopted to work in the Java environment.
In HTML it's normally the responsibility of developer/designer
to remember which tags should be left open (<br>
,
<img>
), which should be closed
(<script></script>
) and which can be
optionally left open (<li>
).
In reality, it's pretty hard to remember all these rules, and it's
also hard to validate them.
As a result output is very error-prone.
XSLT has a very simple solution to this problem: since the output
is XML, all tags must be closed and it's the responsibility of the
output method (renderer) to ensure the valid output of these tags
(see XSLT spec for more info).
XML standard also takes care of the special characters and other
output format specifics.
Just like XSLT, BTL template is an XML document, which guarantees
that the output will be at least well-formed.
Most of the template engines support "${bean.value}
"-like
constructs.
Unfortunately, in majority of cases when this command is used, users
have to remember to escape result value for XML/HTML formats, i.e.
to replace occurrences of "&", "<" and ">" with their escape
sequences ("&" "<" and ">").
Often, different languages have different ways of handling such characters.
For instance, in FreeMarker
this expression will look like "${bean.value?html}
", in
Velocity, it'll be something
similar to "${escapeXml(bean.value)}
", etc.
The problem is that in either case, the developer/designer has to use
these expressions, which can be very error-prone and hard to debug.
Again, XSLT has a very elegant solution to this problem adopted by BTL;
you don't have to worry about character escaping - it's the responsibility
of the renderer.
Handling whitespace is often unnecessarily problematic.
Whitespaces are important for proper rendering and force
developers/designers to either lump instruction on the same line or
use special whitespace-control instructions ("<#t>
"
in FreeMarker, etc).
BTL borrows XSLT whitespace rules whereby all whitespaces b/w any two
tags (closing or opening, instructions or output) are ignored.
Following this simple rule, you won't have to worry about escapes in
the majority of the cases.
Some time in the future we'll all be using XHTML instead of HTML. Currently it's a rather work-intensive and error-prone process to switch from one format to the other. This problem is resolved in XSLT by using output methods, in which switching b/w HTML and XHTML is a simple change in the configuration. BTL renderers follow the same pattern.
Customizing output of subtypes of a particular super-type is a very
common development issue.
Unfortunately, in traditional template languages such customization
would necessitate the use of multi-story "if/switch
"
statements, which are hard to extend and maintain.
XSLT provides the "xsl:apply-templates
" instruction to
address such issues by matching templates to the subtypes using
expressions.
BTL borrows the same idea for its "match-macro/apply
"
instructions.