Revision [2881]

This is an old revision of IncludeRemote made by DarTar on 2004-12-06 08:49:05.

 

Fetching Remote Wikka Content

Last edited by DarTar:
FetchRemote action v.0.6 - link rewriting engine working!
Mon, 06 Dec 2004 08:49 UTC [diff]


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:
  1. the user of a wikka distribution opens a local WikkaDocumentation page containing {{fetchremote page="HelpInfo"}};
  1. the plugin connects to the main wikka server,
  1. it fetches a raw version of HelpInfo with no header and footer (i.e. the mere page content in wikka syntax),
  1. 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),
  1. and finally, it prints locally the documentation contents.
  1. 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:
    1. the fetched content integrates seamlessly with the layout and structure of the Wikka-client;
    1. the user can choose to download locally a fetched page, so as to make it available in its Wikka site.


Screenshot:
http://wikka.jsnx.com/images/fetchremote.jpg


Now, here comes some code.

FetchRemote: a plugin for fetching remote documentation


FetchRemote Action
Version 0.6

What it does

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:

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;
}
?>


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));
    }


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));
    }


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);
}  


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);
}


3. Create in the Wikka client a FetchRemote action (actions/fetchremote.php)

<?php

/**
 * Connects to a specified Wikka server, fetches a remote page and formats it for local use.
 *
 * This action allows the user to locally browse in a Wikka client content fetched from a
 * remote Wikka server. It displays an error message if the remote page does not exist
 * on the server or if a connection is not available.
 * Once a connection is established, the fetched page is parsed for internal links, which
 * are rewritten as links to fetchable pages, and printed on the screen.
 * Fetched pages can then be safely stored on the Wikka client. If a local version
 * of a fetched page is available, a "see local version" button replaces the default
 * "download" button.
 *
 * A "rawcontent" method must be available on the main Wikka server, in order to
 * produce raw wikka-formatted content with header and footer stripped).
 *
 * @package     Actions
 * @name        FetchRemote
 *
 * @author       {@link http://wikka.jsnx.com/DarTar DarTar}
 * @version      0.6
 * @since         Wikka 1.1.X
 *
 * @input         stringĀ  $pageĀ  optional: Starting page on the main Wikka server;
 *               default: HelpInfo
 *                   can be overridden by a $_REQUEST["page"] parameter.
 * @output       prints fetched documentation pages
 *
 * @todo         -Forced link rewriting: check regex for consistency with wikka formatters.
 *                   -CamelCase link rewriting: check regex for consistency with wikka formatters.
 *                   -Interwiki link rewriting.
 */



// SET DEFAULTS

$remote_server_root = "http://wikka.jsnx.com/"; # set remote server root
//$remote_server_root = "http://test/wikka-1.1.5.0/wikka.php?wakka="; # debug server

$defaultpage = 'HelpInfo'; # define default page to be fetched
if (isset($page)) $defaultpage = $page; # pick up action parameter
if (isset($_REQUEST["page"])) $defaultpage = $_REQUEST["page"]; # pick up URL parameter
$page = $defaultpage; # ready to roll


// PERFORM REDIRECTIONS

// redirect to main documentation page
if ($_POST["action"] == "Return to Wikka Documentation") $this->Redirect($this->GetPageTag());

// redirect to Wikka homepage on disconnection
if ($_POST["action"] == "Disconnect") $this->Redirect($this->GetConfigValue("root_page"));

// switch to local version of the page
if ($_POST["action"] == "See local version") $this->Redirect($page);

// automatically redirect to local page if it exists
// NOTE: the use of this feature is discouraged since it traps users 'locally'
// and prevents them from accessing recently updated versions of the Wikka documentation
//if ($this->LoadPage($page)) $this->Redirect($page);

// SET HEADER & FORM ELEMENTS

// header style
// to be replaced by a CSS selector in the definitive version
$style = "text-align: center; margin: 30px 25%; border: 1px dotted #333; background-color: #EEE; padding: 5px;";

