Custom Actions
administrators (intermediate)
With cookbook recipes, it is possible to define custom page actions for PmWiki. The correspondent code is executed whenever a parameter action
is present in the wiki URL like in this made-up example:
[[MyGroup/MyPage
?action=myaction]]
With such an action, you can alter the display and treatment of the current page - like in standard actions as edit
or print
. Or you can manipulate many wiki pages at once or perform global tasks, such as changing the saved mark-up of all pages in that group (beware!) or collecting data from all pages in the wiki. So depending on your code, it may not even matter to which page URL the action parameter is appended, like with standard action phpinfo
.
Whereas a Custom Markup is primarily intended to generate a meaningful text replacement on the current page, a page action is triggered by a url parameter and thus can be used in links as a call to a PHP function, acting on the current page or wiki wide, for instance like:
[[{*$FullName}?action=myaction| do my action]] |
However, if you want to use PmWiki's built-in functions for custom actions you have to be aware of the fact that cookbook recipes are included in config.php
, which is executed early during PmWiki page processing. That means that many variables of these internal functions (e.g. in pmwiki.php
) are not yet properly initialized. Thus, these functions can behave unexpectedly when called directly in the recipe's include file. Remember that functions used for custom mark-up, too, are only called later in the process - Markup()
takes care of this. Analogously, you can use an action handler to make PmWiki execute your action code at the right time, when all the internal workings are set.
The following example shows how to set up a custom action myaction
for URL .../MyGroup/MyPage?action=myaction
. The following nonsensical but instructive example will prepend an "x" to the mark-up of another page MyGroup.MyOtherPage
. Then it will display the page MyGroup.MyPage
that is stated in the URL.
$HandleActions['myaction'] = 'HandleMyAction'; # if url contains action=myaction call HandleMyAction timely $HandleAuth['myaction'] = 'admin'; # authorization level $auth for HandleMyAction function HandleMyAction($pagename, $auth) { # parameters (signature) of handler function required by PmWiki global $Author; # get hold of current author name, e.g. for page history $old = RetrieveAuthPage('MyGroup.MyOtherPage', $auth); # get all information from page MyGroup.MyOtherPage $new = $old; # copy the page information to stay (e.g. page history) $new['text'] = "x".$old['text']; # ... some manipulation of the old wiki mark-up $Author='myactionbot'; # author name to appear in the page history for this manipulation $pn='MyGroup.MyOtherPage'; # need to call UpdatePage with variables (by reference) only UpdatePage($pn,$old,$new); # alter the actual wiki page HandleBrowse($pagename); # display the page specified in the url (e.g. MyGroup.MyPage) }
Notes:
- With 'admin' as authorization level, the action will prompt for an admin password unless it is already present in a cookie from an earlier login. With 'read',
RetrieveAuthPage()
could only access pages that the current user may read. - For some reason,
UpdatePage()
needs to be called with variables (by reference), thusUpdatePage('MyGroup.MyOtherPage',$old,$new),
would yield a PHP error. - Since this action here is affecting unrelated pages (
MyOtherPage
), one would rather exit the script afterUpdatePage()
, maybe after having printed some raw status message, instead of displaying a wiki page withHandleBrowse()
. - If an UpdatePage action includes form field processing, clean up the input before using it to build
$new['text']
. For example:$new['text'] = str_replace("\r",'',stripmagic($_POST['text']));
. - List of Available Actions (Default actions ; Enable diag actions ; Script actions ; Cookbook actions)
Category: PmWiki Developer
This page may have a more recent version on pmwiki.org: PmWiki:CustomActions, and a talk page: PmWiki:CustomActions-Talk?.