Okay, I have to go back to my day job, but I did hang one more bag on
the side of Semantic Forms, so I guess I'll float it up and see if
anyone else has a use for it.
(Daniel, you should cover your eyes now...)
I was looking for a way to change a field in an SF generated page with
a single click.
My SF Form generates pages whose wiki code looks like this:
{{Purpose
|Purpose Type=Objective
|Planning Cycle=FY09
|Status=Draft
|Priority=High
|Business Unit=Operations
|Start Date=1-Jan-2009
|End Date=31-Dec-2009
|Added on=2008-08-27T14:58:56
|Added by=David Towne
}}
Department Objective: Reduce Wait time for Outpatient Registration to
< 4 minutes
As you'll notice the "Status" of this "Purpose" (third parameter) is
"Draft".
After my users have created dozens of objectives, I wanted to present
the ones in "Draft" status in a list so that the user could easily
change their Status to "Submitted" and ultimately strategic planners
and business unit heads would see see a list of "Submitted" entries
and change the Status to "Active", "Rejected", "Deferred", etc.
So I wrote a Special Page called TemplateCallUpdate (see code body
below)
It expects to be called with a URL that looks like this:
...index.php?
title=Special:TemplateCallUpdate&page=Page_Name&template=Purpose&field=Status&value=Submitted
If the page "Page_Name" exists and it contains a template call of
"Purpose" and that call contains a field of "Status", it changes the
value of Status to "Submitted". If the "Status" field doesn't exist,
TemplateCallUpdate adds it with a value of "Submitted".
Pretty simple concept, but it does change the Wiki text directly. I'm
new to Wiki coding, so I don't know if I broke any written or
unwritten rules or guidelines about what Special Pages should and
shouldn't do, but c'est la vie.
In fact the reason I have been trying to use embedded parser function
calls in #arraymap was to dynamically build the list of strategic
planning elements with their associated links to TemplateCallUpdate
whose semantic properties matched the Stakeholder characteristics of
the current user.
The "UI" I'm shooting for is a list like this, where the page name is
the first item in each row, the current status is in parentheses and
the available options follow as links to the TemplateCallUpdate:
Improve Patient Satisfaction (Active) Reject Defer
Improve patient safety (Submitted) Approve Reject Defer
Convert imaging system to digital (Draft) Submit
Open new surgical theater in Hampton (Draft) Submit
Anyway, if there's a better way to do this, I wasn't able to find it.
So here's the source for TemplateCallUpdate.php:
<?php
# Alert the user that this is not a valid entry point to MediaWiki if
they try to access the special pages file directly.
if (!defined('MEDIAWIKI')) {
echo <<<EOT
To install my extension, put the following line in LocalSettings.php:
require_once( "\$IP/extensions/TemplateCallUpdate/
TemplateCallUpdate.php" );
EOT;
exit( 1 );
}
$wgExtensionCredits['specialpage'][] = array(
'name' => 'Template Call Update',
'version' => 0.1,
'author' => 'Barry Welch <
barry...@ps.net>',
'description' => 'This MediaWiki extension replaces template
parameter values in the specified page. ',
'url' => '
http://www.pscwiki.com/wiki/index.php?
title=Extension:Template_Call_Update'
);
$dir = dirname(__FILE__) . '/';
$wgAutoloadClasses['TemplateCallUpdate'] = $dir .
'TemplateCallUpdate_body.php'; # Tell MediaWiki to load the extension
body.
$wgExtensionMessagesFiles['TemplateCallUpdate'] = $dir .
'TemplateCallUpdate.i18n.php';
$wgSpecialPages['TemplateCallUpdate'] = 'TemplateCallUpdate'; # Let
MediaWiki know about your new special page.
Here's the source for TemplateCallUpdate_body.php:
<?php
function efRunTemplateCallUpdate( $par ) {
TemplateCallUpdate::execute( $par );
}
class TemplateCallUpdate extends SpecialPage {
function TemplateCallUpdate() {
SpecialPage::SpecialPage("TemplateCallUpdate", '',
true, 'efRunTemplateCallUpdate');
wfLoadExtensionMessages('TemplateCallUpdate');
}
function execute($par = '') {
global $wgUser, $wgOut, $wgRequest, $wgParser ;
$this->setHeaders();
$page_name = $wgRequest->getVal('page');
$template_name = $wgRequest->getVal('template');
$field_name = $wgRequest->getVal('field');
$field_value = $wgRequest->getVal('value');
$wgOut->setPageTitle(wfMsg('templatecallupdate_title', $field_name,
$field_value, $page_name));
if ( ! $page_name || ! $template_name || ! $field_name ) {
// print an error message
$wgOut->addHTML( "<p class='error'>" .
wfMsg('templatecallupdate_errbadparam', $page_name, $template_name,
$field_name) . '</p>');
$wgOut->addHTML( '<p>' . wfMsg('templatecallupdate_page' ,
$page_name ) . '</p>'
. '<p>' . wfMsg('templatecallupdate_template',
$template_name) . '</p>'
. '<p>' . wfMsg('templatecallupdate_field' ,
$field_name ) . '</p>'
. '<p>' . wfMsg('templatecallupdate_value' ,
$field_value ) . '</p>' );
return;
}
$wgOut->addHTML( '<p>' . wfMsg('templatecallupdate_page' ,
$page_name ) . '<br />'
. wfMsg('templatecallupdate_template',
$template_name) . '<br />'
. wfMsg('templatecallupdate_field' ,
$field_name ) . '<br />'
. wfMsg('templatecallupdate_value' ,
$field_value ) . '</p>' );
$page_title = Title::newFromText($page_name);
if (! isset($page_title)) {
$wgOut->addHTML( '<p class="error">' .
wfMsg('templatecallupdate_errnotitleobj', $page_name) . '</p>');
return;
}
if( ! $page_title->exists() ) {
$wgOut->addHTML( '<p class="error">' .
wfMsg('templatecallupdate_errnopage', $page_name) . '</p>');
return;
}
$page_article = new Article($page_title);
$page_content = $page_article->fetchContent(0);
if (! $page_content) {
$wgOut->addHTML( '<p class="error">' .
wfMsg('templatecallupdate_errnocontent', $page_name) . '</p>');
return;
}
$out = $page_content; // Default to the original page content
if (preg_match("/^(.*\\{\\{" . $template_name . "\\s*(?:\\|.+)*\\|\
\s*)(" . $field_name . ")(\\s*=\\s*)([^\\}\\|\\n\\r]*)(.+)$/ms",
$page_content, $matches )) {
$out = $matches[1];
$out .= $matches[2];
$out .= '=';
$out .= $field_value;
$out .= $matches[5];
$summary = wfMsg( 'templatecallupdate_chgresult', $template_name,
$field_name, $matches[4], $field_value );
$page_article->doEdit( $out, $summary );
$wgOut->addHTML( '<p>' . $summary . '</p>' );
}
elseif (preg_match("/^(.*\\{\\{" . $template_name . "\\s*)([|}].+)$/
ms", $page_content, $matches )) {
$out = $matches[1];
$out .= '|' . $field_name . '=' . $field_value . "\n";
$out .= $matches[2];
$summary = wfMsg( 'templatecallupdate_addresult', $template_name,
$field_name, $field_value );
$page_article->doEdit( $out, $summary );
$wgOut->addHTML('<p>' . $summary . '</p>');
}
else
{
$wgOut->addHTML('<p class="error">' .
wfMsg('templatecallupdate_errresult', $template_name, $field_name,
$page_name) . '<br /><i>' . wfMsg('templatecallupdate_errresult2') .
'</i></p>');
return;
}
// Now, grab the latest revision and update the Semantic Mediawiki
Properties
$options = new ParserOptions();
if ( smwfIsSemanticsProcessed($page_title->getNamespace()) ) {
$revision = Revision::newFromTitle( $page_title );
if ( $revision === NULL ) continue;
$wgParser->parse($revision->getText(), $page_title, $options,
true, true, $revision->getID());
SMWFactbox::storeData(true);
$wgOut->addHTML('<p>' . wfMsg('templatecallupdate_updated') . '</
p>');
} else {
smwfGetStore()->deleteSubject($page_title);
$wgOut->addHTML(wfMsg('<p>' . 'templatecallupdate_cleared') . '</
p>');
}
$skin = $wgUser->getSkin();
$pageLink = $skin->makeKnownLinkObj( $page_title );
$wgOut->addHTML( '<p>' . wfMsg('templatecallupdate_viewpage') .
$pageLink . '</p>' );
}
}
Here's the source for TemplateCallUpdate.i18n.php:
<?php
$messages = array();
$messages['en'] = array(
'templatecallupdate' => 'Template Call Update',
'templatecallupdate_title' => 'Setting $1 to $2 in $3',
'templatecallupdate_errnotitleobj' => 'Error: Title Object not
returned for Page "$1".',
'templatecallupdate_errnopage' => 'Error: Page "$1" does not
exist',
'templatecallupdate_errnocontent' => 'Error: Page "$1" has no
content',
'templatecallupdate_errbadparam' => 'Error: Page ("$1"), template
("$2") or field name ("$3") is empty',
'templatecallupdate_chgresult' => 'Changed the value of $1:$2
from "$3" to "$4".',
'templatecallupdate_addresult' => 'Added $1:$2 with a value of
"$3".',
'templatecallupdate_errresult' => 'Unable to find field: $1:$2
on page: $3.',
'templatecallupdate_errresult2' => 'Please write down what you
were attempting to do, copy or save this message, and contact the site
administrator.',
'templatecallupdate_updated' => 'Properties updated',
'templatecallupdate_cleared' => 'Properties cleared',
'templatecallupdate_page' => 'Page name = $1',
'templatecallupdate_template' => 'Template name = $1',
'templatecallupdate_field' => 'Field name = $1',
'templatecallupdate_value' => 'Field value = $1',
'templatecallupdate_viewpage' => 'View updated page: ',
);