Web Oriented Object Framework

User Guide (Version 0.5b4)

Woof!
User Guide (Version 0.5b4)

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.