★ Report generation: more about templates
posted Mon 12 Feb 2007 by Michael Galloy under IDL, ObjectsTemplates 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:
template = obj_new('MGffTemplate', 'report.tt')
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:
<h1>Results for [% dir %]</h1>
Also, arbitrary IDL expressions can put their results into the output as well:
Reported on [% systime() %]
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
,
[% INCLUDE footer %]
puts the contents of footer.tt (since that is stored in the footer
variable), into the output. So Output produced by MGffTemplate
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,
<p>[% INCLUDE_TEMPLATE header %]</p>
<p>The header variable is set to header.tt which is:</p>
<h1>Results for [% dir %]</h1>
<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:
imageInfo = { filename: '', $
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:
<p>[% FOREACH f IN files %]</p>
<h2>[% f.filename %]</h2>
<table class="[% f.type %]">
<tbody>
<tr>
<td>Number of bands</td>
<td>[% f.channels %]</td>
</tr>
<tr>
<td>Type</td>
<td>[% strlowcase(f.type) %]</td>
</tr>
</tbody>
</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.
August 28th, 2009 at 12:23 pm
[…] these previous posts about the template class. No Comments […]