DocMacros
Introduction [edit section]
TBWiki supports two kinds of extension mechanisms: "macros" and "processors".There are a few builtin macros, but add-on macros and processors can be created and are "run" when a page is parsed and sent by TBWiki.
The function of both of these extension mechanisms (or plugins) is to allow for dynamic creation of page content at the time a page is read by a user. Thus, these act like a kind of embedded CGI-script inside of the TBWiki framework.
Name and Location [edit section]
By convention, the name of a macro is in CamelCase (words strung together with the first letter of each word capitalized).Plugin macros are placed in the data/plugin directory. They are python files and must have a filename starting with the "Macro", then the macro name, and ending in the extension ".py". For example the "Foo" macro would have the path and filename
<data_dir_for_this_wiki>/plugin/MacroFoo.py
Often, the plugin directory will merely be a symlink to the main plugin
directory offered by the tbwiki engine (e.g. at <tbwiki_dir>/cgi-bin/plugins
)
Declaration in a TBWiki Page [edit section]
A macro is declared on a tbwiki page on a single line with the syntax:{{Foo}}
The macro name in the declaration must match the
name part of the filename for the macro python module
in the plugin directory. Thus, the macro "Foo" above would
invoke code in the plugins/MacroFoo.py
module.
Macro arguments (if any) can be specified in the macro declaration, using parenthesis, like so:
{{Foo(arg1, arg2, etc.)}}
TBwiki delivers the arguments as a single string, consisting of exactly the characters inside the parens. Parsing this string into separate arguments (e.g. splitting it on comma, and eliminating white space) are performed by the macro itself.
Note that macros can be declared on a line by themselves, or embedded inline along with other markup, like so:
This is a line with an embedded {{Foo(arg1)}} macro
Interface from TBWiki to the macro [edit section]
A macro must be an importable python module, with some specifically-named function definitions. The TBWiki calls functions in the macro to perform actions, usually resulting in the transformation or creation of new content that will be returned to the user as part of the page where the macro is declared.
main() function [edit section]
A macro must define a function named "main". As a page is rendered by TBWiki, when the macro declaration is encountered in the wiki page, TBWiki calls the 'main' function to invoke the macro functionality.
This main
function takes two arguments, which are
the request object and the args string.
The macro performs its operation, possibly using the information and functions provided in the request object and its argument string, and returns a string of HTML data, for output as part of the returned page.
Example main() [edit section]
Here is an example definition ofmain()
for a hypothetical macro called MacroError.py
:
def main(req, args=""): # do something with args msg = "Error: " + args req.debug_log(msg) html = req.html_error(msg) return html
In this case, the macro creates an error message by
prepending the string "Error:" to the macro argument.
Then it logs the error to the debug log,
and calls html_error()
function to color the indicated text
red, and returns the transformed string to TBWiki for inclusion
on the page.
Example declaration (of Error macro) [edit section]
The exampleError
macro might be invoked like so:
The following text should be red: {{Error(what happened!!)}} Back to normal.
The text of the macro declaration on a page is replaced with the result of executing the macro code, when the page is rendered.
This might result in the following line appearing on the page:
The following text should be red: Error: what happened!! Back to normal.
If no arguments are provided in the macro declaration, like this:
{{Error}}
then the value of the "args" argument to main()
will be the empty string.
help() and help_oneline() actions [edit section]
If a macro defines the special functions "help" and "help_oneline", then the system can provide online help for the processor, from a page displaying the SystemInfo. This function is accessed via a URL with the name: <page_url>?action=<macro_name>.helpThe 'help' function should return text in html format with helpful information about the macro. The 'help_oneline' function should return a single-line description of the processor.
macro side effects or operations [edit section]
Often, a macro is used to place newly-created or transformed content onto a page, during rendering. But it may also be used to perform some operation, such as logging, counting items, or performing some processing on the wiki or the site where it resides.For more complicated processing, consider using a "processor" instead of a macro. See DocProcessors.
Interface from the macro to TBWiki [edit section]
request object [edit section]
The request object has all the data available to tbwiki about the request for this page. This includes the page_name, the entire tbwiki config, and other stuff.Here are some functions and fields that a macro might use:
req functions [edit section]
Some useful functions of the request object are:- req.read_page(page_name) - read a page of the wiki
- req.form = the CGI form data for the request (in the format provided by the python cgi module)
- req.add_to_message = a function to add to the status message for the page. This is often used for debugging purposes, since it appears separately from the page content
- req.page_filename = filename (including full path) of the requested page
- req.page_name = name of the requested page
- req.config.data_dir = location in the local file system where the data pages are located.
- req.config = configuration settings for this wiki
- req.data = data values (and data value functions) for this wiki
- req.data.version - version of the tbwiki engine
- req.data.asctime - current time in ascii (human readable) format
- req.block_to_html - convert a block of text from tbwiki markup to HTML
tbwiki functions [edit section]
You can also import the tbwiki_engine module, to access other helper functions for use by the macro plugin. Here are some that are helpful:- tbwiki_engine.make_url()
- tbiki_engine.html_error()
- tbiki_engine.parse_state = state used for processing lines during page parsing
- tbiki_engine.show_line() = function used to parse a line of TBWIKI-format text and convert it into HTML output (which is printed by show_line)
return value [edit section]
The 'main function should return a single string consisting of HTML to be output as part of the returned page HTML.
If you want tbwiki to process markup text for you into HTML,
you can call req.block_to_html(content)
, and return the
result of that.
Basic Sample - 'Include' macro [edit section]
Here is sample code for a very simple macro which includes the content of another wiki page in the rendered output for the page with the macro.
macro code [edit section]
This would be in the file MacroInclude.pyimport tbwiki_engine def main(req, args=""): page_name = args[0] page_data = req.read_page(page_name) html = tbwiki_engine.block_to_html(req, page_data) html += tbwiki_engine.html_close(req.state) return html
processor invocation [edit section]
To use this processor, a user would place the following on a page:
{{Include(other_page)}}
Assuming the entire page containing the macro looked like this:
This is data from the page. {{Include(other_page)}} This is more data from the first page.
And assuming 'other_page' had this content:
This is content from other_page.
macro result [edit section]
Here is what the resulting output would look like on the page:
This is data from the page. This is content from other_page. This is more data from the first page.