X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/18b3e970ffcc0f74d68538b7094f76442a294609..78e4d5bc6f1a55b400611d12185369b6e76c0f33:/doc/plugins/write.mdwn diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn index 4dc55e302..349a8a1ed 100644 --- a/doc/plugins/write.mdwn +++ b/doc/plugins/write.mdwn @@ -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 @@ -123,34 +123,42 @@ make arbitrary changes. The function is passed named parameters "page", ### 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); -Replace "foo" with the command name that will be used inside brackets for -the preprocessor directive. - -Each time the directive is processed, the referenced function (`preprocess` -in the example above) is called, and is passed named parameters. A "page" -parameter gives the name of the page that embedded the preprocessor -directive, while a "destpage" parameter gives the name of the page the -content is going to (different for inlined pages), and a "preview" -parameter is set to a true value if the page is being previewed. All -parameters included in the directive are included as named parameters as -well. Whatever the function returns goes onto the page in place of the +Replace "foo" with the command name that will be used for the preprocessor directive. -An optional "scan" parameter, if set to a true value, makes the hook be -called during the preliminary scan that ikiwiki makes of updated pages, -before begining to render pages. This parameter should be set to true if -the hook modifies data in `%links`. Note that doing so will make the hook -be run twice per page build, so avoid doing it for expensive hooks. (As an -optimisation, if your preprocessor hook is called in a void contets, you -can assume it's being run in scan mode.) +Each time the directive is processed, the referenced function (`preprocess` +in the example above) is called. Whatever the function returns goes onto +the page in place of the directive. Or, if the function aborts using +`error()`, the directive will be replaced with the error message. + +The function is passed named parameters. First come the parameters set +in the preprocessor directive. These are passed in the same order as +they're in the directive, and if the preprocessor directive contains a bare +parameter (example: `\[[!foo param]]`), that parameter will be passed with +an empty value. + +After the parameters from the preprocessor directive some additional ones +are passed: A "page" parameter gives the name of the page that embedded the +preprocessor directive, while a "destpage" parameter gives the name of the +page the content is going to (different for inlined pages), and a "preview" +parameter is set to a true value if the page is being previewed. + +If `hook` is passed an optional "scan" parameter, set to a true value, this +makes the hook be called during the preliminary scan that ikiwiki makes of +updated pages, before begining to render pages. This should be done if the +hook modifies data in `%links`. Note that doing so will make the hook be +run twice per page build, so avoid doing it for expensive hooks. (As an +optimisation, if your preprocessor hook is called in a void context, you +can assume it's being run in scan mode, and avoid doing expensive things at +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 @@ -180,16 +188,21 @@ languages to ikiwiki. The function is passed named parameters: "page" and "content" and should return the htmlized content. +If `hook` is passed an optional "keepextension" parameter, set to a true +value, then this extension will not be stripped from the source filename when +generating the page. + ### pagetemplate 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 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. @@ -216,6 +229,17 @@ modify the body of a page after it has been fully converted to html. 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 hook(type => "format", id => "foo", call => \&format); @@ -314,7 +338,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 @@ -337,6 +361,73 @@ 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 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: @@ -356,14 +447,14 @@ it's not exported, the wise choice is to not use it. 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 @@ -413,7 +504,7 @@ function that is called after the error message is printed, to do any final 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 @@ -422,7 +513,7 @@ 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`. @@ -562,12 +653,15 @@ 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 @@ -590,15 +684,107 @@ PageSpecs glob patterns, but instead only by a special `internal()` ### 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 commit the new file, it should only +prepare for it to be committed 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 commit the removal, it should only prepare for it +to be committed when `rcs_commit` (or `rcs_commit_staged`) is called. Note +that the new file may be in a new subdir that is not yet in version +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 @@ -613,15 +799,16 @@ 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. +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 `use IkiWiki::Setup; my %setup=IkiWiki::Setup::load($filename)` +By the way, to parse a ikiwiki setup file and populate `%config`, a +program just needs to do something like: +`use IkiWiki::Setup; IkiWiki::Setup::load($filename)`