# Notes on Templating

## Introduction

This document was turned into a document from some notes by WilliamC. These notes where the basis for TimJ's abstraction of the templating engine and most of the points in this note have been addressed.

### Melati and templates

Melati is an open source, Java-based infrastructure for the rapid and convenient development of web-based database applications. This guide describes how to write Webmacro templates which exploit Melati's facilities for automatic rendering of displays and forms for database fields and records.

### Markup language support

This is what the `*MarkupLanguage` classes do:

#### Text escaping

Escaping ("rendering") of text according to the conventions of the language. In fact there are several different kinds of escaping to be done in HTML, depending on the context:

Doc body, attribute value | `&quot;`
Javascript value | `\042`
URL | `=22`

#### Exception rendering

Rendering of exceptions for display to the user, where the `VariableExceptionHandler` returns them to be displayed rather than simply throwing them out to terminate expansion. Again, this is context-dependent:

Doc body | `<I>error!</I>`
Attribute value (e.g. input box content) | `[error!]`

As of 21/07/2000, the representation of the exception is determined from a sub-template or "templet". The `MarkupLanguage` tries to load a WebMacro template (through the servlet's `Broker`) from a directory named after the markup language. The filename of the template is taken at first to be the package-qualified class name of the exception with `.wm` appended; if that doesn't exist, it tries the superclass, and so on until it finds `java.lang.Exception.wm`, which just does

>     [$ml.rendered($exception.toString())]

The templet is expanded to a string against a specially constructed `Context`, and the string is returned to WebMacro for interpolation into the parent template. It would obviously be nice if the templet could be expanded directly to the output stream, so that the extra buffering could be avoided.

### Smart field handling

#### `Field` rendering

Rendering of POEM `Field`s, i.e. values wrapped up with `PoemType`s, for display. (N.B. do we need a `PoemTypedValue` which is like a `Field` but doesn't have a name? The name isn't needed here, only for rendering input controls.)

The functionality is: compute the field's localised ‘cooked string’ representation; size-limit it; escape it for the doc-body context.

- Exceptions are caught and passed to `VariableExceptionHandler` set up in the expansion context, which can throw them out or return them to be rendered for the doc-body context as above.

- The locale is determined from the Request's `Accept-Language` if present, defaulting to UK if absent.

- There are different variants for calling up `SHORT`, `MEDIUM`, `LONG` and `FULL` styles. This is really intended for use on dates.

- The size limit is generally 10M, and is only meant to prevent out-of-memory errors. There is a variant which limits to 50 chars, for ‘short displays’ such as the admin system browse lists.

#### `Persistent` rendering

Rendering of POEM `Persistent`s, which just means calling up their localised `displayString` and rendering that in the doc-body context.

#### Input control rendering

Rendering of an input box, dropdown, etc. appropriate for entering the value of a POEM `Field`. This has always used a ‘templet’ mechanism similar to that used for exceptions: a markup language-specific directory is searched for a templet named after the `PoemType` of the field, except that the templet name can also be set explicitly in the field's `getRenderInfo` property (ultimately, in the admin interface).

The name of the field is prefixed with `field_` (the prefixing is done in each templet individually, which doesn't seem right). When the returning form is interpreted, `Melati.extractFields` knows to put that prefix on the field names of the `Persistent` into which things are going.

#### General observations

- The decision as to how to render a given object is done in a strangely mixed way. `rendered(Field)` is chosen by WebMacro's introspection mechanism, but everything else falls into `rendered(Object)`, where an `instanceof` dispatch decides what to do. Probably it's best to do everything by the former mechanism (or even better by static method selection according to signature in the case of JTemplater), and disallow the rendering of arbitrary `Object`s using `toString`.

- Probably the display of everything should be delegated to markup language-specific templets, not just `Exception`s and `Field`s.

- ‘What are we rendering’ and ‘what context are we rendering in’ are essentially orthogonal considerations. This is actually handled quite well in the current implementation, where `HTMLMarkupLanguage` will give you an `AttributeHTMLMarkupLanguage` as one of its properties. However, the most tricky situations, such as that in which one is rendering a JavaScript expression containing a value in quotes will which eventually become part of the document body, may not be adequately covered.

## Desirable features for cleaner version

Note all of these suggestions have been implemented.

The idea of making ‘Melati’ essentially a utility object (`$melati`) accessible within templates still seems a good one. However,

- Done -

  It shouldn't care which templating mechanism is being used. The same abstract logic should work with WebMacro and JTemplater.

- Done -

  It should be capable, where possible, of rendering complex objects directly to the output stream rather than returning a string for interpolation.

- Done -

  It should be simpler. There are rather a lot of ‘here's one I found handy once’ methods floating around.

- Done -

  It should make it more obvious how to create a `$melati` object from outside a `MelatiServlet`.

- Done -

  It should bring out more clearly the notions of expansion context and raw/cooked representation.

- Done -

  It should make the ‘current object’ feature a bit more optional. In particular the logical database should probably be configurable in a `.properties` file.

- Done -

  It should make it easy to say ‘make me a dropdown’ without having to know what a `Field` is.

Generalising from that last point,

- It should have a three-level stack of methods for value and input-control rendering, operating at the level of the `Persistent`, the `Field` and entirely non-POEM objects. These should be isolated into separate classes so that the templets mechanism can be compiled independently of POEM.

## About this document

### Readership and purpose

- Page authors should understand how to use Melati's templating facilities and how they fit in to its broader contex.

This document is also intended to give the wider open source community an insight into Melati, so that they can give us feedback pre-release and evaluate the finished product in an informed manner.

### History

The CVS log for this document is:
$Log: Templating.html,v $
Revision 1.1 2005/11/21 22:01:49 timp
Moved from site/doc
Revision 1.9 2003/07/11 23:47:41 timp
remove a few broken links
Revision 1.8 2003/04/15 02:26:39 jimw
Largely cosmetic fixes
Revision 1.7 2002/12/13 01:12:06 timp
Auto save prior to moving