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.