### preprocess
-Adding a [[ikiwiki/PreProcessorDirective]] is probably the most common use
+Adding a preprocessor [[ikiwiki/directive]] is probably the most common use
of a plugin.
hook(type => "preprocess", id => "foo", call => \&preprocess);
that point.)
Note that if the [[htmlscrubber]] is enabled, html in
-[[ikiwiki/PreProcessorDirective]] output is sanitised, which may limit what
+preprocessor [[ikiwiki/directive]] output is sanitised, which may limit what
your plugin can do. Also, the rest of the page content is not in html
format at preprocessor time. Text output by a preprocessor directive will
be linkified and passed through markdown (or whatever engine is used to
hook(type => "pagetemplate", id => "foo", call => \&pagetemplate);
+
[[Templates|wikitemplates]] are filled out for many different things in
ikiwiki, like generating a page, or part of a blog page, or an rss feed, or
a cgi. This hook allows modifying the variables available on those
the state is saved. The function can save other state, modify values before
they're saved, etc.
-## renamepage
+### renamepage
hook(type => "renamepage", id => "foo", call => \&renamepage);
`newpage`, and `content`, and should try to modify the content to reflect
the name change. For example, by converting links to point to the new page.
+### getsetup
+
+ hook(type => "getsetup", id => "foo", call => \&getsetup);
+
+This hooks is not called during normal operation, but only when setting up
+the wiki, or generating a setup file. Plugins can use this hook to add
+configuration options.
+
+The hook is passed no parameters. It returns data about the configuration
+options added by the plugin. It can also check if the plugin is usable, and
+die if not, which will cause the plugin to not be offered in the configuration
+interface.
+
+The data returned is a list of `%config` options, followed by a hash
+describing the option. There can also be an item named "plugin", which
+describes the plugin as a whole. For example:
+
+ return
+ option_foo => {
+ type => "boolean",
+ description => "enable foo?",
+ advanced => 1,
+ safe => 1,
+ rebuild => 1,
+ },
+ option_bar => {
+ type => "string",
+ example => "hello",
+ description => "option bar",
+ safe => 1,
+ rebuild => 0,
+ },
+ plugin => {
+ description => "description of this plugin",
+ safe => 1,
+ rebuild => 1,
+ },
+
+* `type` can be "boolean", "string", "integer", "pagespec",
+ or "internal" (used for values that are not user-visible). The type is
+ the type of the leaf values; the `%config` option may be an array or
+ hash of these.
+* `example` can be set to an example value.
+* `description` is a short description of the option.
+* `link` is a link to further information about the option. This can either
+ be a wikilink, or an url.
+* `advanced` can be set to true if the option is more suitable for advanced
+ users.
+* `safe` should be false if the option should not be displayed in unsafe
+ configuration methods, such as the web interface. Anything that specifies
+ a command to run, a path on disk, or a regexp should be marked as unsafe.
+ If a plugin is marked as unsafe, that prevents it from being
+ enabled/disabled.
+* `rebuild` should be true if changing the option (or enabling/disabling
+ the plugin) will require a wiki rebuild, false if no rebuild is needed,
+ and undef if a rebuild could be needed in some circumstances, but is not
+ strictly required.
+
## Plugin interface
To import the ikiwiki plugin interface:
A plugin can access the wiki's configuration via the `%config`
hash. The best way to understand the contents of the hash is to look at
-[[ikiwiki.setup]], which sets the hash content to configure the wiki.
+your ikiwiki setup file, which sets the hash content to configure the wiki.
### %pagestate
The `%pagestate` hash can be used by plugins to save state that they will need
next time ikiwiki is run. The hash holds per-page state, so to set a value,
-use `%pagestate{$page}{$id}{$key}=$value`, and to retrieve the value,
-use `%pagestate{$page}{$id}{$key}`.
+use `$pagestate{$page}{$id}{$key}=$value`, and to retrieve the value,
+use `$pagestate{$page}{$id}{$key}`.
The `$value` can be anything that perl's Storable module is capable of
serializing. `$key` can be any string you like, but `$id` must be the same
cleanup.
If called inside a preprocess hook, error() does not abort the entire
-wiki build, but instead replaces the [[ikiwiki/PreProcessorDirective]] with
+wiki build, but instead replaces the preprocessor [[ikiwiki/directive]] with
a version containing the error message.
In other hooks, error() is a fatal error, so use with care. Try to avoid
### RCS plugins
-ikiwiki's support for [[revision_control_systems|rcs]] also uses pluggable
-perl modules. These are in the `IkiWiki::RCS` namespace, for example
-`IkiWiki::RCS::svn`.
+ikiwiki's support for [[revision_control_systems|rcs]] is also done via
+plugins. See [[RCS_details|rcs/details]] for some more info.
+
+RCS plugins must register a number of hooks. Each hook has type 'rcs',
+and the 'id' field is set to the name of the hook. For example:
+
+ hook(type => "rcs", id => "rcs_update", call => \&rcs_update);
+ hook(type => "rcs", id => "rcs_prepedit", call => \&rcs_prepedit);
+
+#### `rcs_update()`
+
+Updates the working directory with any remote changes.
+
+#### `rcs_prepedit($)`
+
+Is passed a file to prepare to edit. It can generate and return an arbitrary
+token, that will be passed into `rcs_commit` when committing. For example,
+it might return the current revision ID of the file, and use that
+information later when merging changes.
+
+#### `rcs_commit($$$;$$)`
+
+Passed a file, message, token (from `rcs_prepedit`), user, and ip address.
+Should try to commit the file. Returns `undef` on *success* and a version
+of the page with the rcs's conflict markers on failure.
+
+#### `rcs_commit_staged($$$)`
+
+Passed a message, user, and ip address. Should commit all staged changes.
+Returns undef on success, and an error message on failure.
+
+Changes can be staged by calls to `rcs_add, `rcs_remove`, and
+`rcs_rename`.
+
+#### `rcs_add($)`
+
+Adds the passed file to the archive. The filename is relative to the root
+of the srcdir.
+
+Note that this should not check the new file in, it should only
+prepare for it to be checked in when rcs_commit (or `rcs_commit_staged`) is
+called. Note that the file may be in a new subdir that is not yet in
+to version control; the subdir can be added if so.
+
+#### `rcs_remove($)`
+
+Remove a file. The filename is relative to the root of the srcdir.
+
+Note that this should not check the removal in, it should only prepare for it
+to be checked in when `rcs_commit` (or `rcs_commit_staged`) is called. Note
+that the new file may be in a new subdir that is not yet inversion
+control; the subdir can be added if so.
+
+#### `rcs_rename($$)`
+
+Rename a file. The filenames are relative to the root of the srcdir.
+
+Note that this should not commit the rename, it should only
+prepare it for when `rcs_commit` (or `rcs_commit_staged`) is called.
+The new filename may be in a new subdir, that is not yet added to
+version control. If so, the subdir will exist already, and should
+be added to revision control.
+
+#### `rcs_recentchanges($)`
+
+Examine the RCS history and generate a list of recent changes.
+The parameter is how many changes to return.
+
+The data structure returned for each change is:
+
+ {
+ rev => # the RCSs id for this commit
+ user => # name of user who made the change,
+ committype => # either "web" or the name of the rcs,
+ when => # time when the change was made,
+ message => [
+ { line => "commit message line 1" },
+ { line => "commit message line 2" },
+ # etc,
+ ],
+ pages => [
+ {
+ page => # name of page changed,
+ diffurl => # optional url to a diff of changes
+ },
+ # repeat for each page changed in this commit,
+ ],
+ }
+
+#### `rcs_diff($)`
+
+The parameter is the rev from `rcs_recentchanges`.
+Should return a list of lines of the diff (including \n) in list
+context, and the whole diff in scalar context.
+
+#### `rcs_getctime($)`
-Each RCS plugin must support all the `IkiWiki::rcs_*` functions.
-See IkiWiki::RCS::Stub for the full list of functions. It's ok if
-`rcs_getctime` does nothing except for throwing an error.
+This is used to get the page creation time for a file from the RCS, by looking
+it up in the history.
-See [[RCS_details|rcs/details]] for some more info.
+It's ok if this is not implemented, and throws an error.
### PageSpec plugins
### Setup plugins
-The ikiwiki setup file is loaded using a pluggable mechanism. If you
-look at the top of [[ikiwiki.setup]], it starts with
-'use IkiWiki::Setup::Standard', and the rest of the file is passed to
-that module's import method.
+The ikiwiki setup file is loaded using a pluggable mechanism. If you look
+at the top of a setup file, it starts with 'use IkiWiki::Setup::Standard',
+and the rest of the file is passed to that module's import method.
It's possible to write other modules in the `IkiWiki::Setup::` namespace that
can be used to configure ikiwiki in different ways. These modules should,
when imported, populate `$IkiWiki::Setup::raw_setup` with a reference
-to a hash containing all the config items.
+to a hash containing all the config items. They should also implement a
+`gendump` function.
By the way, to parse a ikiwiki setup file, a program just needs to
do something like: