Revision [841]

This is an old revision of DreckFehler made by JsnX on 2004-08-01 15:49:59.

 

driving my own (german speaking) wakkawiki spin off called mindWiki, i have been fallen in love with the straight, compact code ;)

contact form

the following hacks and tweaks are based on WakkaWiki v. 1.2 (unless stated otherwisse). try to figure out yourself, where to put the changes in modified code ;)

discussion

if the config-value "pages_purge_time" is set to another value than zero (never purge), any revision will be deleted if a page is untouched for a while and modified after a period greater than the purge-time. due to this it's possible to destroy old pages which aren't modified frequently without any chance to recover it.

this flaw may be covered by the mechanism used in wikka wiki to mark minor changes as non cacheble and only cleanup only those pages(?). if not, there shold be a more sophisticated use of purging in the function $wakka->maintenance. any ideas?

Yes, this is good discussion item. Personally, I've never used "pages_purge_time", and had not given it much thought. It seems that we need another option such as purge_keep_limit, which will specify that at least x number of page revisions should be kept. What do you think? -- JsnX

ok, let's give it a try:

first alter the pages-table like this:

ALTER TABLE `wakka_pages` CHANGE `latest` `latest` ENUM( 'N', 'Y', 'B' ) DEFAULT 'N' NOT NULL


then refer to the $wakka-savepage() function and look for the following line:

<?php
$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_Escape_string($tag)."'");
?>


and expand it to this:

<?php
$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_Escape_string($tag)."'"); // unchanged, it sets all "b"-flagged rows to "n"
if ($threshold = $this->LoadSingle("select * from ".$this->config["table_prefix"]."pages where tag ='".mysql_Escape_string($tag)."' order by time desc limit 10,1")) { // maybe its better to use a variable like $wakka->config["keep_revisions"] for the "limit"-clause
    $this->Query("update ".$this->config["table_prefix"]."pages set latest = 'B' where tag = '".mysql_Escape_string($tag)."' and time > '".$threshold["time"]."'");
} else {
    $this->Query("update ".$this->config["table_prefix"]."pages set latest = 'B' where tag = '".mysql_Escape_string($tag)."'");
}
?>


looks ugly ;)

for mysql version 4.0.0 and later the following should fit:

<?php
$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_Escape_string($tag)."'");
$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'B' where tag = '".mysql_Escape_string($tag)."' order by time desc limit 10");
?>


leave the maintenance-function as is. it will treat only the "n"-flagged rows as usual. with every new revision the save-function will determine which versions should be protected by changing the flag to "b"

ready-to-use modifications:

bug in rendering of lists

if a list - ordered or unordered - is put at the very begining of a page (i.e. there is no text before that list), the first item of the list will not be recognized as a list-member, because the body is trimmed before saving. the bug is located in the function $wakka->savePage().

change this code-snippet

// add new revision
$this->Query("insert into ".$this->config["table_prefix"]."pages set ".
    "tag = '".mysql_escape_string($tag)."', ".
    ($comment_on ? "comment_on = '".mysql_escape_string($comment_on)."', " : "").
    "time = now(), ".
    "owner = '".mysql_escape_string($owner)."', ".
    "user = '".mysql_escape_string($user)."', ".
    "latest = 'Y', ".
    "body = '".mysql_escape_string(trim($body))."'");


to this one

// add new revision
if (preg_match("/^([\t]+)(-|([1aiAI]\))?)/", $body, $matches)) $lead = $matches[1]; // save tab(s) of first list-definition, if any at the begining
$body = $lead.trim($body); //and write it back to the trimmed body

$this->Query("insert into ".$this->config["table_prefix"]."pages set ".
    "tag = '".mysql_escape_string($tag)."', ".
    ($comment_on ? "comment_on = '".mysql_escape_string($comment_on)."', " : "").
    "time = now(), ".
    "owner = '".mysql_escape_string($owner)."', ".
    "user = '".mysql_escape_string($user)."', ".
    "latest = 'Y', ".
    "body = '".mysql_escape_string($body)."'"); // <<<<<<< trim() removed! we did it already


wikkawiki trims the body again, when it checks for changes in the edit.php before saving. so we have to do the same tweak there (otherwise nothing serious would happen, wikka would just save unchanged pages when they start with a list)

