Revision [2713]
This is an old revision of IncludeRemote made by DarTar on 2004-12-01 12:46:21.
Fetching Remote Wikka Content
An interesting solution for making freshly-updated HelpInfo wikka documentation available to end users, without distributing the whole documentation package, might be to create a {{fetchremote page="PageName"}} plugin allowing to retrieve content from the main wikka server, using something like the raw method.
The idea
Here's how it might function:
- the user of a wikka distribution opens a local WikkaDocumentation page containing {{fetchremote page="HelpInfo"}};
- the plugin connects to the main wikka server,
- it fetches a raw version of HelpInfo with no header and footer (i.e. the mere page content in wikka syntax),
- it parses the fetched page for internal links and translates them into local links to fetchable pages (links pointing to remote URLs need not be translated),
- and finally, it prints locally the documentation contents.
- if a connection is not available, a splash page with a static link to http://wikka.jsnx.com/HelpInfo and a short text is printed;
A similar plugin might be used also for bug notifications and other kinds of "centralized" content.
Notes:
- Basically, the idea is to make the main Wikka site work as a server providing wikka-formatted content to Wikka-clients. There are several advantages in this approach, compared to merely fetching HTML:
- the fetched content integrates seamlessly with the layout and structure of the Wikka-client;
- the user can choose to download locally a fetched page, so as to make it available in its Wikka site.
- no MySQL connection to the central database is needed, provided that a method exists for retrieving pure page content with the header and footer stripped;
- when displaying locally a remote page, a box (like a grey float at the top of each fetched page) should alert the user that he is actually retrieving remote content. Otherwise the risk is to be "trapped" on the main wikka server without realizing it!
- when local and remote pages with the same name exist, the user should be given the choice which of the two pages he wants to display.
Screenshot:
http://wikka.jsnx.com/images/fetchremote.jpgNow, here comes some code.
FetchRemote: a plugin for fetching remote documentation
FetchRemote Action
Version 0.4
What it does
- Connects to the main Wikka server and fetches Wikka Documentation Pages
A "rawcontent" method must be available on the main Wikka server, in order to produce raw wikka-formatted content with header and footer stripped
- Displays an error message if remote pages do not exist on the server or if a connection is not available
- Parses the fetched page and rewrites links as links to fetchable pages
- Prints the fetched page locally, together with a header
- Allows fetched pages to be safely stored on the Wikka client
- If a page with the same name exists on the Wikka client, show a "see local version" button instead of the "download" button
How to use it
Simply add {{fetchremote}} in one of your pages.You can specify a starting page by adding: {{fetchremote page="HomePage"}}
Note
Remote fetching of pages through fopen() must be allowed by php (by default it is).Todo:
- Forced link rewriting: done - check regex for consistency with wikka formatters
- CamelCase link rewriting: done - check regex for consistency with wikka formatters
- Interwiki link rewriting
Here's a three-step installation:
1. Create on the target server a rawcontent handler (handlers/page/rawcontent.php)
<?php
if ($this->HasAccess("read")) {
if (!$this->page) {
return;
} else {
// display raw page
print($this->page["body"]);
}
} else {
return;
}
?>
if ($this->HasAccess("read")) {
if (!$this->page) {
return;
} else {
// display raw page
print($this->page["body"]);
}
} else {
return;
}
?>
2. Update wikka.php on the target server
The following blocks of code must be modified to enable the rawcontent handler:
A)
original
if (preg_match('/\.(xml|mm)$/', $this->method)) {
header("Content-type: text/xml");
print($this->Method($this->method));
}
header("Content-type: text/xml");
print($this->Method($this->method));
}
modified
if (preg_match('/\.(xml|mm)$/', $this->method)) {
header("Content-type: text/xml");
print($this->Method($this->method));
}
// rawcontent method
elseif ($this->method == "rawcontent"){
header("Content-type: text/plain");
print($this->Method($this->method));
}
header("Content-type: text/xml");
print($this->Method($this->method));
}
// rawcontent method
elseif ($this->method == "rawcontent"){
header("Content-type: text/plain");
print($this->Method($this->method));
}
B)
original
// if (!preg_match("/\.(xml|raw|mm)$/", $method))
{
$tend = getmicrotime();
//Calculate the difference
$totaltime = ($tend - $tstart);
//Output result
printf ("<div class=\"smallprint\">Page was generated in %.4f seconds</div>\n</body>\n</html>", $totaltime);
}
{
$tend = getmicrotime();
//Calculate the difference
$totaltime = ($tend - $tstart);
//Output result
printf ("<div class=\"smallprint\">Page was generated in %.4f seconds</div>\n</body>\n</html>", $totaltime);
}
modified
if (!preg_match("/(xml|raw|mm|rawcontent)$/", $method))
{
$tend = getmicrotime();
//Calculate the difference
$totaltime = ($tend - $tstart);
//Output result
printf ("<div class=\"smallprint\">Page was generated in %.4f seconds</div>\n</body>\n</html>", $totaltime);
}
{
$tend = getmicrotime();
//Calculate the difference
$totaltime = ($tend - $tstart);
//Output result
printf ("<div class=\"smallprint\">Page was generated in %.4f seconds</div>\n</body>\n</html>", $totaltime);
}
3. Create in the Wikka client a FetchRemote action (actions/fetchremote.php)
<?php
// FetchRemote Action
// Written by DarTar <http://wikka.jsnx.com/DarTar>
// Version 0.4
//
// * Connects to the main Wikka server and fetches Wikka Documentation Pages
// (a "rawcontent" method must be available on the main Wikka server, in order to produce
// raw wikka-formatted content with header and footer stripped).
// * Displays an error message if remote pages do not exist on the server or if a connection is not available
// * Parses the fetched page and rewrites links as links to fetchable pages
// * Prints the fetched page locally, together with a header
// * Allows fetched pages to be safely stored on the Wikka client
//
// Parameters: page - specifies starting page on the remote server
// Set remote Wikka server root
//$remote_server_root = "http://wikka.jsnx.com/";
// debugging
$remote_server_root="http://test/wikka-1.1.5.0/wikka.php?wakka=";
//set default remote page if no page parameter or GET value is specified
$page = $_REQUEST["page"]? $_REQUEST["page"] : $page;
if ($page == "") $page = "HelpInfo";
// redirect to home on disconnection
if ($_POST["action"] == "Disconnect") $this->Redirect($this->GetConfigValue("root_page"));
// open connection
$remote_page = fopen($remote_server_root.$page."/rawcontent", "r");
if (!$remote_page) {
// connection failed: print static link
echo $this->Format("=====Wikka Documentation===== --- Visit the **[[http://wikka.jsnx.com/HelpInfo Wikka Documentation Project]]** --- --- ");
} else {
// connection established: start fetching remote page
// fetch rawcontent of remote page
while (!feof($remote_page)) {
$content .= fgets($remote_page, 1024);
}
// header style
$style = "text-align: center; margin: 30px 25%; border: 1px dotted #333; background-color: #EEE; padding: 5px;";
if (!$content) {
// missing page: show error message
$header = "Sorry, **";
$header .= "\"\"<a href='".$this->Href("","","page=".$page)."'>".$page."</a>\"\"";
$header .= "** cannot be found on the [[".$remote_server_root.$page." Wikka server]]! --- Return to the **[[".$this->GetPageTag()." Wikka Documentation Project]]** --- ";
$form = "";
} else {
// regex pattern for forced links to internal pages
$forced = "/\[\[([^ \/]+) ([^\]]+)\]\]/";
// regex pattern for CamelCase links
$camel = "/[^a-z=>\"\[\/\{]([A-Z]+[a-z]+[A-Z][A-Za-z0-9]+)+/";
// rewrite forced links
$content = preg_replace($forced, "\"\"<a href='".$this->Href("","","page=\\1")."'>\\2</a>\"\"", $content);
// rewrite camelcase links
$content = preg_replace($camel, "\"\" <a href='".$this->Href("","","page=\\1")."'>\\1</a>\"\"", $content);
if ($_POST["action"] == "Download this page") {
// trying to save page
if ($this->LoadPage($page)) {
// local page with this name already exists => display error message
// in the future we might show a form to ask if local version should be overwritten
$header = "@@Sorry, a page named **[[".$page."]]** already exists on this site!@@ --- ";
$form = $this->FormOpen()."<input type='submit' name='action' value='Return to Wikka Documentation' /><input type='submit' name='action' value='Disconnect' />".$this->FormClose();
} else {
// local page does not exist => proceed
// write page to database and display message
$note = "fetched from the Wikka server";
$this->SavePage($page, $content, $note);
$header = "@@This page is now available on your site!@@ --- ";
$form = $this->FormOpen()."<input type='hidden' name='page' value='".$page."' /><input type='submit' name='action' value='See local version' /><input type='submit' name='action' value='Return to Wikka Documentation' />".$this->FormClose();
}
} else if ($_POST["action"] == "See local version") {
// switch to local version of the page
$this->Redirect($page);
} else {
// main header & form
$header = "You are currently browsing: **";
$header .= "\"\"<a href='".$this->Href("","","page=".$page)."'>".$page."</a>\"\"";
$header .= "** --- from the **[[".$this->GetPageTag()." Wikka Documentation Project]]** --- (fetched from the [[".$remote_server_root.$page." Wikka server]])";
$buttontext = ($this->LoadPage($page))? "See local version" : "Download this page";
$form = $this->FormOpen()."<input type='hidden' name='page' value='".$page."' /><input type='submit' name='action' value='".$buttontext."' /><input type='submit' name='action' value='Disconnect' />".$this->FormClose();
}
}
// last step: print header and rewritten content
print "<div style='".$style."'>".$this->Format($header).$form."</div>".$this->Format($content);
}
fclose($remote_page);
?>
<?php
// LINK REWRITING PLAYGROUND
/*
echo $this->Format("=====Link Translation Test===== --- --- (Source: ".$remote_server_root.$page.") --- --- ");
if (preg_match_all($forced, $content, $forcedlinks)) {
echo $this->Format("==Forced links:==");
foreach ($forcedlinks[0] as $fkey => $fitem) {
$ftag = $forcedlinks[1][$fkey];
$fanchor = $forcedlinks[2][$fkey];
// display link and rewritten link
echo $this->Format($fkey.": ".$fitem." => ")."<a href='".$this->Href("","","page=".$ftag)."'>".$fanchor."</a><br />";
// add rewritten link to array
$fsearch[$fkey] = $fitem;
$freplace[$fkey] = "\"\"<a href='".$this->Href("","","page=".$ftag)."'>".$fanchor."</a>\"\"";
}
// rewrite forced links
//$content = preg_replace($fsearch, $freplace, $content);
}
if (preg_match_all($camel, $content, $camellinks)) {
echo $this->Format(" --- ==Camelcase links:==");
foreach ($camellinks[0] as $ckey => $citem) {
$citem = ltrim($citem);
echo $this->Format($ckey.": ".$citem." => ")."<a href='".$this->Href("","","page=".$citem)."'>".$citem."</a><br />";
$csearch[$ckey] = $citem;
$creplace[$ckey] = " \"\"<a href='".$this->Href("","","page=".$citem)."'>".$citem."</a>\"\"";
}
// rewrite CamelCase links
//$content = preg_replace($csearch, $creplace, $content);
}
*/
?>
// FetchRemote Action
// Written by DarTar <http://wikka.jsnx.com/DarTar>
// Version 0.4
//
// * Connects to the main Wikka server and fetches Wikka Documentation Pages
// (a "rawcontent" method must be available on the main Wikka server, in order to produce
// raw wikka-formatted content with header and footer stripped).
// * Displays an error message if remote pages do not exist on the server or if a connection is not available
// * Parses the fetched page and rewrites links as links to fetchable pages
// * Prints the fetched page locally, together with a header
// * Allows fetched pages to be safely stored on the Wikka client
//
// Parameters: page - specifies starting page on the remote server
// Set remote Wikka server root
//$remote_server_root = "http://wikka.jsnx.com/";
// debugging
$remote_server_root="http://test/wikka-1.1.5.0/wikka.php?wakka=";
//set default remote page if no page parameter or GET value is specified
$page = $_REQUEST["page"]? $_REQUEST["page"] : $page;
if ($page == "") $page = "HelpInfo";
// redirect to home on disconnection
if ($_POST["action"] == "Disconnect") $this->Redirect($this->GetConfigValue("root_page"));
// open connection
$remote_page = fopen($remote_server_root.$page."/rawcontent", "r");
if (!$remote_page) {
// connection failed: print static link
echo $this->Format("=====Wikka Documentation===== --- Visit the **[[http://wikka.jsnx.com/HelpInfo Wikka Documentation Project]]** --- --- ");
} else {
// connection established: start fetching remote page
// fetch rawcontent of remote page
while (!feof($remote_page)) {
$content .= fgets($remote_page, 1024);
}
// header style
$style = "text-align: center; margin: 30px 25%; border: 1px dotted #333; background-color: #EEE; padding: 5px;";
if (!$content) {
// missing page: show error message
$header = "Sorry, **";
$header .= "\"\"<a href='".$this->Href("","","page=".$page)."'>".$page."</a>\"\"";
$header .= "** cannot be found on the [[".$remote_server_root.$page." Wikka server]]! --- Return to the **[[".$this->GetPageTag()." Wikka Documentation Project]]** --- ";
$form = "";
} else {
// regex pattern for forced links to internal pages
$forced = "/\[\[([^ \/]+) ([^\]]+)\]\]/";
// regex pattern for CamelCase links
$camel = "/[^a-z=>\"\[\/\{]([A-Z]+[a-z]+[A-Z][A-Za-z0-9]+)+/";
// rewrite forced links
$content = preg_replace($forced, "\"\"<a href='".$this->Href("","","page=\\1")."'>\\2</a>\"\"", $content);
// rewrite camelcase links
$content = preg_replace($camel, "\"\" <a href='".$this->Href("","","page=\\1")."'>\\1</a>\"\"", $content);
if ($_POST["action"] == "Download this page") {
// trying to save page
if ($this->LoadPage($page)) {
// local page with this name already exists => display error message
// in the future we might show a form to ask if local version should be overwritten
$header = "@@Sorry, a page named **[[".$page."]]** already exists on this site!@@ --- ";
$form = $this->FormOpen()."<input type='submit' name='action' value='Return to Wikka Documentation' /><input type='submit' name='action' value='Disconnect' />".$this->FormClose();
} else {
// local page does not exist => proceed
// write page to database and display message
$note = "fetched from the Wikka server";
$this->SavePage($page, $content, $note);
$header = "@@This page is now available on your site!@@ --- ";
$form = $this->FormOpen()."<input type='hidden' name='page' value='".$page."' /><input type='submit' name='action' value='See local version' /><input type='submit' name='action' value='Return to Wikka Documentation' />".$this->FormClose();
}
} else if ($_POST["action"] == "See local version") {
// switch to local version of the page
$this->Redirect($page);
} else {
// main header & form
$header = "You are currently browsing: **";
$header .= "\"\"<a href='".$this->Href("","","page=".$page)."'>".$page."</a>\"\"";
$header .= "** --- from the **[[".$this->GetPageTag()." Wikka Documentation Project]]** --- (fetched from the [[".$remote_server_root.$page." Wikka server]])";
$buttontext = ($this->LoadPage($page))? "See local version" : "Download this page";
$form = $this->FormOpen()."<input type='hidden' name='page' value='".$page."' /><input type='submit' name='action' value='".$buttontext."' /><input type='submit' name='action' value='Disconnect' />".$this->FormClose();
}
}
// last step: print header and rewritten content
print "<div style='".$style."'>".$this->Format($header).$form."</div>".$this->Format($content);
}
fclose($remote_page);
?>
<?php
// LINK REWRITING PLAYGROUND
/*
echo $this->Format("=====Link Translation Test===== --- --- (Source: ".$remote_server_root.$page.") --- --- ");
if (preg_match_all($forced, $content, $forcedlinks)) {
echo $this->Format("==Forced links:==");
foreach ($forcedlinks[0] as $fkey => $fitem) {
$ftag = $forcedlinks[1][$fkey];
$fanchor = $forcedlinks[2][$fkey];
// display link and rewritten link
echo $this->Format($fkey.": ".$fitem." => ")."<a href='".$this->Href("","","page=".$ftag)."'>".$fanchor."</a><br />";
// add rewritten link to array
$fsearch[$fkey] = $fitem;
$freplace[$fkey] = "\"\"<a href='".$this->Href("","","page=".$ftag)."'>".$fanchor."</a>\"\"";
}
// rewrite forced links
//$content = preg_replace($fsearch, $freplace, $content);
}
if (preg_match_all($camel, $content, $camellinks)) {
echo $this->Format(" --- ==Camelcase links:==");
foreach ($camellinks[0] as $ckey => $citem) {
$citem = ltrim($citem);
echo $this->Format($ckey.": ".$citem." => ")."<a href='".$this->Href("","","page=".$citem)."'>".$citem."</a><br />";
$csearch[$ckey] = $citem;
$creplace[$ckey] = " \"\"<a href='".$this->Href("","","page=".$citem)."'>".$citem."</a>\"\"";
}
// rewrite CamelCase links
//$content = preg_replace($csearch, $creplace, $content);
}
*/
?>
-- DarTar
CategoryDevelopment