Wiki source for HtmlAreaEditing


Show raw source

HTMLAREA for Wakka

[Note: HTMLArea is now apparently a commercial product. The codebase that was the start of HTMLarea (and may have been opensourced) is now under the name Areaedit (see http://www.formvista.com/otherprojects/areaedit.html) - 19 Aug 05]


This is a patch for WakkaWiki coded by VictorManuelVarela.

WakkaWiki a lightweight WikiEngine powered by PHP and MySQL, and developed by Hendrik Mans and Carlo Zotman. Good job!


Download Wakka with HTMLAREA

File: wakka-with-htmlarea.tgz

Note: You must set "default_handler" to "html" to run HTMLAREA in new pages.


Steps to use HTMLAREA in existing Wakka Wikis
1. Patching wakka.php
diff file for wakka.php:
%%(php)
*** ../wakka-subversion/wakka.php Wed Jan 21 17:26:49 2004
--- wakka.php Thu Jan 22 11:01:31 2004
***************
*** 120,126 ****
function LoadPageTitles() { return $this->LoadAll("select distinct tag from ".$this->config["table_prefix"]."pages order by tag"); }
function LoadAllPages() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' order by tag"); }
function FullTextSearch($phrase) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' and match(tag, body) against('".mysql_escape_string($phrase)."')"); }
! function SavePage($tag, $body, $comment_on = "")
{
// get current user
$user = $this->GetUserName();
--- 120,126 ----
function LoadPageTitles() { return $this->LoadAll("select distinct tag from ".$this->config["table_prefix"]."pages order by tag"); }
function LoadAllPages() { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' order by tag"); }
function FullTextSearch($phrase) { return $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where latest = 'Y' and match(tag, body) against('".mysql_escape_string($phrase)."')"); }
! function SavePage($tag, $body, $comment_on = "", $handler="page")
{
// get current user
$user = $this->GetUserName();
***************
*** 163,168 ****
--- 163,169 ----
"owner = '".mysql_escape_string($owner)."', ".
"user = '".mysql_escape_string($user)."', ".
"latest = 'Y', ".
+ "handler = '".mysql_escape_string($handler)."', ".
"body = '".mysql_escape_string(trim($body))."'");
}
}
***************
*** 352,358 ****
{
$method = substr($method, strrpos('/', $method));
}
! if (!$handler = $this->page["handler"]) $handler = "page";
$methodLocation = $handler."/".$method.".php";
return $this->IncludeBuffered($methodLocation, "<i>Unknown method \"$methodLocation\"</i>", "", $this->config["handler_path"]);
}
--- 353,359 ----
{
$method = substr($method, strrpos('/', $method));
}
! if (!$handler = $this->page["handler"]) $handler = $this->config["default_handler"];
$methodLocation = $handler."/".$method.".php";
return $this->IncludeBuffered($methodLocation, "<i>Unknown method \"$methodLocation\"</i>", "", $this->config["handler_path"]);
}
***************
*** 590,595 ****
--- 591,597 ----

"action_path" => "actions",
"handler_path" => "handlers",
+ "default_handler" => "page",

"header_action" => "header",
"footer_action" => "footer",
%%

Explanation:

search the ""SavePage()"" function, add a new $handler param (with "page" default value) and add a line in SQL insert command: handler = '$handler'
search the Method function, modify ($handler = "page") to ($handler = $this->config["default_handler"]
search the $wakkaConfig default value, add ("default_handler" => "page",)


2. Adding html formatter

formatters/html.php:
%%(php)
<?php

// This may look a bit strange, but all possible formatting tags have to be in a single regular expression for this to work correctly. Yup!

if (!function_exists("wakka2callback"))
{
function wakka2callback($things)
{
$thing = $things[1];

global $wakka;

// forced links
if (preg_match("/^\[\[(\S*)(\s+(.+))?\]\]$/", $thing, $matches))
{
list (, $url, , $text) = $matches;
if ($url)
{
if (!$text) $text = $url;
return $wakka->Link($url, "", $text);
}
else
{
return "";
}
}
// events
else if (preg_match("/^\{\{(.*?)\}\}$/s", $thing, $matches))
{
if ($matches[1])
return $wakka->Action($matches[1]);
else
return "{{}}";
}
// interwiki links!
else if (preg_match("/^[A-Z,ÄÖÜ][A-Z,a-z,ÄÖÜ,ßäöü]+[:]([A-Z,a-z,0-9,ÄÖÜ,ßäöü]*)$/s", $thing))
{
return $wakka->Link($thing);
}
// wakka links!
else if (preg_match("/^[A-Z,ÄÖÜ][a-z,ßäöü]+[A-Z,0-9,ÄÖÜ][A-Z,a-z,0-9,ÄÖÜ,ßäöü]*$/s", $thing))
{
return $wakka->Link($thing);
}
// if we reach this point, it must have been an accident.
return $thing;
}
}

$text = str_replace("\r", "", $text);
$text = trim($text)."\n";
$text = preg_replace_callback(
"/(\[\[.*?\]\]|\b[a-z]+:\/\/\S+|\n\t+(-|[0-9,a-z,A-Z]+\))?|\{\{.*?\}\}|".
"\b[A-Z,ÄÖÜ][A-Z,a-z,ÄÖÜ,ßäöü]+[:]([A-Z,a-z,0-9,ÄÖÜ,ßäöü]*)\b|".
"\b([A-Z,ÄÖÜ][a-z,ßäöü]+[A-Z,0-9,ÄÖÜ][A-Z,a-z,0-9,ÄÖÜ,ßäöü]*)\b|".
"\n)/ms", "wakka2callback", $text);

// we're cutting the last <br>
$text = preg_replace("/<br \/>$/", "", trim($text));
print($text);
?>
%%

Explanation:

delete all HTML related stuff to show html as is.
delete all Wiki related stuff (except WakkaLinks and WakkaActions)



3. Adding html handler

Copy handlers/page/* into handlers/html/*.
The files you must change is edit.php and show.php.

diff file for handlers/html/edit.php:
%%(php)
*** ../page/edit.php Wed Jan 21 17:26:57 2004
--- edit.php Thu Jan 22 10:31:31 2004
***************
*** 29,41 ****
// only save if new body differs from old body
if (trim($body) != $this->page['body']) {
// add page (revisions)
! $this->SavePage($this->tag, $body);

// now we render it internally so we can write the updated link table.
$this->ClearLinkTable();
$this->StartLinkTracking();
$dummy = $this->Header();
! $dummy .= $this->Format($body);
$dummy .= $this->Footer();
$this->StopLinkTracking();
$this->WriteLinkTable();
--- 29,41 ----
// only save if new body differs from old body
if (trim($body) != $this->page['body']) {
// add page (revisions)
! $this->SavePage($this->tag, $body,'','html');

// now we render it internally so we can write the updated link table.
$this->ClearLinkTable();
$this->StartLinkTracking();
$dummy = $this->Header();
! $dummy .= $this->Format($body,'html');
$dummy .= $this->Footer();
$this->StopLinkTracking();
$this->WriteLinkTable();
***************
*** 67,73 ****
"<input type=\"hidden\" name=\"previous\" value=\"".$previous."\" />\n".
"<input type=\"hidden\" name=\"body\" value=\"".htmlspecialchars($body)."\" />\n";

! $output .= $this->Format($body);

$output .=
"<br />\n".
--- 67,73 ----
"<input type=\"hidden\" name=\"previous\" value=\"".$previous."\" />\n".
"<input type=\"hidden\" name=\"body\" value=\"".htmlspecialchars($body)."\" />\n";

! $output .= $this->Format($body,'html');

$output .=
"<br />\n".
***************
*** 88,101 ****
$body = trim($body)."\n\n----\n\n--".$this->UserName()." (".strftime("%c").")";
}

$output .=
$this->FormOpen("edit").
"<input type=\"hidden\" name=\"previous\" value=\"".$previous."\" />\n".
! "<textarea onKeyDown=\"fKeyDown()\" name=\"body\" style=\"width: 100%; height: 400px\">".htmlspecialchars($body)."</textarea><br />\n".
"<input name=\"submit\" type=\"submit\" value=\"Store\" accesskey=\"s\" /> <input name=\"submit\" type=\"submit\" value=\"Preview\" accesskey=\"p\" /> <input type=\"button\" value=\"Cancel\" onClick=\"document.location='".$this->href("")."';\" />\n".
$this->FormClose();
}


print($output);
}
--- 88,117 ----
$body = trim($body)."\n\n----\n\n--".$this->UserName()." (".strftime("%c").")";
}

+ $output .=
+ '<script language="JavaScript" src="'.$this->config['base_url'].'/htmlarea/htmlarea.js"></script>'."\n".
+ '<script language="JavaScript" src="'.$this->config['base_url'].'/htmlarea/dialog.js"></script>'."\n".
+ '<script language="JavaScript" src="'.$this->config['base_url'].'/htmlarea/popups/en/htmlarea-lang.js"></script>'."\n";
+
$output .=
$this->FormOpen("edit").
"<input type=\"hidden\" name=\"previous\" value=\"".$previous."\" />\n".
! "<textarea onKeyDown=\"fKeyDown()\" id=\"body\" name=\"body\" style=\"width: 100%; height: 400px\">".htmlspecialchars($body)."</textarea><br />\n".
"<input name=\"submit\" type=\"submit\" value=\"Store\" accesskey=\"s\" /> <input name=\"submit\" type=\"submit\" value=\"Preview\" accesskey=\"p\" /> <input type=\"button\" value=\"Cancel\" onClick=\"document.location='".$this->href("")."';\" />\n".
$this->FormClose();
}

+ $output .= "<script language=\"JavaScript\">\n".
+ "<!--\n".
+ "var editor=new HTMLArea(\"body\");\n".
+ "editor.config.editorURL = \"{$this->config['base_url']}/htmlarea/\";\n".
+ "editor.config.imgURL = \"images/\";\n".
+ "editor.config.popupURL = \"popups/en/\";\n".
+ "editor.config.bodyDirection = \"ltr\";\n".
+ 'editor.config.toolbar = [[ "formatblock", "space", "bold", "italic", "underline", "separator", "copy", "cut", "paste", "space", "undo", "redo", "separator", "justifyleft", "justifycenter", "justifyright", "justifyfull", "separator", "insertorderedlist", "insertunorderedlist", "outdent", "indent", "separator", "forecolor", "separator", "inserthorizontalrule", "createlink", "insertimage", "inserttable" ]];'."\n".
+ "editor.generate();\n".
+ "//-->\n".
+ "</script>\n";

print($output);
}
%%

%%(php)
diff file for handlers/html/show.php:
*** show.php Thu Jan 22 13:18:40 2004
--- showht.php Thu Jan 22 13:15:26 2004
***************
*** 21,27 ****


// display page
! print($this->Format($this->page["body"], "wakka"));

// if this is an old revision, display some buttons
if ($this->HasAccess("write") && ($this->page["latest"] == "N"))
--- 21,27 ----


// display page
! print($this->Format($this->page["body"], "html"));

// if this is an old revision, display some buttons
if ($this->HasAccess("write") && ($this->page["latest"] == "N"))
%%

Explanation:

add 'html' to ""SavePage()"" call.
insert javascript links to htmlarea.js, dialog.js, and popups/en/htmlarea-lang.js before textarea
insert javascript code to init HTMLArea
change 'wakka' to 'html' in Format call (when formatting body).


4. Install HTMLAREA into your wakka root path

Download htmlarea.tgz

HTMLAREA is an easy JavaScript WYSIWYG editor created by Interactive Tools



5. Add classes for HTMLAREA in your wakka.css

%%
.htmlarea { background: #fff; }

.htmlarea .toolbar {
cursor: default;
background: #F8F8F8;
padding: 3px;
}
.htmlarea .toolbar table { font-family: tahoma,verdana,sans-serif; font-size: 11px; }
.htmlarea .toolbar img { border: none; }
.htmlarea .toolbar .label { padding: 0px 3px; }

.htmlarea .toolbar .button {
background: #F8F8F8;
color: ButtonText;
border: 1px solid #F8F8F8;
padding: 1px;
margin: 0px;
}
.htmlarea .toolbar .buttonHover {
border: 1px solid;
border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
}
.htmlarea .toolbar .buttonActive, .htmlarea .toolbar .buttonPressed {
padding: 2px 0px 0px 2px;
border: 1px solid;
border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
}
.htmlarea .toolbar .buttonPressed {
background: ButtonHighlight;
}
.htmlarea .toolbar .indicator {
padding: 0px 3px;
overflow: hidden;
width: 20px;
text-align: center;
cursor: default;
border: 1px solid ButtonShadow;
}

.htmlarea .toolbar .buttonDisabled { background-color: #aaa; }

.htmlarea .toolbar .buttonDisabled img {
filter: alpha(opacity = 25);
-moz-opacity: 25%;
}

.htmlarea .toolbar .separator {
position: relative;
margin: 3px;
border-left: 1px solid ButtonShadow;
border-right: 1px solid ButtonHighlight;
width: 0px;
height: 16px;
padding: 0px;
}

.htmlarea .toolbar .space { width: 5px; }

.htmlarea .toolbar select { font: 11px Tahoma,Verdana,sans-serif; }

.htmlarea .toolbar select,
.htmlarea .toolbar select:hover,
.htmlarea .toolbar select:active { background: FieldFace; color: ButtonText; }

.htmlarea .statusBar {
border: 1px solid;
border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
padding: 2px 4px;
background-color: ButtonFace;
color: ButtonText;
font: 11px Tahoma,Verdana,sans-serif;
}

.htmlarea .statusBar .statusBarTree a {
padding: 2px 5px;
color: #00f;
}

.htmlarea .statusBar .statusBarTree a:visited { color: #00f; }
.htmlarea .statusBar .statusBarTree a:hover {
background-color: Highlight;
color: HighlightText;
padding: 1px 4px;
border: 1px solid HighlightText;
}


/* Hidden DIV popup dialogs (PopupDiv) */

.dialog {
color: ButtonText;
background: ButtonFace;
}

.dialog .content { padding: 2px; }

.dialog, .dialog button, .dialog input, .dialog select, .dialog textarea, .dialog table {
font: 11px Tahoma,Verdana,sans-serif;
}

.dialog table { border-collapse: collapse; }

.dialog .title {
background: #008;
color: #ff8;
border-bottom: 1px solid #000;
padding: 1px 0px 2px 5px;
font-size: 12px;
font-weight: bold;
cursor: default;
}

.dialog .title .button {
float: right;
border: 1px solid #66a;
padding: 0px 1px 0px 2px;
margin-right: 1px;
color: #fff;
text-align: center;
}

.dialog .title .button-hilite { border-color: #88f; background: #44c; }

.dialog button {
width: 5em;
padding: 0px;
}

.dialog .buttonColor {
padding: 1px;
cursor: default;
border: 1px solid;
border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
}

.dialog .buttonColor-hilite {
border-color: #000;
}

.dialog .buttonColor .chooser, .dialog .buttonColor .nocolor {
height: 0.6em;
border: 1px solid;
padding: 0px 1em;
border-color: ButtonShadow ButtonHighlight ButtonHighlight ButtonShadow;
}

.dialog .buttonColor .nocolor { padding: 0px; }
.dialog .buttonColor .nocolor-hilite { background-color: #fff; color: #f00; }

.dialog .label { text-align: right; width: 6em; }
.dialog .value input { width: 100%; }
.dialog .buttons { text-align: right; padding: 2px 4px 0px 4px; }

.dialog legend { font-weight: bold; }
.dialog fieldset table { margin: 2px 0px; }

.popupdiv {
border: 2px solid;
border-color: ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight;
}

.popupwin {
padding: 0px;
margin: 0px;
}

.popupwin .title {
background: #fff;
color: #000;
font-weight: bold;
font-size: 120%;
padding: 3px 10px;
margin-bottom: 10px;
border-bottom: 1px solid black;
letter-spacing: 2px;
}
%%


6. Set your wakka.config.php

Set the new default_handler to "html" to activate HTMLAREA in new pages.
To change an existing page to HTML handler you must run the next query:

UPDATE wakka_pages
SET handler = 'html'
WHERE tag = '""ExistingPage""' AND latest = 'Y'



Esta página no tiene comentarios. [Mostrar comentarios/formulario]
- Ultima version: 2004-01-22 12:50:14
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki