WikklyText Plugins
The Plugin API allows you to extend the functionality of WikklyText in several ways:
- You can add new macros than can be called from wikitexts as <<mymacro ..>> (link)
- You can add functions that appear in the namespace of <?py code embedded in wikitexts. (link)
- You can attach extra styling information (CSS) to the rendered document (link)
Click a link for more, or read on for full details.
Creating new macros
Macros are ordinary Python functions with the following calling sequence:
def mymacro(context, ...):
...
Where
context is a
WikContext (
ref: wikklytext.base) and the remainder of the args are passed from the macro call. For example:
<<mymacro 123 456 "abc">>
Would call:
def mymacro(context, a, b, c):
# a.text = "123"
# b.text = "456"
# c.text = "abc"
Note that each passed argument is an
Element so you use
.text to get the text portion. (
More general macros might want to deal with arbitrary ElementTrees as arguments, but text args are the simplest and most common.)
Macros can return any of the following:
- An Element
- A unicode string
- A byte-string
- A list/tuple of any of the above types.
Here is what a typical plugin looks like. Let's assume:
- My plugin is named myplugin.
- I'm defining two macros that are safe for anyone to call named happy and nice.
- I'm defining two macros that only trusted users are allowed to call named evil and bad.
My
__init__.py would look like this:
plugins/myplugin/__init__.py
__safe__ = ['happy', 'nice']
__unsafe = ['evil', 'bad']
def happy(context, ...):
...
def nice(context, ...):
...
.. etc. ..
(
In a real plugin, you'd probably split your code up into multiple files. The above example shows all code being placed in __init__.py for simplicity.)
Creating embedded functions
Embedded functions are ordinary Python functions that are available by default in the global namespace of embedded Python code (
<?py). They
do not get a
context arg, and are called like any other function (and may return any value).
To add functions to the embedded namespace, add their names to the
__embed__ list at the top of your module (similar to
__safe__ and
__unsafe___ above).
Adding styling (CSS) information
You might find yourself defining new CSS classes as part of your macros. While it is certainly possible to tell your macro users to add your new styles to their wiki
StyleSheet, it is much more convenient to provide the classes automatically.
To do this, simply define a module level variable
__css__ that is a string with the styling information to be added to the document
<HEAD>. For example:
__css__ = '''
div.myclass1 {
color: red;
}
'''
The string will be added to a
<style> tag when creating the HTML document.
A simple example
Here is a simple complete example:
- First, create a folder hello under plugins/ in your wiki folder.
- Create a file plugins/hello/__init__.py
'''
This is just like any other Python package where you have __init__.py
defining the interface.
__init__ may define any/all/none of: __embed__, __safe__ and __unsafe__.
'''
__embed__ = ['hello_embedded']
__safe__ = ['hello_safe', 'hello_box']
__unsafe__ = ['hello_unsafe']
__css__ = '''
div.hellobox {
background: yellow;
color: black;
border: 3px solid blue;
padding-left: 3em;
}'''
'''
For real code you'd probably split these functions into their
own files and just import them here.
'''
def hello_safe(context, msg):
return "Hello safe, message=%s" % msg.text
def hello_unsafe(context, msg):
return "Hello unsafe, message=%s" % msg.text
def hello_box(context, msg):
"A slightly more complex example ..."
from wikklytext.plugapi import DIV, Text, eval_wiki_text
d = DIV('hellobox')
d.append(eval_wiki_text(context, msg.text))
return d
def hello_embedded(msg):
return "Hello Embedded, message=%s" % msg.text
- Finally, create a new wiki item with this text:
<?py
def hello(context, msg):
return hello_embedded(msg) # auto-added to embedded namespace
?>
/% Minimal example, showing how args are passed. %/
!!!From ''<$py''
<<hello "Embedded message!">>
!!!From ''<nowiki><<hello_safe>></nowiki>''
<<hello_safe "Safe message!">>
!!!From ''<nowiki><<hello_unsafe>></nowiki>''
<<hello_unsafe "Unsafe message!">>
!!!From ''<nowiki><<hello_box>></nowiki>''
<<hello_box '''This text should be inside a yellow box.
This macro uses a custom CSS class. All
__wikitext__ //styling// @@markup@@ works
here as well.'''>>
Save the item and you should see that it works.