]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blobdiff - doc/plugins/write.mdwn
Merge commit 'origin/master'
[git.ikiwiki.info.git] / doc / plugins / write.mdwn
index 255be4207c54ed5bc05062d421696719919c2b5d..abcabbdc39e43871af4b491b47b1540fda99a34f 100644 (file)
@@ -123,7 +123,7 @@ 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);
@@ -158,7 +158,7 @@ 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
@@ -188,6 +188,10 @@ 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);
@@ -356,7 +360,7 @@ 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
+### renamepage
 
        hook(type => "renamepage", id => "foo", call => \&renamepage);
 
@@ -379,33 +383,49 @@ 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. For example:
+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",
+                               description => "enable foo?",
+                               advanced => 1,
                                safe => 1,
                                rebuild => 1,
                        },
                        option_bar => {
                                type => "string",
                                example => "hello",
-                               description => "what to say",
+                               description => "option bar",
                                safe => 1,
                                rebuild => 0,
                        },
+                       plugin => {
+                               description => "description of this plugin",
+                               safe => 1,
+                               rebuild => 1,
+                       },
 
-* `type` can be "boolean", "string", "integer", 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.
+* `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.
-* `description_html` is an optional short description, that can contain html
+* `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.
-* `rebuild` should be true if changing the option will require a wiki rebuild.
+  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
 
@@ -432,8 +452,8 @@ your ikiwiki setup file, which sets the hash content to configure the wiki.
 
 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
@@ -446,6 +466,15 @@ When pages are deleted, ikiwiki automatically deletes their pagestate too.
 Note that page state does not persist across wiki rebuilds, only across
 wiki updates.
 
+### %wikistate
+
+The `%wikistate` hash can be used by a plugin to store persistant state
+that is not bound to any one page. To set a value, use
+`$wikistate{$id}{$key}=$value, where `$value` is anything Storable can
+serialize, `$key` is any string you like, and `$id` must be the same as the
+"id" parameter passed to `hook()` when registering the plugin, so that the
+state can be dropped if the plugin is no longer used.
+
 ### Other variables
 
 If your plugin needs to access data about other pages in the wiki. It can
@@ -483,7 +512,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
@@ -501,6 +530,9 @@ parameters are passed to `HTML::Template->new`.
 Passed a page name, returns the base name that will be used for a the html
 page created from it. (Ie, it appends ".html".)
 
+Use this when constructing the filename of a html file. Use `urlto` when
+generating a link to a page.
+
 #### `add_depends($$)`
 
 Makes the specified page depend on the specified [[ikiwiki/PageSpec]].
@@ -603,6 +635,23 @@ a type that ikiwiki knowns how to htmlize. Otherwise, returns undef.
 Given the name of a source file, returns the name of the wiki page
 that corresponds to that file.
 
+#### `pagetitle($)`
+
+Give the name of a wiki page, returns a version suitable to be displayed as
+the page's title. This is accomplished by de-escaping escaped characters in
+the page name. "_" is replaced with a space, and '__NN__' is replaced by 
+the UTF character with code NN.
+
+#### `titlepage($)`
+
+This performs the inverse of `pagetitle`, ie, it converts a page title into
+a wiki page name.
+
+#### `linkpage($)`
+
+This converts text that could have been entered by the user as a
+[[WikiLink]] into a wiki page name.
+
 #### `srcfile($;$)`
 
 Given the name of a source file in the wiki, searches for the file in
@@ -641,6 +690,12 @@ 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.
 
+#### `newpagefile($$)`
+
+This can be called when creating a new page, to determine what filename
+to save the page to. It's passed a page name, and its type, and returns
+the name of the file to create, relative to the srcdir.
+
 #### `targetpage($$)`
 
 Passed a page and an extension, returns the filename that page will be
@@ -702,8 +757,8 @@ Changes can be staged by calls to `rcs_add, `rcs_remove`, and
 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
+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.
 
@@ -711,9 +766,9 @@ to version control; the subdir can be added if so.
 
 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
+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($$)`
@@ -765,6 +820,30 @@ it up in the history.
 
 It's ok if this is not implemented, and throws an error.
 
+#### `rcs_receive()`
+
+This is called when ikiwiki is running as a pre-receive hook (or
+equivalent), and is testing if changes pushed into the RCS from an
+untrusted user should be accepted. This is optional, and doesn't make
+sense to implement for all RCSs.
+
+It should examine the incoming changes, and do any sanity 
+checks that are appropriate for the RCS to limit changes to safe file adds,
+removes, and changes. If something bad is found, it should exit
+nonzero, to abort the push. Otherwise, it should return a list of
+files that were changed, in the form:
+
+       {
+               file => # name of file that was changed
+               action => # either "add", "change", or "remove"
+               path => # temp file containing the new file content, only
+                       # needed for "add"/"change", and only if the file
+                       # is an attachment, not a page
+       }
+
+The list will then be checked to make sure that each change is one that
+is allowed to be made via the web interface.
+
 ### PageSpec plugins
 
 It's also possible to write plugins that add new functions to
@@ -788,6 +867,85 @@ when imported, populate `$IkiWiki::Setup::raw_setup` with a reference
 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)`
+
+### Function overriding
+
+Sometimes using ikiwiki's pre-defined hooks is not enough. Your plugin
+may need to replace one of ikiwiki's own functions with a modified version,
+or wrap one of the functions.
+
+For example, your plugin might want to override `displaytime`, to change
+the html markup used when displaying a date. Or it might want to override
+`IkiWiki::formattime`, to change how a date is formatted. Or perhaps you
+want to override `bestlink` and change how ikiwiki deals with WikiLinks.
+
+By venturing into this territory, your plugin is becoming tightly tied to
+ikiwiki's internals. And it might break if those internals change. But
+don't let that stop you, if you're brave.
+
+Ikiwiki provides an `inject()` function, that is a powerful way to replace
+any function with one of your own. This even allows you to inject a
+replacement for an exported function, like `bestlink`. Everything that
+imports that function will get your version instead. Pass it the name of
+the function to replace, and a new function to call. 
+
+For example, here's how to replace `displaytime` with a version using HTML 5
+markup:
+
+       inject(name => 'IkiWiki::displaytime', call => sub {
+               return "<time>".formattime(@_)."</time>";
+       });
+
+Here's how to wrap `bestlink` with a version that tries to handle
+plural words:
+
+       my $origbestlink=\&bestlink;
+       inject(name => 'IkiWiki::bestlink', call => \&mybestlink);
+
+       sub deplural ($) {
+               my $word=shift;
+               $word =~ s/e?s$//; # just an example :-)
+               return $word;
+       }
+
+       sub mybestlink ($$) {
+               my $page=shift;
+               my $link=shift;
+               my $ret=$origbestlink->($page, $link);
+               if (! length $ret) {
+                       $ret=$origbestlink->($page, deplural($link));
+               }
+               return $ret;
+       }
+
+### Javascript
+
+Some plugins use javascript to make ikiwiki look a bit more web-2.0-ish.
+
+All javascript code should be put in `.js` files in the `javascript`
+underlay, and plugins using those files can enable use of the underlay by
+calling `add_underlay("javascript");` in their `import` function.
+
+You'll have to arrange for `<script>` tags to be added to the pages that
+use your javascript. This can be done using a `format` hook.
+
+Ikiwiki provides some utility functions in `ikiwiki.js`, for use by other
+javascript code. These include:
+
+#### `getElementsByClass(cls, node, tag)` 
+
+Returns an array of elements with the given class. The node and tag are
+optional and define what document node and element names to search.
+
+#### `hook(name, call)`
+
+The function `call` will be run as part of the hook named `name`.
+
+Note that to hook into `window.onload`, you can use the `onload' hook.
+
+#### `run_hooks(name)`
+
+Runs the hooks with the specified name.