Templates are tools for creating text output reports. The beauty of templates is that they allow a separation of the code that generates/calculates information from the code that produces the output. The template code produces the output and is done in plain text in the type of output desired with a few directives that are used to insert the real information, check conditions, do loops, include other files, etc. This article will demonstrate more features than my original post about templates. The demo program mg_report_demo.pro (docs) uses three templates to create its output: the main template, the header, and the footer.
The files needed to use the template are the MGffTemplate class (docs) and the MGffTokenizer class (docs).
Using the template object is simply a matter of instantiating an MGffTemplate object that uses a template file, in this case report.tt; create a a structure of variables; and call the process method with the structure of variables. In MG_REPORT_DEMO this is done with:
variables = { dir: myDir, $
files: infoArray, $
header: 'header.tt', $
footer: 'footer.tt' $
}
template->process, variables, 'report.html'
obj_destroy, template
The fields of the structure variables will be variables accessible in the template via directives. Directives are enclosed between squares brackets and the percent sign. For example, the myDir field can be included in the output by:
Also, arbitrary IDL expressions can put their results into the output as well:
There are also directives to include output from other files. The "include" directive simply copies the contents of the file into the output, no processing is done. So the following snippet in report.tt,
puts the contents of footer.tt (since that is stored in the footer variable), into the output. So
is copied directly and any directives in it would be ignored (just copied verbatim). To process the file as another template, passing the variables structure to it and processing its directives, use the "include_template" directive. Here,
The header variable is set to header.tt which is:
<p class="date">Reported on [% systime() %]</p>
The last directive demonstrated is the "foreach" directive which loops through an array. Any array can be used, but an array of structures is particularly useful. The files field of the variables structure is an array of structures of the form:
channels: 0L, $
dimensions: lonarr(2), $
has_palette: 0L, $
num_images: 0L, $
image_index: 0L, $
pixel_type: 0L, $
type: '' $
}
The following (partial snippet) code accesses the various fields of each element of the files array in turn:
<table class="[% f.type %]">
<tr>
<td>Number of bands</td>
<td>[% f.channels %]</td>
</tr>
<tr>
<td>Type</td>
<td>[% strlowcase(f.type) %]</td>
</tr>
</table>
[% END %]
See report.tt for the full loop.
This example used HTML output, but that is not required. Any text can be output, i.e. XML, TeX, etc.

April 6th, 2007 at 10:11 am
Sweet!
I created alot of IDL code to provide text and HTML output for reports from my coding projects. Your template object class works great by providing a much simpler way of creating professional looking output and saving me a lot of time.
Although, your template examples didn’t produce the same results as your results, it was a good exercise in HTML and CSS in getting the templates to produce the desired results.
I use your documentation utility (IDLdoc) all the time and hope to apply your unit testing framework to some of my work.
Keep up the good work.
Kelly Dean
Fort Collins, CO
April 6th, 2007 at 10:27 am
Thanks for the feedback!
I’ll look at the results to make sure they match up.
I have some code that I will be releasing shortly that will extend the templates to objects (in place of the structures) that will allow for more representation of arbitrary hierarchical data.
I also have some additions to the unit testing framework to allow for fixtures (setup/teardown before/after each test is run). Look for that soon too.