Difference between revisions of "Extension:Livelets.php"

From Organic Design wiki
m
(simplified code and added interwiki capability)
Line 6: Line 6:
 
# - Author: http://www.organicdesign.co.nz/nad
 
# - Author: http://www.organicdesign.co.nz/nad
  
define('LIVELETS_VERSION', '0.0.3, 2007-05-10');
+
define('LIVELETS_VERSION', '0.1.0, 2007-05-11');
  
 
$wgLiveletsMagic              = "live"; # the parser-function name for doing live-transclusions
 
$wgLiveletsMagic              = "live"; # the parser-function name for doing live-transclusions
Line 13: Line 13:
  
 
$wgExtensionCredits['parserhook'][] = array(
 
$wgExtensionCredits['parserhook'][] = array(
'name'       => 'Livelets',
+
'name'       => 'Livelets',
'author'     => '[http://www.organicdesign.co.nz/User:Nad User:Nad]',
+
'author'     => '[http://www.organicdesign.co.nz/User:Nad User:Nad]',
      'description' => 'dynamic nonpolling updates of articles',
+
'description' => 'dynamic non-polling updates of articles',
'url'       => 'http://www.mediawiki.org/wiki/Extension:Livelets',
+
'url'         => 'http://www.mediawiki.org/wiki/Extension:Livelets',
        'version'   => LIVELETS_VERSION
+
'version'     => LIVELETS_VERSION
 
);
 
);
  
Line 23: Line 23:
  
 
var $version = LIVELETS_VERSION;
 
var $version = LIVELETS_VERSION;
var $magic;
 
var $args;
 
 
var $id = 0;
 
var $id = 0;
  
Line 31: Line 29:
 
global $wgParser,$wgHooks,$wgOut,$wgScript,$wgLiveletsPath;
 
global $wgParser,$wgHooks,$wgOut,$wgScript,$wgLiveletsPath;
 
$live = array_key_exists('live',$_REQUEST);
 
$live = array_key_exists('live',$_REQUEST);
$this->magic = $magic;
 
$this->args  = array();
 
 
$wgParser->setFunctionHook($magic,array($this,'functionHook'));
 
$wgParser->setFunctionHook($magic,array($this,'functionHook'));
$wgParser->setHook($magic,array($this,'tagHook'));
+
}
  
# If the query string contains "live" return naken and die
+
# Remove live container content
if ($live) $wgHooks['OutputPageBeforeHTML'][] = 'wfLiveletsNakedArticle';
+
function functionHook(&$parser,$title) {
 +
global $wgScript,$wgLiveletsPath;
 +
$this->addJSandSWF();
 +
$id    = 'livelet'.$this->id++; # this should be a GUID
 +
$url  = Title::newFromText($title)->getFullURL('action=render');
 +
$html  = "<div class='livelet' id='$id' url='$url'><div style='text-align:center'><img src='$wgLiveletsPath/wait.gif'/></div></div>";
 +
$html .= "<script type='text/javascript'>liveletRequest('$id')</script>";
 +
return array($html,isHTML => true);
 +
}
 +
 
 +
function addJSandSWF() {
 +
global $wgOut,$wgLiveletsPath,$wgAddJavaScriptFunctions;
  
 
# Add the livelets JavaScript functions to the output page
 
# Add the livelets JavaScript functions to the output page
else $wgAddJavaScriptFunctions['Livelets'] = "
+
$wgAddJavaScriptFunctions['Livelets'] = "
  
 
// Keep record of livelets on page
 
// Keep record of livelets on page
Line 50: Line 57:
 
livelets.push(livelet);
 
livelets.push(livelet);
 
livelet.id = id
 
livelet.id = id
livelet.url = '$wgScript?title=' + livelet.getAttribute('title') + '&live'
+
livelet.url = livelet.getAttribute(url);
 
livelet.xmlhttp = null
 
livelet.xmlhttp = null
 
if (window.XMLHttpRequest) livelet.xmlhttp = new XMLHttpRequest()
 
if (window.XMLHttpRequest) livelet.xmlhttp = new XMLHttpRequest()
Line 81: Line 88:
  
 
# Embed livelets.swf into the output page
 
# Embed livelets.swf into the output page
 +
# NOTE: this actually needs to be served by the WikiDaemon, not the PHP
 
$swf = "$wgLiveletsPath/livelets.swf";
 
$swf = "$wgLiveletsPath/livelets.swf";
if (0 && !$live) $wgOut->addHTML("<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0'
+
$wgOut->addHTML("<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0'
 
id='livelets' width=100 height=100>
 
id='livelets' width=100 height=100>
 
<param name='movie' value='$swf'>  
 
<param name='movie' value='$swf'>  
 
<embed swliveconnect='true' name='livelets' src='$swf' width=100 height=100 type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'>
 
<embed swliveconnect='true' name='livelets' src='$swf' width=100 height=100 type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'>
 
</embed></object>");
 
</embed></object>");
}
 
 
# Remove live container content, store its parameters and convert it to $magic tags
 
function functionHook(&$parser) {
 
$magic = $this->magic;
 
$id    = 'livelet'.$this->id++;
 
$args  = array();
 
foreach (func_get_args() as $arg) if (!is_object($arg)) {
 
if (preg_match('/^(.+?)=(.+)$/',$arg,$match)) $args[$match[1]] = $match[2]; else $args[] = $arg;
 
}
 
$this->args[$id] = $args;
 
return "<$magic>$id</$magic>";
 
}
 
 
# Convert the $magic tags to client-side javascript request code from its stored parameters
 
function tagHook($id,$argv,&$parser) {
 
global $wgScript,$wgLiveletsPath;
 
$args  = $this->args[$id];
 
$title = $args[0];
 
$html  = "<div class='livelet' id='$id' title='$title'><div style='text-align:center'><img src='$wgLiveletsPath/wait.gif'/></div></div>";
 
$html .= "<script type='text/javascript'>liveletRequest('$id')</script>";
 
return $html;
 
 
}
 
}
  
Line 125: Line 111:
 
$magicWords[$wgLiveletsMagic] = array(0,$wgLiveletsMagic);
 
$magicWords[$wgLiveletsMagic] = array(0,$wgLiveletsMagic);
 
return true;
 
return true;
}
 
 
# Output the naked page and die
 
function wfLiveletsNakedArticle(&$out,&$text) {
 
while(@ob_end_clean());
 
$out->sendCacheControl();
 
if (in_array('Content-Encoding: gzip',headers_list())) $text = gzencode($text);
 
echo($text);
 
die;
 
 
}
 
}
  
 
{{AddJavaScript}}
 
{{AddJavaScript}}
 
?>
 
?>

Revision as of 21:49, 10 May 2007

<?

  1. Extension:Livelets{{#Security:*|dev}}{{#Security:view|*}}Template:Php
  2. - Allows live articles to be transcluded which update automatically on change in a non-polling, fully event-driven way
  3. - See http://www.mediawiki.org/wiki/Extension:Livelets for installation and usage details
  4. - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
  5. - Author: http://www.organicdesign.co.nz/nad

define('LIVELETS_VERSION', '0.1.0, 2007-05-11');

$wgLiveletsMagic = "live"; # the parser-function name for doing live-transclusions $wgExtensionFunctions[] = 'wfSetupLivelets'; $wgHooks['LanguageGetMagic'][] = 'wfLiveletsLanguageGetMagic';

$wgExtensionCredits['parserhook'][] = array( 'name' => 'Livelets', 'author' => 'User:Nad', 'description' => 'dynamic non-polling updates of articles', 'url' => 'http://www.mediawiki.org/wiki/Extension:Livelets', 'version' => LIVELETS_VERSION );

class Livelets {

var $version = LIVELETS_VERSION; var $id = 0;

# Constructor function Livelets($magic) { global $wgParser,$wgHooks,$wgOut,$wgScript,$wgLiveletsPath; $live = array_key_exists('live',$_REQUEST); $wgParser->setFunctionHook($magic,array($this,'functionHook')); }

# Remove live container content function functionHook(&$parser,$title) { global $wgScript,$wgLiveletsPath; $this->addJSandSWF(); $id = 'livelet'.$this->id++; # this should be a GUID $url = Title::newFromText($title)->getFullURL('action=render');

$html = "

<img src='$wgLiveletsPath/wait.gif'/>

";

$html .= "<script type='text/javascript'>liveletRequest('$id')</script>"; return array($html,isHTML => true); }

function addJSandSWF() { global $wgOut,$wgLiveletsPath,$wgAddJavaScriptFunctions;

# Add the livelets JavaScript functions to the output page $wgAddJavaScriptFunctions['Livelets'] = "

// Keep record of livelets on page var livelets = new Array();

// Request an URL function liveletRequest(id) { livelet = document.getElementById(id) livelets.push(livelet); livelet.id = id livelet.url = livelet.getAttribute(url); livelet.xmlhttp = null if (window.XMLHttpRequest) livelet.xmlhttp = new XMLHttpRequest() else if (window.ActiveXObject) livelet.xmlhttp = new ActiveXObject('Microsoft.XMLHTTP') if (livelet.xmlhttp != null) { livelet.xmlhttp.onreadystatechange = stateChange livelet.xmlhttp.open('GET',livelet.url,true) livelet.xmlhttp.send(null) } else alert('Your browser does not support XMLHTTP!') }

// Update the livelet content when loaded function stateChange() { for (var i = 0; i < livelets.length; i++) { var livelet = livelets[i]; var xmlhttp = livelet.xmlhttp if (xmlhttp.readyState == 4) { if (xmlhttp.status == 200) livelet.innerHTML = xmlhttp.responseText else alert('Problem retrieving XML data!') xmlhttp.readyState = 0; } } }

// Trap fscommands from the SWF movie function livelets_DoFScommand(cmd,args) { alert(args) }";

# Embed livelets.swf into the output page # NOTE: this actually needs to be served by the WikiDaemon, not the PHP $swf = "$wgLiveletsPath/livelets.swf"; $wgOut->addHTML("<object classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://active.macromedia.com/flash2/cabs/swflash.cab#version=4,0,0,0' id='livelets' width=100 height=100> <param name='movie' value='$swf'> <embed swliveconnect='true' name='livelets' src='$swf' width=100 height=100 type='application/x-shockwave-flash' pluginspage='http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash'> </embed></object>"); }

}

  1. Called from $wgExtensionFunctions array when initialising extensions

function wfSetupLivelets() { global $wgLivelets,$wgLiveletsMagic,$wgScriptPath,$wgLiveletsPath; $wgLivelets = new Livelets($wgLiveletsMagic); if ($wgLiveletsPath == ) $wgLiveletsPath = "$wgScriptPath/extensions/livelets"; }

  1. Needed in MediaWiki >1.8.0 for magic word hooks to work properly

function wfLiveletsLanguageGetMagic(&$magicWords,$langCode = 0) { global $wgLiveletsMagic; $magicWords[$wgLiveletsMagic] = array(0,$wgLiveletsMagic); return true; }

Template:AddJavaScript ?>