Monday, 19 November 2012

XQuery templating engines and TXQ

"...separating logic from presentation" is good thing; and you don`t need much presentation before code can start looking a bit messy. Here is an example of mine at about the limit of what I feel comfortable with.

Landscape

I have been using Node.js a bit recently and it has an impressive list of  templating engines. One of the things I like about  Node is the module ecosystem; where vast numbers of different  approaches compete in  Darwinian fashion for "developer mind share". For reasons that I can't quite remember, I ended up using EJS with custom delimiters of single { and }. It looks a bit like XQuery.

When it comes to XQuery there are not so many choices :-). Maybe most are mentioned in this thread: eXist MVC and separating XHTML templates from XQuery code More recently eXistdb has Exist html templates. This looks to be standard XQuery 3.0 and provide a lot of high level functionality, but very much linked into the eXistdb environment.

What the world needs now is...

.. another XQuery templating system. So from my experience with EJS and express.js.  Some features that I liked are:
  • A render method to take a view and a map type object to produce a page
  • A location, a collection or folder, for templates (views) completely separated from the code.
  • A quick syntax to wrap common page features  around rendered results.
  • A block/partial/repeat type concept for list/tables.
 Looking for the simplest thing that might possibly  work..Noting that:
  1. A XML document is a valid XQuery program.
  2. If we put some {$var} type expressions in it and get XQuery to evaluate it  in the right context-  we are almost there.
  3. BaseX has a (non-standard) function xquery:invoke that has just the right signature.
The start.. With this view1.xml template Invoking..
Layout pages use the convention that a layout template has a $body field into which the sub template will be inserted
Example layout template. Invoking
Often there is a need to render repeated items from some node collection. A solution to this repeatedly invoke a sub-template, injecting a map with an item set to each node in turn. For example our map has a "actions" value. An XML node with a variable number of <generate> sub nodes that we wish to render.
The actions1.xml partial template.
A slight addition to the original render function makes this easy. Below shows the the full TXQ module.

1 comment:

  1. Due to changes in BaseX's handling of external variables this no longer works exactly as described. See
    https://mailman.uni-konstanz.de/pipermail/basex-talk/2014-October/007490.html

    ReplyDelete