Implementing template processors
A template processor plug-in basically wraps the API provided by
the template processor implementation into the interface expected by Woof!
The plug-in is required to implement a single command with two subcommands
compile and render.
When Woof! processes a template for the first time, it reads it from
the file on the disk and passes it to the
compile command. The output from the command is then passed to the
render command which should return the HTML to be included
in the generated page. Note that returned HTML should be a HTML fragment,
not a whole HTML page.
In effect what the two step sequence does is to allow
template processors to convert a template into an internal form that
is amenable to quicker processing by the rendering step which
then inserts the dynamic data.
In addition, Woof! caches the compiled form of the template since that
does not depend on the dynamic parts of the page. The
next request for the page directly calls the render
command and bypasses
the read from disk and compile steps, resulting in much faster processing.
Note that the template processor compile step should not depend on any dynamic data.
We will illustrate the steps by implementing Markdown support for Woof!
page sections. We will make use of the hoedown package
which implements a Markdown processor.
The required code is shown below.
package require hoedown
namespace eval woof::hoedown {
proc compile {in} {
return [::hoedown::render $in]
}
proc render {in} {
return $in
}
# Create the woof::hoedown command with subcommand compile and render
namespace export compile render
namespace ensemble create
}
[::woof::master::app_interp] alias ::woof::hoedown ::woof::hoedown
The interface is very simple, with all the hard work being implemented
by the hoedown package. As we mentioned previously, Markdown
is a text format and not a template processor and hence does not deal
with dynamic data. Thus the render
command simply returns its input.
Do not confuse the render command of the
hoedown package with our ::woof:hoedown::render
command; they happen to have the same name by coincidence.
We have to now arrange for this code to be loaded. The mechanisms for doing this are detailed in The Woof! interpreter model. We follow the instructions there. The above code fragment is short enough that we can directly save it in the app/app_master.tcl file so it is loaded into the master interpreter. The last line then makes the command available to the application interpreter.
The final step is in arranging our hoedown template
processor to be called for the appropriate files. We describe that next.