Helma Logo
main list history
previous version  overview  next version

Version 46 by hannes on 30. October 2006, 23:20

== Spec ==

# Macros in skins are delimited by <% %>.
# Macros can contain both named and unnamed parameters, in any combination (see Notes for implementation details).
# Named parameters are denoted as name=value, unnamed parameters are denoted as value.
# The following types are supported as parameter values:
## strings: "foo"
## numbers: 13
## boolean false|true
## object literals: {foo: bar, x: y}
## array literals: [1, 2, "drei"]
# For string values, single or double quotes are optional unless the value contains whitespace characters.
# Round brackets ( ) can be used to group multiple macro parameters into one. (syntactic sugar for arrays?)
# <strike>Macro parameter values wrappedn in {{ }} are interpreted as nested skins.</strike>
# Helma provides native skin scanning/parsing features, but skins and macros are implemented in JavaScript.
# <strike>Nested skins and macros are passed to macros as skin and macro objects, respectively. In other words, macro evaluation and skin rendering is up to the containing macro.</strike>
# Todo: provide a feature for marking subtemplates within a skin file.

Parsed skins are exposed as JavaScript arrays, with the static skin parts represented by string elements, while the macro parts are represented by a MacroTag class. The MacroTag class is itself a JavaScript array, with an additional params property to expose the named parameters.

Consider for example the following skin source:

  image <% img dancer.gif dim={width: 30, height: 120} %>

It is parsed to the following construct:

  [image , [img, dancer.gif]{dim={width=30.0, height=120.0}}]

and the following conditions would evaluate to true:

  skin.length == 2;
  skin[0] == "image ";
  skin[1].length == 2;
  skin[1][0] == "img";
  skin[1][1] == "dancer.gif";
  skin[1].params.dim.width == 30;
  skin[1].params.dim.height == 120;

== Implementation ==

Native template scanning support is implemented in class *org.helma.template.TemplateScanner|Source/file/helma/trunk/src/org/helma/template/TemplateScanner.java*, which can be conveniently accessed using the global parseSkinResource(path) function<b>parseSkin(str)</b> and <b>parseSkinResource(path)</b> functions. It parses skins to a java.util.List filled with Strings for the static parts and Macro tags, which are again java.util.List objects with a special param property that contains the tag's named parameters.

All this is wrapped in *ScriptableLists|helma 2 core reference/scriptableList* and *ScriptableMaps|helma 2 core reference/scriptablemap* so you can sweep through it like it were native JavaScript arrays and objects.

I started a simple JavaScript renderer for skins parsed this way. It currently implements very simplistic if/foreach constructs.

<% this.attachments %>

The following code shows how to use this:

  function handle_get() {
    var t = new Templatex("skins/main.skin");
    t.render({topics: ["Berge", "Taeler", "Seen", "Fluesse"]});

== Examples ==

I removed the old examples since they didn't match the renewed spec anymore. Generally speaking, all kinds of macro syntax can be implemented based on the features discribed in this proposals, as long as they use <% %> as macro delimiters.

== Comments ==

I removed Jürg's comments as well, for the same reason.