This is an AMP version of the article, its original content can be found here.
XML Data and XSL Views in Takes Framework
A year ago, I tried to explain how effectively data and its presentation can be separated in a web application with the help of XML and XSL. In a few words, instead of using templating (like JSP, Velocity, FreeMarker, etc.) and injection of data into HTML, we compose them in the form of an XML document and then let the XSL stylesheet transform them into HTML. Here is a brief example of how all this can be used together with the Takes framework.
First, let's agree that templating is a bad idea in the first place. Yes, I mean
it. The entire design of JSP is wrong, with all due respect to its creators.
Here is how it works: Let's say my website has to fetch the current exchange rate of
the euro from a database and show it on the home page. Here's how my
In order to create HTML, the JSP engine will have to call
get() on object
rates and render what's returned through
toString(). It's a terrible
design for a few reasons. First, the view is tightly coupled with the model.
Second, the flexibility of rendering is very limited. Third, the result of
rendering is not reusable, and views are not stackable. There are many other
reasons ... more about them in one of the next articles.
Let's see how this should be done right. First, we let our model generate the output in XML format, for example:
This is what the model will produce, having no knowledge of the view. Then, we create the view as an XSL stylesheet, which will transform XML into HTML:
As you see, the view doesn't know anything about the model in terms of implementation. All it knows is the format of XML data output produced by the model. Here is how you design it in the Takes framework. Let's start with a simple example:
It's a simple web application that starts a web server
and never ends (it waits for connections in daemon mode). To make it work,
we should create a simple "take" named
This "take" always returns the same XML response, but it doesn't
do any XSL transformation yet. We need to add the
RsXSLT class to the picture:
Excuse me for using string concatenation, which is a bad practice; it's merely for the simplicity of the example.
As you see, I also added an XML stylesheet processing instruction to
RsXSLT will understand it and try to find the
resource on classpath. You see the content of that file above.
Well, not really. Building XML from strings is not a good idea. We have a better instrument in the Takes framework. We use Xembly, which is a simple imperative language for building and modifying XML documents. More about it here: Xembly, an Assembly for XML.
Here is how our
TkApp would look:
The most important class here is
The idea is to let
model classes expose their data through Xembly "directives," which
will later be applied to a DOM structure by
directives but with different meanings
(they are all instances of an
Their names describe their
intentions rather well.
just chains everything that is
delivered by encapsulated "directive sources."
returns directives that create a single XML processing instruction.
creates an XML node and adds encapsulated directives to it.
simply returns what's inside.
In the end, this code will create exactly the same XML document as I created above with string concatenation.
The beauty of this approach is in the perfect decoupling of data generation and XML building and translation between XML and HTML. It is perfectly reusable and "stackable." We can transform the data in XML format multiple times, applying different XSL stylesheets to each one. We can even transform them into JSON without changing a line of code in model classes.
Moreover, we can format them differently, using rather powerful XSLT 2.0 instruments. XSLT by itself is a powerful and purely functional language that enables any possible data manipulations. No templating engine is even close to it.
Take a look at how it works in the
class in Rultor, for example.