// build form chunks
$form_local = "<input type='submit' name='action' value='See local version' />";
$form_main = "<input type='submit' name='action' value='Return to Wikka Documentation' />";
$form_disconnect = "<input type='submit' name='action' value='Disconnect' />";
$form_page = "<input type='hidden' name='page' value='".$page."' />";
$form_download = "<input type='submit' name='action' value='Download this page' />";


// TRY TO CONNECT
$remote_page = fopen($remote_server_root.$page."/rawcontent", "r");

if (!$remote_page) {

    // NO CONNECTION AVAILABLE
    echo $this->Format("=====Wikka Documentation===== --- Visit the **[[http://wikka.jsnx.com/HelpInfo Wikka Documentation Project]]** --- --- ");
    // if a local version of the starting page is available:
    if ($this->LoadPage($page)) print $this->FormOpen().$form_local.$this->FormClose();

} else {

    // CONNECTION ESTABLISHED

    // fetch rawcontent of remote page
    while (!feof($remote_page)) {
        $content .= fgets($remote_page, 1024);
    }

    if (!$content) {
        // missing or empty 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]]! --- --- ";
        $form = $this->FormOpen().$form_page;
        $form .= ($this->LoadPage($page))? $form_local : "";
        $form .= $form_main.$this->FormClose();
    } else {

        // START LINK-REWRITING ENGINE

        // regex pattern for forced links to *internal pages* on remote server
        $forced = "/\[\[([^ \/]+) ([^\]]+)\]\]/";
        //$forced = "/\[\[(\S*)(\s+(.+))?\]\]/"; #JW's suggestion
        // regex pattern for CamelCase links to *internal pages* on remote server
        $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);

        // build callback function for marking CamelCase words within forced links
        function MarkCamel($fmatches) {
            global $wakka;
            $camel = "/([A-Z]+[a-z]+[A-Z][A-Za-z0-9]+)+/";
            $markedcamel = preg_replace($camel, "|||\\1|||", $fmatches[2]);
            // 1) This is working
            $output = '""<a href="'.$fmatches[1].'">'.$markedcamel.'</a>""';
            // 2) This is NOT working
            // How do I call a global function from within a callback function?
            $output = '""<a href="'.$wakka->Href('','',"page=".$fmatches[1]).'">'.$markedcamel.'</a>""';
            return $output;
        }
        // rewrite forced links
        $content = preg_replace_callback($forced, 'MarkCamel', $content);

        // rewrite camelcase links
        $content = preg_replace($camel, ' ""<a href="'.$this->Href('','',"page=\\1").'">'."\\1".'</a>""', $content);

        //strip "|||" markers from content
        $content = str_replace("|||", "", $content);
   
        if ($_POST["action"] == "Download this page") {

            // SAVING FETCHED 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 the local version should be overwritten
                $header = "Sorry, a page named **[[".$page."]]** already exists on this site! --- ";
                $form = $this->FormOpen().$form_main.$form_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().$form_page.$form_local.$form_main.$this->FormClose();
            }

        } else {
           
            // display default header & form
            $header = "You are currently browsing: **";
            $header .=  "\"\"<a href='".$this->Href("","","page=".$page)."'>".$page."</a>\"\"";
            $header .= "** --- from the **[[".$this->GetPageTag()." Wikka Documentation Project]]** --- ";
            $header .= "(fetched from the [[".$remote_server_root.$page." Wikka server]])";
            $form = $this->FormOpen().$form_page;
            $form .= ($this->LoadPage($page))? $form_local : $form_download;
            $form .= $form_disconnect.$this->FormClose();
        }
    }

    // PRINT HEADER AND CONTENT
    print "<div style='".$style."'>".$this->Format($header).$form."</div>".$this->Format($content);
}

// CLOSE CONNECTION
fclose($remote_page);
?>



-- DarTar


CategoryDevelopment
There are 17 comments on this page. [Show comments]
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki