DocMacros in 'raw' format
{{TableOfContents}} = Introduction = 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 = 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 = 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 = 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 == 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() === Here is an example definition of ``main()`` 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) === The example ``Error`` 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: {{HTML(<font color="red">)}}Error: what happened!! {{HTML(</font>)}} 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 == 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>.help The '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 == 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 = == request object == 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 == 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 = 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 == 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 = 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 == This would be in the file MacroInclude.py {{{ import 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 == 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: {{{#!YellowBox This is data from the page. {{Include(other_page)}} This is more data from the first page. }}} And assuming 'other_page' had this content: {{{#!YellowBox This is content from other_page. }}} == macro result == Here is what the resulting output would look like on the page: {{{#!YellowBox This is data from the page. This is content from other_page. This is more data from the first page. }}}