]> sipb.mit.edu Git - ikiwiki.git/blobdiff - doc/plugins/write.mdwn
finish with rcs plugin conversion
[ikiwiki.git] / doc / plugins / write.mdwn
index 508dd83dc102dfaad6ac99024e1a04f594b91f63..896b988270914e47faa9b714ac036f6a3da9fd7b 100644 (file)
@@ -3,7 +3,7 @@ written to extend ikiwiki in many ways. Despite the length of this page,
 it's not really hard. This page is a complete reference to everything a
 plugin might want to do. There is also a quick [[tutorial]].
 
-[[toc levels=2]]
+[[!toc levels=2]]
 
 ## Types of plugins
 
@@ -46,11 +46,13 @@ being edited.
 
 Plugins should, when imported, call `hook()` to hook into ikiwiki's
 processing. The function uses named parameters, and use varies depending on
-the type of hook being registered -- see below. Note that a plugin can call
-the function more than once to register multiple hooks. All calls to
-`hook()` should be passed a "type" parameter, which gives the type of
-hook, a "id" paramter, which should be a unique string for this plugin, and
-a "call" parameter, which tells what function to call for the hook.
+the type of hook being registered -- see below. A plugin can call
+the function more than once to register multiple hooks.
+
+All calls to `hook()` should be passed a "type" parameter, which gives the
+type of hook, a "id" parameter, which should be a unique string for this
+plugin, and a "call" parameter, which tells what function to call for the
+hook.
 
 An optional "last" parameter, if set to a true value, makes the hook run
 after all other hooks of its type. Useful if the hook depends on some other
@@ -99,6 +101,18 @@ built when the wiki is refreshed. The function is passed a reference to an
 array of pages that will be rebuilt, and can modify the array, either
 adding or removing files from it.
 
+### scan
+
+       hook(type => "scan", id => "foo", call => \&scan);
+
+This hook is called early in the process of building the wiki, and is used
+as a first pass scan of the page, to collect metadata about the page. It's
+mostly used to scan the page for WikiLinks, and add them to `%links`.
+Present in IkiWiki 2.40 and later.
+
+The function is passed named parameters "page" and "content". Its return
+value is ignored.
+
 ### filter
 
        hook(type => "filter", id => "foo", call => \&filter);
@@ -154,23 +168,11 @@ and later.
 Plugins that implement linkify must also implement a scan hook, that scans
 for the links on the page and adds them to `%links`.
 
-### scan
-
-       hook(type => "scan", id => "foo", call => \&scan);
-
-This hook is called early in the process of building the wiki, and is used
-as a first pass scan of the page, to collect metadata about the page. It's
-mostly used to scan the page for WikiLinks, and add them to `%links`.
-Present in IkiWiki 2.40 and later.
-
-The function is passed named parameters "page" and "content". Its return
-value is ignored.
-
 ### htmlize
 
        hook(type => "htmlize", id => "ext", call => \&htmlize);
 
-Runs on the raw source of a page and turns it into html. The id parameter
+Runs on the source of a page and turns it into html. The id parameter
 specifies the filename extension that a file must have to be htmlized using
 this plugin. This is how you can add support for new and exciting markup
 languages to ikiwiki.
@@ -187,7 +189,7 @@ 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
 templates. The function is passed named parameters. The "page" and
 "destpage" parameters are the same as for a preprocess hook. The "template"
-parameter is a [[cpan HTML::Template]] object that is the template that
+parameter is a [[!cpan HTML::Template]] object that is the template that
 will be used to generate the page. The function can manipulate that
 template object.
 
@@ -211,8 +213,19 @@ want to change the default ("page.tmpl"). Template files are looked for in
 Use this to implement html sanitization or anything else that needs to
 modify the body of a page after it has been fully converted to html.
 
-The function is passed named parameters: "page" and "content", and 
-should return the sanitized content.
+The function is passed named parameters: "page", "destpage", and "content",
+and should return the sanitized content.
+
+### postscan
+
+       hook(type => "postscan", id => "foo", call => \&postscan);
+
+This hook is called once the full page body is available (but before the
+format hook). The most common use is to update search indexes. Added in
+ikiwiki 2.54.
+
+The function is passed named parameters "page" and "content". Its return
+value is ignored.
 
 ### format
 
@@ -220,7 +233,9 @@ should return the sanitized content.
 
 The difference between format and sanitize is that sanitize only acts on
 the page body, while format can modify the entire html page including the
-header and footer inserted by ikiwiki, the html document type, etc.
+header and footer inserted by ikiwiki, the html document type, etc. (It
+should not rely on always being passed the entire page, as it won't be
+when the page is being previewed.)
 
 The function is passed named parameters: "page" and "content", and 
 should return the formatted content.
@@ -256,9 +271,9 @@ state is loaded, and with no session information.
 
        hook(type => "auth", id => "foo", call => \&auth);
 
-This hook can be used to implement a different authentication method than
-the standard web form. When a user needs to be authenticated, each registered
-auth hook is called in turn, and passed a CGI object and a session object. 
+This hook can be used to implement an authentication method. When a user
+needs to be authenticated, each registered auth hook is called in turn, and
+passed a CGI object and a session object. 
 
 If the hook is able to authenticate the user, it should set the session
 object's "name" parameter to the authenticated user's name. Note that
@@ -310,7 +325,7 @@ It can modify the content as desired, and should return the content.
        hook(type => "formbuilder_setup", id => "foo", call => \&formbuilder_setup);
        hook(type => "formbuilder", id => "foo", call => \&formbuilder);
 