<?php
    // only save if new body differs from old body
    if (preg_match("/^([\t ]+)(-|([1aiAI]\))?)/", $body, $matches)) $lead = $matches[1]; // <<<<<<<<<<<< insert this line
    if ($lead.trim($body) != $this->page['body']) { // <<<<<<<<<<<< and the $lead in front of the actual body
?>

[Note: Forced links in square brackets is now fixed in Wikka by default starting with Wikka 1.1.3.1, thanks to Dreck.]
think about a [[forced link]] set into square brackets like this: [dreckfehler]. it wouldn't work without a trick, because wakkawiki don't know how to deal with three subsequent brackets. obviously it should render the innermost brackets but it takes the leftmost. to solve this behaviour we have to assure that the formatter uses only those opening brackets which are not followed by more square brackets. refer to the formatters/wakka.php and look for the huge regular expression which is stored in the variable $text and steers the parsing-process. change the line dealing with the forced links

the old version:
<?php
    "\[\[.*?\]\]|".
?>


and the new one:

<?php
    "\[\[[^\[].*?\]\]|".
?>


and you're done. the corresponding regex within the callback-function doesn't need any changes, because it will never get three subsequent opening brackets to match.

unnamed parameters

action googleform

[Note: The googleform action is now in Wikka by default starting with Wikka 1.1.3.1, thanks to Dreck.]

little stupid example for the unnamed parameters below ;) but it's sometimes quite useful. i leave such a googleform on every page that is considered "under construction". this gives me quick access to further research on a topic.

<?php if (!$q) $q = $this->tag(); ?>

<p><FORM action="http://www.google.com/search" method=get name=f target=_blank>
        <INPUT type=text value='<?=$q ?>' framewidth='4' name='q' size='30'> <INPUT name='btnG' type='submit' value='Google'>
</FORM>


save this snippet as "googleform.php" in the actions-folder. after that you can call anywhere {{googleform}} to show a searchform which is preset with the page-title. if you want to offer another search-term as default, call {{googleform q="wikkawiki"}}.

unnamed parameters

lots of actions need only one parameter and there is no need to distinguish it from others. additionally in some cases (like the googleform above) quotation marks are useful within the parameter, which isn't recognized by the action-api. the solution is to define an extra variable that contains the whole parameterstring. the old mechanism to pass over parameters (i.e. var_name="value") will still work.

we need to modify the function $wakka->Action():

old version (wikkawiki v. 1.1.3):

<?php
// stupid attributes check
if (stristr($action, "=\"")) {
    // extract $action and $vars_temp ("raw" attributes)
    preg_match("/^([A-Za-z0-9]*)(.*)$/", $action, $matches);
    list(, $action, $vars_temp) = $matches;

    // match all attributes (key and value)
    preg_match_all("/([A-Za-z0-9]*)=\"(.*)\"/U", $vars_temp, $matches);

    // prepare an array for extract() to work with (in $this->IncludeBuffered())
    if (is_array($matches)) {
        for ($a = 0; $a < count($matches[0]); $a++) {
            $vars[$matches[1][$a]] = $matches[2][$a];
            // ?? $vars[$a] = $matches[2][$a];
        }
    }
}
?>


modify it as follows:

<?php
// stupid attributes check
// if (stristr($action, "=\"")) { <<<<<<< this is not needed, we'll do this check in the following preg_match
    // extract $action and $vars_temp ("raw" attributes)
if (preg_match("/^([A-Za-z0-9]*)\s+(.*)$/", $action, $matches);) { // <<<<<<< treat everything after the first whitespace as parameter
    list(, $action, $vars_temp) = $matches;
    if (!$action) return "<span class='error'><i>unknown action, the action-name must not contain special chars!</i></span>"; // <<<<<<< the pattern ([A-Za-z0-9])\s+ didn't match!

    // match all attributes (key and value)
    preg_match_all("/([A-Za-z0-9]*)=\"(.*)\"/U", $vars_temp, $matches);

    // prepare an array for extract() to work with (in $this->IncludeBuffered())
    if (is_array($matches)) {
        for ($a = 0; $a < count($matches[0]); $a++) {
            $vars[$matches[1][$a]] = $matches[2][$a];
        }
    }
    $vars["wakka_vars"] = trim($vars_temp); // <<<<<<< add the buffered parameter-string to the array
}
?>


now we can refer to the whole parameter-string in $wakka_vars even if it doesn't follow the pattern var="value" ... how to treat this feature belongs to the actions itself.

let's have a look at the googleform-action from above:

<?php
    if (!$q) { //leave the old syntax untouched. you may omit this if-clause when you never used the former action-call (or want to change every appereance of it in your wiki ;) )
        if ($wakka_vars) $q = $wakka_vars;
        else $q = $this->tag();
    }
?>

<p><FORM action="http://www.google.com/search" method=get name=f target=_blank>
        <INPUT type=text value='<?=$q ?>' framewidth='4' name='q' size='30'> <INPUT name='btnG' type='submit' value='Google'>
</FORM>


now you can offer a more convinient syntax: {{googleform searchstring}}. even double-quotes are passed to the input field, i.e. {{googleform "search phrase"}} will search for a connected phrase instead of two separate words.
There is one comment on this page. [Display comment]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki