FrontPage 

TB Wiki

Login

DocMacros in split format

= Introduction = TBWiki supports two kinds of extension mechanisms: "macros" and "processors".
{{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.
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.
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]

= 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
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)
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]

= 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.
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.)}} }}}
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.
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 }}}
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]

= 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 [edit section]

== 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.
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.
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]

=== 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
}}}
{{{
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.
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]

=== 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 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.
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:
This might result in the following line appearing on the page:
The following text should be red: Error: what happened!! Back to normal.
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}} }}}
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.
then the value of the "args" argument to ``main()`` will be the empty string.

help() and help_oneline() actions [edit section]

== 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.
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 [edit section]

== 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.
For more complicated processing, consider using a "processor"
instead of a macro.  See [[DocProcessors]].

Interface from the macro to TBWiki [edit section]

= 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:
Here are some functions and fields that a macro might use:

req functions [edit section]

== 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
 * 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]

== 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 [edit section]

== 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.
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]

= 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 [edit section]

== 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)
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 }}}
    html = tbwiki_engine.block_to_html(req, page_data)
    html += tbwiki_engine.html_close(req.state)
    return html
}}}

processor invocation [edit section]

== processor invocation ==
To use this processor, a user would place the following on a page:
{{Include(other_page)}}
}}}
{{{
{{Include(other_page)}}
}}}
Assuming the entire page containing the macro looked like this:
Assuming the entire page containing the macro looked like this:
{{{#!YellowBox
This is data from the page.
Error getting item 'other_page' using Include() macro: Page other_page not found in parse_item_ref
{{Include(other_page)}}
This is more data from the first page. }}}
This is more data from the first page.
}}}
And assuming 'other_page' had this content:
And assuming 'other_page' had this content:
{{{#!YellowBox
This is content from other_page.
}}}

macro result [edit section]

== 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 content from other_page.
This is more data from the first page. }}}
This is more data from the first page.
}}}
TBWiki engine 1.9.2 by Tim Bird