-These hooks allow tapping into the parts of ikiwiki that use [[cpan
+These hooks allow tapping into the parts of ikiwiki that use [[!cpan
 CGI::FormBuilder]] to generate web forms. These hooks are passed named
 parameters: `cgi`, `session`, `form`, and `buttons`. These are, respectively,
 the `CGI` object, the user's `CGI::Session`, a `CGI::FormBuilder`, and a
@@ -329,15 +344,65 @@ called. It can be used to validate the form, but should not display it.
 
        hook(type => "savestate", id => "foo", call => \&savestate);
 
-This hook is called wheneven ikiwiki normally saves its state, just before
+This hook is called whenever ikiwiki normally saves its state, just before
 the state is saved. The function can save other state, modify values before
 they're saved, etc.
 
+## renamepage
+
+       hook(type => "renamepage", id => "foo", call => \&renamepage);
+
+This hook is called by the [[plugins/rename]] plugin when it renames
+something. The hook is passed named parameters: `page`, `oldpage`,
+`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 the plugin is not available, 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. For example:
+
+                return
+                       option_foo => {
+                               type => "boolean",
+                               description => "enable foo",
+                               safe => 1,
+                               rebuild => 1,
+                       },
+                       option_bar => {
+                               type => "string",
+                               example => "hello",
+                               description => "what to say",
+                               safe => 1,
+                               rebuild => 0,
+                       },
+
+* `type` can be "boolean", "string", "integer", "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.
+* `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.
+* `rebuild` should be true if changing the option will require a wiki rebuild.
+
 ## Plugin interface
 
 To import the ikiwiki plugin interface:
 
-       use IkiWiki '1.00';
+       use IkiWiki '2.00';
 
 This will import several variables and functions into your plugin's
 namespace. These variables and functions are the ones most plugins need,
@@ -361,10 +426,11 @@ 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}`.
 
-`$key` can be any string you like, but `$id` must be the same as the "id"
-parameter passed to `hook()` when registering the plugin. This is so
-ikiwiki can know when to delete pagestate for plugins that are no longer
-used.
+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
+as the "id" parameter passed to `hook()` when registering the plugin. This
+is so ikiwiki can know when to delete pagestate for plugins that are no
+longer used.
 
 When pages are deleted, ikiwiki automatically deletes their pagestate too.
 
@@ -407,16 +473,17 @@ Aborts with an error message. If the second parameter is passed, it is a
 function that is called after the error message is printed, to do any final
 cleanup.
 
-Note that while any plugin can use this for a fatal error, plugins should
-try to avoid dying on bad input, as that will halt the entire wiki build
-and make the wiki unusable. So for example, if a
-[[ikiwiki/PreProcessorDirective]] is passed bad parameters, it's better to
-return an error message, which can appear on the wiki page, rather than
-calling error().
+If called inside a preprocess hook, error() does not abort the entire
+wiki build, but instead replaces the [[ikiwiki/PreProcessorDirective]] with
+a version containing the error message.
+
+In other hooks, error() is a fatal error, so use with care. Try to avoid
+dying on bad input when building a page, as that will halt
+the entire wiki build and make the wiki unusable.
 
 #### `template($;@)`
 
-Creates and returns a [[cpan HTML::Template]] object. The first parameter
+Creates and returns a [[!cpan HTML::Template]] object. The first parameter
 is the name of the file in the template directory. The optional remaining
 parameters are passed to `HTML::Template->new`.
 
@@ -556,18 +623,23 @@ time.
 
 This is the standard gettext function, although slightly optimised.
 
-#### `urlto($$)`
+#### `urlto($$;$)`
 
 Construct a relative url to the first parameter from the page named by the
 second. The first parameter can be either a page name, or some other
 destination file, as registered by `will_render`.
 
+If the third parameter is passed and is true, an absolute url will be
+constructed instead of the default relative url.
+
 #### `targetpage($$)`
 
 Passed a page and an extension, returns the filename that page will be
 rendered to.
 
-## Internal use pages
+## Miscellaneous
+
+### Internal use pages
 
 Sometimes it's useful to put pages in the wiki without the overhead of
 having them be rendered to individual html files. Such internal use pages
@@ -580,19 +652,111 @@ either on them with extreme caution), and are not matched by regular
 PageSpecs glob patterns, but instead only by a special `internal()`
 [[ikiwiki/PageSpec]].
 
-## RCS plugins
+### RCS plugins
+
+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.
 
-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`. 
+#### `rcs_remove($)`
 
-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.
+Remove a file. The filename is relative to the root of the srcdir.
 
-See [[RCS_details|rcs/details]] for some more info.
+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.
 
-## PageSpec plugins
+#### `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($)`
+
+This is used to get the page creation time for a file from the RCS, by looking
+it up in the history.
+
+It's ok if this is not implemented, and throws an error.
+
+### PageSpec plugins
 
 It's also possible to write plugins that add new functions to
 [[PageSpecs|ikiwiki/PageSpec]]. Such a plugin should add a function to the
@@ -602,3 +766,19 @@ two parameters: The name of the page being matched, and the thing to match
 against. It may also be passed additional, named parameters. It should return
 a IkiWiki::SuccessReason object if the match succeeds, or an
 IkiWiki::FailReason object if the match fails.
+
+### 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.
+
+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.
+
+By the way, to parse a ikiwiki setup file, a program just needs to
+do something like:
+`use IkiWiki::Setup; my %setup=IkiWiki::Setup::load($filename)`