Extension:VIKI/Plugin Structure

Overview edit

By design, VIKI is architected to support either an individual wiki or a series of collectively managed wikis (wiki farm), and this support comes in the form of a hook structure for plugins. Similarly to MediaWiki, VIKI defines a set of points of time during the execution when it will call any hook functions which are registered with it.

Plugins are MediaWiki extensions themselves which register with VIKI hooks. Plugins may execute code on both the PHP side and the JavaScript side. If the plugin includes JavaScript, a resource module containing the JS files must be declared and registered with VIKI to load. As your plugin is a MediaWiki extension itself, you may choose to (for example) define MediaWiki API extensions in your plugin.

Currently, VIKI defines one PHP hook and 11 JavaScript hooks:

PHP Hooks

Hook Name

Description

PHP Hook Called during the execution of the VIKI PHP code before the VIKI script is added to $wgOut. Extensions may add a PHP hook to allow any PHP code to run, perhaps to set up any JavaScript to run before VIKI is initialized on the JavaScript side.

JavaScript Hooks

Hook Name

Description

Passed-in Parameters

GetAllWikisHook Called toward the end of the VIKI.initialize() function to allow any plugins to provide a list of other wikis which VIKI should be aware of. None
InitializationCompleteHook Called after GetAllWikisHook at the end of VIKI.initialize() function to allow any plugins to perform last-minute initialization functions. None
NewWikiNodeCreatedHook Called immediately after a new wiki node has been created, but not yet added. This allows any plugins to examine the node to determine if it should not be added to the graph. If so, set the node's value of unadded to true. parameters[0] - the newly created node

parameters[1] - the node from which the new node originates as a link

NewExternalNodeCreatedHook Called immediately after a new external node has been created, but not yet added. Same use case as NewWikiNodeCreatedHook. parameters[0] - the newly created node

parameters[1] - the node from which the new node originates as a link

NewWikiNodeAddedHook Called immediately after a new wiki node has been added. parameters[0] - the newly added wiki node.
New ExternalNodeAddedHook Called immediately after a new external node has been added. parameters[0] - the newly added external node.
ExternalNodeHook Called when a new batch of external nodes has been added to the graph, to allow any plugins to perform further analysis and processing of the external node. parameters[0] – the current batch of new external nodes to be added as an array.
IntraInNodeHook Called when a new batch of internal nodes (linking into the node being elaborated) has been added to the graph, to allow any plugins to perform further analysis and processing of the external node. parameters[0] – the current batch of new external nodes to be added as an array.
IntraOutNodeHook Called when a new batch of internal nodes (linking out from the node being elaborated) has been added to the graph, to allow any plugins to perform further analysis and processing of the external node. parameters[0] – the current batch of new external nodes to be added as an array.
BeforeVisitNodeHook Called immediately before the wiki node is visited to verify its existence. Can be useful for pre-processing to change the node's page name or URL if recognized by a plugin. (Note that external nodes are not visited to verify their existence. Existence verification is performed by the MediaWiki API.) parameters[0] - the wiki node about to be visited.
AfterVisitNodeHook Called immediately after the wiki node is visited to verify its existence, and only if it has been verified to exist. Can be useful for further processing of a node while allowing other plugins acting on other hooks to operate first. parameters[0] - the wiki node about to be visited.


Declaring A Plugin edit

Declaring a JavaScript plugin requires two steps:

  1. In your plugin's PHP file, register the name of the plugin function hook with $wgVIKI_Function_Hooks.
    global $wgVIKI_Function_Hooks;
    
    if(!isset($wgVIKI_Function_Hooks))
    	$wgVIKI_Function_Hooks = array();
    
    if(array_key_exists('GetAllWikisHook', $wgVIKI_Function_Hooks))
    	$wgVIKI_Function_Hooks['GetAllWikisHook'][] = 'VIKI.YourSubModule.yourPluginJSFunctionName';
    else
    	$wgVIKI_Function_Hooks['GetAllWikisHook'] = array('VIKI.YourSubModule.yourPluginJSFunctionName');
    
  2. Also in your plugin's PHP file, have VIKI add the resource module for the plugin at ParserFirstCallInit. Note that for historical reasons, the core VIKI class is called 'VikiJS'.
    $wgHooks['ParserFirstCallInit'][] = 'efYourPlugin_Setup';
    
    function efYourPlugin_Setup (& $parser) {
    	VikiJS::addResourceModule("ext.YourPlugin");
    	return true;
    }
    


