aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorJoey Hess <joey@kodama.kitenet.net>2008-10-21 17:57:19 -0400
committerJoey Hess <joey@kodama.kitenet.net>2008-10-21 17:57:19 -0400
commite75818572fff5256d16221a2b065b214d8cb9f5d (patch)
tree30e45561111b4dcc48f4726bfaef0ca99f5d47d2 /doc
parent92a43d5d384ba4e504c5255989a869ced424219c (diff)
downloadikiwiki-e75818572fff5256d16221a2b065b214d8cb9f5d.tar
ikiwiki-e75818572fff5256d16221a2b065b214d8cb9f5d.tar.gz
function injection overhaul
Add an inject function, that can be used by plugins that want to replace one of ikiwiki's functions with their own version. (This is a scary thing that grubs through the symbol table, and replaces all exported occurances of a function with the injected version.) external: RPC functions can be injected to replace exported functions. Removed the stupid displaytime hook, and use injection instead.
Diffstat (limited to 'doc')
-rw-r--r--doc/plugins/contrib/po.mdwn5
-rw-r--r--doc/plugins/write.mdwn50
2 files changed, 55 insertions, 0 deletions
diff --git a/doc/plugins/contrib/po.mdwn b/doc/plugins/contrib/po.mdwn
index 30ede95a6..c4b7f9ee9 100644
--- a/doc/plugins/contrib/po.mdwn
+++ b/doc/plugins/contrib/po.mdwn
@@ -47,6 +47,11 @@ Any thoughts on this?
>>> `targetpage`, `bestlink`, and `beautify_urlpath`. But, I noticed
>>> the other day that such wrappers around exported functions are only visible by
>>> plugins loaded after the plugin that defines them.
+>>>
+>>> Update: Take a look at the new "Function overriding" section of
+>>> [[plugins/write]]. I think you can just inject wrappers about a few ikiwiki
+>>> functions, rather than adding hooks. The `inject` function is pretty
+>>> insane^Wlow level, but seems to work great. --[[Joey]]
>>
>> The Discussion pages issue is something I am not sure about yet. But I will
>> probably decide that "slave" pages, being only translations, don't deserve
diff --git a/doc/plugins/write.mdwn b/doc/plugins/write.mdwn
index 856b34ba1..2e11e6234 100644
--- a/doc/plugins/write.mdwn
+++ b/doc/plugins/write.mdwn
@@ -854,6 +854,56 @@ 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.