image

RubyFrontier Documentation

Filters

At four points during the rendering process, RubyFrontier stops and turns control over to you, so that you can modify the outcome of the process. It does this via four “filter” scripts: the FirstFilter, the PageFilter, the PostMacroFilter, and the FinalFilter. These scripts are .rb files which, if they exist, will be sought in a #filters folder.

The idea is to provide you with “hooks” or “callbacks” at key moments so that you can insert your own functionality into the rendering process.

The FirstFilter

After the initial building of the page table, and before the page object itself has been examined, if there is a #filters folder and it has a firstFilter.rb file in it, we call that file’s top-level firstFilter() method with one parameter — the page table.

I don’t use this feature in any of my sites, so it’s a little hard for me to suggest what you might use it for; but it’s a Frontier feature so RubyFrontier does it. I imagine you might use this moment to manipulate the directive contents of the page table in some tricky way. For example, you could set the :siterootfolder dynamically if you didn’t want to use the static :folder entry of #ftpsite.yaml.

The PageFilter

Just before we locate the template and insert the page object into it, if there is a #filters folder and it has a pageFilter.rb file in it, we call that file’s top-level pageFilter() method with one parameter — the page table.

This is your chance to modify the page table’s :bodytext entry, which contains the rendered page object, not yet poured into its template, and with macros not yet processed nor glossary expansion yet performed.

In my own sites, for example, this is the point at which I would pass a Markdown text page object through Markdown to turn it into HTML. There are various reasons why this is the correct moment for such a transformation. For example, Markdown lets me express a link like [this](link). When we get to glossary expansion, that link needs to have been re-expressed in the form expected by RubyFrontier, namely like <a href="link">this<a>. So clearly Markdown transformation needs to precede glossary expansion.

The PostMacroFilter

Just after macro processing, if there is a #filters folder and it has a postMacroFilter.rb file in it, we call that file’s top-level postMacroFilter() method with one parameter — the page table.

This is your chance to modify the page table’s :postmacrotext entry, which contains the rendered page object, poured into its template and with macros already processed, but with glossary expansion not yet performed.

This filter, which did not exist in the original Frontier, is implemented because this turns out to be a good moment for certain transformations. For example, if you’re going to use something like kramdown, instead of Markdown and SmartyPants, this is a good moment for it; kramdown transformation needs to occur before glossary expansion (for the same reasons as Markdown), but it behaves badly with unprocessed macros. (Indeed, if Markdown were capable of operating inside <div> tags, such as might be wrapped around the page content by the template, I’d run Markdown, and probably SmartyPants, at this point instead of the PageFilter.)

The FinalFilter

At the very end of the rendering process, just before we write the completely rendered HTML out to disk, if there is a #filters folder and it has a finalFilter.rb file in it, we call that file’s top-level finalFilter() method with one parameter — the page table.

This is your chance to modify the page table’s :renderedtext entry, which contains the completely rendered page object, ready to write out to disk.

In my own sites, for example, this is the point at which I might run SmartyPants to turn the page’s quotation marks into smart quotes. Why do I wait until the last moment to do this? Well, for one thing, it isn’t necessary to do it any earlier. For another, events such as macro processing and even insertion of the title into the page header may generate text that SmartyPants needs to deal with, so clearly it makes sense for SmartPants to come into play later than these events.

Another use of the FinalFilter might be to pass the page through an XSL transform. I do this in some sites in order to give each page a table of contents, for example.

The Extra Parameter

Although I have said that every filter is called with a single parameter, the page table, in actual fact if you are a power-user you might define a filter method to take two parameters, in which case the second parameter will be the PageMaker object. Filter scripts are not called with macro scoping, so this second parameter provides an easy way for a filter script to call PageMaker methods.

Next: The Page Header and Page Footer

This documentation prepared by Matt Neuburg, phd = matt at tidbits dot com (http://www.apeth.net/matt/), using RubyFrontier.
Download RubyFrontier from GitHub.