Declaring a PHP plugin requires one step:

  1. In your plugin's PHP file, register the name of the plugin function hook with VIKI. Any parameters passed in should be passed as an array, and the function should be declared to take one parameter, which is the array of parameters.
    $wgHooks['ParserFirstCallInit'][] = 'efYourPlugin_AddResource';
    
    function efYourPlugin_AddResource (& $parser) {
    	VikiJS::addPHPHook("efYourPlugin_PHP_Function", array(param1, param2, ...));
    	return true;
    }
    
    function efYourPlugin_PHP_Function($params) {
    	...
    }
    

If the plugin contains both a PHP and JavaScript side, all three steps must be taken.

JavaScript Structure edit

VIKI takes advantage of the JavaScript Loose Augmentation Module Pattern. Core VIKI is declared as a submodule within the VIKI module called VikiJS, and any VIKI plugins with a JavaScript component are expected to be declared as submodules to VIKI as well.

If your JavaScript plugin is an object literal, it may take the following form:

window.VIKI = (function(my) {
	my.YourSubModule = {
		// ...
	};
	return my;
}(window.VIKI || {}));


If your JavaScript plugin is an object with a prototype, it may take the following form:

window.VIKI = (function(my) {
	my.YourSubModule = function() {
		this.someConstant = "foo";
		// ...
		my.YourSubModule.prototype.foo = function() {
			// ...
		}

		my.YourSubModule.prototype.foo2 = function() {
			// ...
		}
	}
	return my;
}(window.VIKI || {}));


JavaScript Hook Functions edit

JavaScript hook functions all take the same parameters:

  • vikiObject – a reference to the VIKI object which this hook was called from
  • parameters – any parameters passed to the hook function (reference chart above)
  • hookName – the name of the hook this function was called from


All JavaScript hook functions must call vikiObject.hookCompletion(hookName, params ) at the conclusion of their execution. params is a JSON object of certain parameters that VIKI can handle. Currently, VIKI can handle three possible parameters:

  • "redraw" : true/false - this will cause VIKI to redraw the entire graph at the completion of your hook.
  • "redrawNode" : true/false - this will cause VIKI to redraw just the node you specify (below) at the completion of your hook.
  • "node" : <your node object> - this passes a node back to VIKI to be used to redraw that node.


If the hook function involves one or more asynchronous operations, e.g. an AJAX call, care should be taken to ensure that hookCompletion is only called at the end of the last possible success/error handler, for example.

Wiki-Farm Support edit

VIKI is designed to support farms consisting of multiple wikis. If provided a list of known wikis, VIKI can recognize links between pages on different wikis as internal links and treat them as such, creating wiki page nodes in the graph and allowing for further elaboration of those pages. To take advantage of this, a plugin must perform the following actions:

  1. Register with the GetAllWikisHook.
  2. During the function registered with this hook, access the VIKI object's allWikis array (empty by default).
  3. Populate the object's allWikis array with objects containing the following key-value pairs:
    • wikiTitle: title of wiki
    • apiURL: URL to the wiki's API, e.g. http://www.mediawiki.org/w/api.php
    • contentURL: wiki's content URL, usually the value of $wgServer + $wgArticlePath
    • logoURL: wiki's logo URL, which can be obtained from the value of $wgLogo
    • searchableWiki: whether this wiki is searchable through the MediaWikiAPI (boolean value). Note that if searchableWiki = false, then VIKI will recognize this wiki as a known wiki and will properly display pages from this wiki with the site logo, but this page cannot be elaborated in the graph because the API is closed.
  4. Remember to call hookCompletion() with the GetAllWikisHook name after populating the list.

Below is an example of wiki data that VIKI could recognize:

{
	wikiTitle: "MediaWiki",
	apiURL: "http://www.mediawiki.org/w/api.php",
	contentURL: "http://www.mediawiki.org/wiki/$1",
	logoURL: "http://upload.wikimedia.org/wikipedia/mediawiki/b/bc/Wiki.png",
	searchableWiki: true
}


Examples edit

We have developed several VIKI plugins which will be open-sourced over time. For now, two examples are available: