External plugins are standalone, executable programs, that can be written
in any language. When ikiwiki starts up, it runs the program, and
-communicates with it using XML RPC. If you want to [[write]] an external
-plugin, read on..
+communicates with it using [XML RPC][xmlrpc]. If you want to [[write]] an
+external plugin, read on..
+
+[xmlrpc]: http://www.xmlrpc.com/
ikiwiki contains one sample external plugin, named `externaldemo`. This is
written in perl, but is intended to be an example of how to write an
There's now a second external plugin, the [[rst]] plugin, written in
python. It uses a `proxy.py`, a helper library for ikiwiki python plugins.
-[[toc ]]
+[[!toc ]]
## How external plugins use XML RPC
stdout, also using XML RPC. After reading a command, and before returning
the result, the plugin can output XML RPC requests of its own, calling
functions in ikiwiki. Note: *Never* make an XML RPC request at any other
-time. Ikiwiki won't be listening for it, and you will deadlock.
+time. IkiWiki won't be listening for it, and you will deadlock.
When ikiwiki starts up an external plugin, the first RPC it will make
is to call the plugin's `import()` function. That function typically makes
## Accessing data structures
-Ikiwiki has a few global data structures such as `%config`, which holds
+IkiWiki has a few global data structures such as `%config`, which holds
its configuration. External plugins can use the `getvar` and `setvar` RPCs
to access any such global hash. To get the "url" configuration value,
call `getvar("config", "url")`. To set it, call
stored state, call `getstate("page", "id", "key")`, and to store state,
call `setstate("page", "id", "key", "value")`.
+To access ikiwiki's ARGV array, call `getargv()`. To change its ARGV, call
+`setargv(array)`.
+
## Notes on function parameters
The [[plugin_interface_documentation|write]] talks about functions that take
to convert these named parameters into something more natural for the
language as part of their XML RPC interface.
+## undef
+
+XML RPC has a limitation that it does not have a way to pass
+undef/NULL/None. There is an extension to the protocol that supports this,
+but it is not yet available in all versions of the [[!cpan XML::RPC]] library
+used by ikiwiki.
+
+Until the extension is available, ikiwiki allows undef to be communicated
+over XML RPC by passing a sentinal value, a hash with a single key "null"
+with a value of an empty string. External plugins that need to communicate
+null values to or from ikiwiki will have to translate between undef and
+the sentinal.
+
## Function injection
-Some parts of ikiwiki are extensible by adding functions. For example, the
-RCS interface relies on plugins providing several IkiWiki::rcs_* functions.
+Some parts of ikiwiki are extensible by adding or overriding functions.
It's actually possible to do this from an external plugin too.
-To make your external plugin provide an `IkiWiki::rcs_update` function, for
+To make your external plugin override the `IkiWiki::formattime` function, for
example, make an RPC call to `inject`. Pass it named parameters "name" and
"call", where "name" is the name of the function to inject into perl (here
-"Ikiwiki::rcs_update" and "call" is the RPC call ikiwiki will make whenever
+"Ikiwiki::formattime" and "call" is the RPC call ikiwiki will make whenever
that function is run.
If the RPC call is memoizable, you can also pass a "memoize" parameter, set
FormBuilder perl objects), or use it to call `template()` (which returns a
perl HTML::Template object).
-Also. the `getopt` hook doesn't work, as ARGV is not available to the external
-plugin.
-
## Performance issues
Since each external plugin is a separate process, when ikiwiki is
are called generally rarely, and pass around minimal data.
External plugins should avoid making RPC calls unnecessarily (ie, in a loop).
-Memoizing the results of appropriate RPC calls is one good way to minimise the
+Memoizing the results of appropriate RPC calls is one good way to minimize the
number of calls.
Injecting a replacement for a commonly called ikiwiki function
could result in a lot more RPC calls than expected and slow
-eveything down. `pagetitle`, for instance, is called about 100 times
+everything down. `pagetitle`, for instance, is called about 100 times
per page build. Whenever possible, you should tell ikiwiki to memoize
injected functions.