Domplate variables and variable formatters
September 10, 2008
Posted in Domplate, JavaScript

I have more domplate goodness for you. First of all keep in mind that domplate only works in Firefox right now. I will be making it cross-browser soon! Also, it requires some plumbing code if used outside of Firebug that I will be removing as well.

This post is about the variable substitution and variable formatter functionality in domplate. I will start by showing you what you can do with the domplate implementation that is shipped with Firebug and then tell you about a little enhancement I made on my own copy.

Lets take a look at the following template taken from here. To run this locally you will also need this copy of domplate.

TABLE(
  TBODY(
    TR(
      TH({'style':'background-color: gray;'},
         'Names')
    ),
    FOR('row','$people|getRows',
      TR(
        TD({'style':'background-color: $row.color'},
           'Hello $row.name|formatName')
      )
    )
  )
)

As you can see, a domplate template is simply a set of nested function calls where the function name represents the HTML tag except for some special functions like FOR. The first argument contains any HTML attributes you want to add and the remaining arguments further tags or the actual content that is to reside within the tag.

Variables

You will notice that there are a number of variables in the basic form of $var. Variables in domplate work just like they do in javascript although only printing of object variables is supported. Arrays are supported for passing data to formatters (more on that later), but they cannot be printed as the array items cannot be accessed directly.

Variables have scope. When a template executes all variables passed to domplate from your calling code will be present by default throughout the entire template. In the example above the FOR loop will create its own sub-scope with its own variables. These variables are only accessible from within the FOR loop and are not available after the for loop as exited.

You can access properties of objects stored in the variables via the dot syntax. The $row.name variable accesses the name property of the row object.

A variable is recognized as such if it begins with a $ and ends with a space, comma or pipe (more on the comma and pipe later). The first character after the $ may not be numeric (just like in javascript) and any alphanumeric characters including underscore and period and valid thereafter.

$var1
$var1.prop1
$var1 Hello
Hello$var1

You can print any number of variables embedded into the tag content.

Variable Formatters

Variables are great and essential in a template system, but domplate really shines in its support for variable formatters. A variable formatter is a function callback that allows you to call a function defined within your template object and pass along a template variable. The task of the function is to format the variable and return it to be printed, used in special functions like FOR or piped to another formatter.

To define a formatter simply append |func to the end of a variable. This will pipe the variable to the function called func which means that it will pass the variable to the function as the first and only argument.

In the above example $row.name|formatName will pass the $row.name variable to the formatName function and the result will be printed inline. Similarly $people|getRows will pass the $people variable to the getRows function and the result will be used to iterate over in the FOR loop.

You can chain multiple formatters to a variable by appending more than one |func to it. It will pass the specified variable to the first function and the result to the second function and so on. Think of it like unix pipes. Hence the use of the | character. You can pipe the result of one formatter to another.

$var|func
$var|func1|func2

The FOR loop

While we are at it lets examine the FOR loop a bit closer. I will have further posts about other built-in functions in future.

The FOR function is a built-in template function that iterates over a list of values by repeating its sub-template for every entry in an indexed array. Each array value can be a simple string, integer or an object containing one or more properties where a property can contain further nested objects.

FOR('row','$people|getRows',
  ...
)

This FOR loop will iterate over the array returned by the getRows formatter. The formatter in turn is taking in the $people variable as its source of data. This setup allows you to iterate over any variable as long as the formatter knows how to interpret it in order to return a list of values to the FOR loop.

As the loop steps through the array, each value is assigned to a variable called row. You can access it via $row and if your array values are objects you can use the dot syntax to get the object properties such as $row.name. As mentioned above the $row variable has limited scope and is only available from within the loop.

You can nest FOR loops and supply a variable without a formatter as the data for the loop as long as it is already an indexed array of values.

Passing multiple variables to a formatter

If you use formatters in their basic form which is to format variables for display you will usually only need to pass one variable to it. Even if you need to be able to customize a formatter dynamically you can register a variable on the template object which the formatter can access.

There are cases however where you don’t want to pollute the template object with such variables or you need more flexibility in your templates especially if they are nested and/or inherit and customize other templates. It is also useful if you need to combine two variables in a formatter that will be used to feed a FOR loop.

This is where my little enhancement comes in handy.

$var1,$var2|func
$var1,$var2,$var3|func1|func2

It allows you to pass two or more variables to a formatter while still being able to chain formatters. Simply separate each variable with a comma to assemble a list of variables to be piped to the first formatter as function arguments in corresponding order.

function func(var1,var2) {
}

Do not include any spaces in this list or the variables will be treated separately. The second formatter will simply receive the result of the first as its only argument.

Note that this feature is only available in my copy of domplate and not supported by Firebug at this point. You can see an example of it here. You need to download it along with the domplate code to run it.

Enjoy! If you have any questions post them here.

1 Comment
alvaro
September 27, 2008

Nice tutorial :)

Comments are closed.
Linkbacks