Tuesday, February 07, 2006

Paul aka Wiki Wookie on php & wiki


Why do I think phpWiki is the way to go?

There are lots of modules out there, and it can be devilishly difficult to pick between them. But there are some good rules of thumb you can use to pick the future winner...
1) Features
2) Quality of the Code

Is the module feature-rich and you need a lot of features? Or does it do a few things very well?

I stray away from PHP Modules that's written in spaghetti code. Too bug-prone, and a headache to keep maintaining, and code that is this badly written rarely get better over time. On the other hand, if code is written using the newest and best practices, consistently, and professionally, that's the module I tend to stick with.

phpWiki passes both criteria with flying colors. It allows you to plug-in RSS feeds, images, searches, Google, IMDB, Calendars, Weather, XML, FOAF, RDF, SOAP, Rich Tables, XML. It already has most of the features built-in that we are looking for.

But what really took my breath away was the quality of the code. I've seen programs approach it, but this is world-class stuff.
- It's internationalized, using the ISO standard coverying glyphs in many different languages.
- It uses Templating, XML, Cascading Style sheets for the presentation layer. It has a themes folder with templates, that is exensible in every way.
- It works with different databases, and file-based db modules.
- It uses a configuration file for specifics. The coding conventions are consistent, and this is a very large program too.
- It intercepts what comes into and what leaves a browser, it is mult-browser compatible and detects what browser it uses.
- It is w3c standards-savvy. Uses namespaces, xhtml, xml schemas, different MIME types.
- It handles many different types of authentication, from http_auth to LDAP to database-centric.
- It takes the object-oriented methodology as far as it goes in php.
- It is caching, and configurable about caching.
- It is self-regulating, it downloads new versions of modules, and handle conflicts. This is scary stuff for most programmers.

Here is a code sample that epitomizes its style...
from plugin/EditMetaData.php -> extends standard plugin class.
*
* This will give you an idea how big the whole system is, cause there are lots of object references here.
* It also shows you how modular it is, using a common function called pushContent, which is used to build xml trees as well as html.

function run($dbi, $argstr, &$request, $basepage) { $this->_args = $this->getArgs($argstr, $request); extract($this->_args); if (!$page) return '';

$hidden_pagemeta = array ('_cached_html'); $readonly_pagemeta = array ('hits'); $dbi = $request->getDbh(); $p = $dbi->getPage($page); $pagemeta = $p->getMetaData();

// Look at arguments to see if submit was entered. If so, // process this request before displaying. // if ($request->isPost() and $request->_user->isAdmin() and $request->getArg('metaedit')) { $metafield = trim($request->getArg('metafield')); $metavalue = trim($request->getArg('metavalue')); if (!in_array($metafield, $readonly_pagemeta)) { if (preg_match('/^(.*?)\[(.*?)\]$/', $metafield, $matches)) { list(,$array_field, $array_key) = $matches; $array_value = $pagemeta[$array_field]; $array_value[$array_key] = $metavalue; $p->set($array_field, $array_value); } else { $p->set($metafield, $metavalue); } } $dbi->touch(); $url = $request->getURLtoSelf(false, array('metaedit','metafield','metavalue')); $request->redirect($url); // The rest of the output will not be seen due to the // redirect.

}

// Now we show the meta data and provide entry box for new data.

$html = HTML();

$html->pushContent(fmt("Existing page-level metadata for %s:", $page)); $dl = HTML::dl(); foreach ($pagemeta as $key => $val) { if (is_string($val) and (substr($val,0,2) == 'a:')) { $dl->pushContent(HTML::dt("\n$key => $val\n", $dl1 = HTML::dl())); foreach (unserialize($val) as $akey => $aval) { $dl1->pushContent(HTML::dt(HTML::strong("$key" . '[' . $akey . "] => $aval\n")) ); } $dl->pushContent($dl1); } elseif (is_array($val)) { $dl->pushContent(HTML::dt("\n$key:\n", $dl1 = HTML::dl())); foreach ($val as $akey => $aval) { $dl1->pushContent(HTML::dt(HTML::strong("$key" . '[' . $akey . "] => $aval\n")) ); } $dl->pushContent($dl1); } elseif (in_array($key,$hidden_pagemeta)) { ; } elseif (in_array($key,$readonly_pagemeta)) { $dl->pushContent(HTML::dt(array('style' => 'background: #dddddd'), "$key => $val\n")); } else { $dl->pushContent(HTML::dt(HTML::strong("$key => $val\n"))); } } $html->pushContent($dl);

if ($request->_user->isAdmin()) { $action = $request->getPostURL(); $hiddenfield = HiddenInputs($request->getArgs()); $instructions = _("Add or change a page-level metadata 'key=>value' pair. Note that you can remove a key by leaving the value-box empty."); $keyfield = HTML::input(array('name' => 'metafield'), ''); $valfield = HTML::input(array('name' => 'metavalue'), ''); $button = Button('submit:metaedit', _("Submit"), false); $form = HTML::form(array('action' => $action, 'method' => 'post', 'accept-charset' => $GLOBALS['charset']), $hiddenfield, $instructions, HTML::br(), $keyfield, ' => ', $valfield, HTML::raw(' '), $button );

$html->pushContent(HTML::br(), $form); } else { $html->pushContent(HTML::em(_("Requires WikiAdmin privileges to edit."))); } return $html; }

0 Comments:

Post a Comment

<< Home