Extension:Nimbus

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual
Crystal Clear action run.png
Nimbus

Release status: beta

Nimbus screenshot.png
Implementation Tag
Description Cumulus (flash) presentation of top categories, degrading to Text Category Cloud
Author(s) Mark Smaga (Msmagatalk)
Latest version 1.1 (2010-01-06)
MediaWiki tested on 1.16.0beta3, 1.15.x and 1.14.0
Database changes No
License creative commons
Download see installation instruction
Example
Hooks used
ParserFirstCallInit

Translate the Nimbus extension if it is available at translatewiki.net

Check usage and version matrix; code metrics

The Nimbus extension returns a (user defined) number of Category (or Requested Pages) links, and displays them in font sizes relative to the number of links in those Categories/Pages. The returned list can be optionally animated when "Flash" is available to the browser. This extension serves as a direct replacement for the "WikiCategoryCloud" extension. All default settings can be overwritten by Mediawiki page. Based on WikiCategoryTagCloud by Daniel Friesen and WP-Cumulus Port to mediawiki by Luc.

Thanks to Wikimini, George Alexandru Dudău and others for Requested Pages suggestions and modifications.

Note: Fonts displayed are flash images. Latin characters are pre-loaded and should immediately work. Instructions for loading additional characters or sets are on Roy Tanck's site.

Usage[edit | edit source]

All variables have "reasonable" defaults, which can be overwritten on the MediaWiki page.

Test MediaWiki implementation:

{| class="nimbus" style="color:#000;" |
   <tagcloud style="background: transparent; padding:0; border:0;">
   flash=1
   min_size=60
   min_count=20
   max_items=30
   increase_factor=150
   exclude=CategoryName, Delete, Help
   </tagcloud>
|}

IMPORTANT: each variable must be set on a separate line. one variable per line.

Options[edit | edit source]

The full set of options which can be passed from the Wiki Page are:

Variable Default Purpose
Flash 0 Use flash display? 0=FALSE, 1=TRUE. Default FALSE for replacement of Wiki Category Cloud
min_size 60 Minimum text size (a percentage of normal)
increase_factor 150 Difference between smallest & largest item fonts (percentage)
min_count 0 Minimum number of links for a category to be considered for display
max_items 30 maximum number of items to be displayed in a cloud
point_factor 175 Relative sizing of flash fonts as a percentage of static fonts
speed 150 Relative speed of sphere: 25 - 500 is "normal"
flash_width 330 Fixed-width of flash display area in pixels (generally wider than high for text)
flash_height 230 Fixed-height of flash display area
color 0x002bb8 Category item color
hicolor 0xcc2200 Category item mouse-over color
exclude CategoryName, Delete, Help Categories named here will not be considered for display
cloud_table categorylinks Cloud Table Name
cloud_column cl_to Cloud Column Name, containing Wiki Page Titles
wanted_cloud 0 Requested Items / Wanted Items Cloud? 0=false/1=true. Overrides cloud_column to "pl_title"

Installation[edit | edit source]

To install this extension, add the following to LocalSettings.php:

require_once("$IP/extensions/Nimbus/Nimbus.php");

You must have in the Nimbus directory:

  • swfobject.js [1] (Please note: This link will lead you to download version 2.2 (as of Nov 2011) which is not compatible with the Nimbus extension. What you want is the old version 1.4 (any <=1.5 should do) which you can find here[2])
  • tagcloud.swf [3]
  • Nimbus.php (see below)

These files are read & executed, set permissions to 755. From the command line in the Nimbus directory type:

chmod 755 Nimbus/*

Code : Nimbus.php[edit | edit source]

<?php
/*
 * Nimbus-
 * A Cumulus (flash) presentation of top categories, degrading to a Wiki Category Cloud presentation.
 *  - Optionally presents a 'Requested Items / 'Wanted Items' cloud.
 * @author Mark Smaga msmaga@esri.com
 * @date   12/18/2009
 * @ver    1.1
 *
 * Based on "Wiki Category Tag Cloud" by Daniel Friesen at http://daniel.friesen.name
 *      and "WP-Cumulus Port to mediawiki" by Luc at http://www.mediawiki.org/w/index.php?title=Extension:Cumulus
 *
 * Some special characters are included, but for more & UTF-8 characters, please refer to:
 *    http://www.roytanck.com/2008/08/04/how-to-add-more-characters-to-wp-cumulus/
 *   
 * Wiki pages containing apostrophes will not have links (Javascript/SWFobject/MediaWiki incompatibilities).
 *    &rsquo; or &8217; work visually, but may make searches less intuitive
 *
 * This extension serves as a replacement for WikiCategoryCloud.
 * All default settings can be overwritten by Mediawiki page.  See $defaults.
 * Include this file in Wiki/LocalSettings.php by adding line:
 *      require_once("$IP/extensions/Nimbus/Nimbus.php");
 *
 * Defaults array - see function getMediaWikiVar at end of this file.  
 * These vars can be passed from MediaWiki by placing them each on one line.
 *   Typical Mediawiki implementation:
 * 
 *   |-
 *   | class="nimbus" style="text-align:center;" |
 *   <tagcloud style="background: transparent; padding:0; border:0;">
 *   flash=1
 *   increase_factor=150
 *   exclude=CategoryName, Delete, Help
 *   </tagcloud>
 *   |-
 *
 */
 
if (!defined('MEDIAWIKI')) die();
 
$wgExtensionCredits['parserhook'][] = array(
  'name' =>        'Nimbus',
  'author' =>      'Mark Smaga',
  'version' =>     '1.1',
  'url' =>         'https://www.mediawiki.org/wiki/Extension:Nimbus',
  'description' => 'Cumulus Presentation of Wiki Category Cloud Top Categories in Mediawiki',
);
 
// Avoid unstubbing $wgParser too early on modern (1.12+) MW versions, as per r35980
if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) {
    $wgHooks['ParserFirstCallInit'][] = 'registerTagCloudExtension';
} 
else {
    $wgExtensionFunctions[] = 'registerTagCloudExtension';
}
 
/*
 * Hook this to <tagcloud></tagcloud>
 */
function registerTagCloudExtension() {
    global $wgParser;
    $wgParser->setHook( 'tagcloud', 'renderTagCloud' );
    return true;
}
 
/*
 * Main process
 */
function renderTagCloud( $input, $params, $parser ) {	
    global $wgScriptPath;
    $http = (stripos ($_SERVER['SERVER_PROTOCOL'], 'HTTPS') == false) ? 'http://' : 'https://' ;
    $scriptPath = (isset($wgScriptPath) && ($wgScriptPath == '/')) ? $_SERVER['SCRIPT_NAME'] : $wgScriptPath;
    $dbr = wfGetDB( DB_SLAVE );
 
    $cloudStyle = @$params['style'];
    $cloudClasses = preg_split( '/\s+/', @$params['class'] );
    array_unshift( $cloudClasses, 'tagcloud' );
    $linkStyle = isset($params['linkstyle']) ? $params['linkstyle'] : '';
    $linkClasses = preg_split( '/\s+/', @$params['linkclass'] );
 
    $flashInput = getMediaWikiVar( $input, 'flash' );
    $flash = ( $flashInput == true );
 
    $min_count = getMediaWikiVar( $input, 'min_count', true );
    $min_size = getMediaWikiVar( $input, 'min_size', true );
    $increase_factor = getMediaWikiVar( $input, 'increase_factor', true );
    $point_factor_input = getMediaWikiVar( $input, 'point_factor', true );    
    $point_factor = ($min_size/100) * ($point_factor_input / 1000);
    $max_items = getMediaWikiVar( $input, 'max_items', true );
    $exclude = getMediaWikiVar( $input, 'exclude' );
    $color = getMediaWikiVar( $input, 'color' );
    $hicolor = getMediaWikiVar( $input, 'hicolor' );
    $speed = getMediaWikiVar( $input, 'speed', true );
    $flash_width = getMediaWikiVar( $input, 'flash_width', true );
    $flash_height = getMediaWikiVar( $input, 'flash_height', true );
    $cloudTable = getMediaWikiVar( $input, 'cloud_table' );
    $cloudColumn = getMediaWikiVar( $input, 'cloud_column' );
    $wantedCloud = (getMediaWikiVar( $input, 'wanted_cloud', true ) == 1);
 
    $exclude_condition = '';
    if ( strlen( $exclude ) > 0 ) {
        $excluded_categories = explode( ",", $exclude );
        if ( count( $excluded_categories ) > 0 ) {
            $exclude_condition = " WHERE $cloudColumn NOT IN (";
            for ( $i = 0; $i < count( $excluded_categories ); $i++ ) {
                $exclude_condition = $exclude_condition . "\"" . trim( $excluded_categories[$i] ) . "\"";
                if ( $i < count( $excluded_categories ) - 1 ) {
                    $exclude_condition = $exclude_condition . ",";
                }
            }
            $exclude_condition = $exclude_condition . ")";
        }
    }
 
	// Get top categories in order of popularity (quantity of links)\	
	$thisTable = $dbr->tableName( $cloudTable );
 
    if ($wantedCloud) {
        // add two more queries
        $pagelinks = $dbr->tableName( 'pagelinks' );
        $page      = $dbr->tableName( 'page' );
	    $cloudColumn = 'pl_title';	// override $cloudColumn for wantedCloud
 
        $sql = "SELECT 'Wantedpages' AS type, pl_namespace AS namespace, $cloudColumn AS title, COUNT(*) AS count FROM $pagelinks LEFT JOIN $page AS pg1 ON pl_namespace = pg1.page_namespace AND $cloudColumn = pg1.page_title  LEFT JOIN $page AS pg2	 ON pl_from = pg2.page_id WHERE pg1.page_namespace IS NULL AND pl_namespace NOT IN ( 2, 3 )  AND pg2.page_namespace != 8 GROUP BY $cloudColumn HAVING count >= $min_count ORDER BY count DESC LIMIT $max_items";
    }
    else
        $sql = "SELECT $cloudColumn as title, COUNT(*) as count FROM {$thisTable} " . $exclude_condition . " GROUP BY $cloudColumn HAVING count >= $min_count ORDER BY count DESC LIMIT $max_items";
 
    $res = $dbr->query( $sql );
    $count = $dbr->numRows( $res );
 
	// determine the minimum and maximum number of links per item in this group
    $min = 1000000;
    $max = - 1;
    for ( $i = 0; $i < $count; $i++ ) {
        $obj = $dbr->fetchObject( $res );
        $tags[$i][0] = $obj->title;
        $tags[$i][1] = $obj->count;
        if ( $obj->count < $min ) {
            $min = $obj->count;
        }
        if ( $obj->count > $max ) {
            $max = $obj->count;
        }
    }
 
    // setup <a> tags
    $linksArray = array();
    $linksNoFlash = '';
    $links = '';	
    $currentRowP = '';	
    for ( $i = 0; $i < $count; $i++ ) {
        $textSize = $min_size + ( $increase_factor * ( $tags[$i][1] ) ) / ( $max );
 
        $title = Title::makeTitle( 'NS_', $tags[$i][0] );
        $style = $linkStyle;
        if ( $style != '' && $style { -1 } != ';' ) $style .= ';';
        $style .= "font-size: {$textSize}%;";
        $currentRow = "<a class=\"" . implode( ' ', $linkClasses ) . "\" style=\"{$style}\" href=\"" . $title->getLocalURL() . "\">" . $title->getText() . "</a>&nbsp; ";
	$linksArray[$title->getText()] = $currentRow;
 
	// do cumulus-style links
	$textSizeP = round($textSize * $point_factor);
        $titleP = '';
        if (strtolower ($cloudTable) == 'categorylinks')
            $titleP = 'Category:';
        if (strpos ($title->getText(), "'") === false) {  // wiki title contains no apostrophes
            $titleP .= htmlentities($title->getText(), ENT_QUOTES, 'utf-8');
            $titleP = str_replace( 'index.php/', 'index.php?title=', $titleP );
            $currentRowP = "<a href='http://{$_SERVER['SERVER_NAME']}$scriptPath/index.php?title=$titleP' style='$textSizeP' color='$color' hicolor='$hicolor'>{$title->getText()}</a>";
        }
        else { 
            // unable to reliably pass wiki titles containing apostrophes:  show the name but no link
            $currentRowP = "<a href='' style='$textSizeP' color='$color' hicolor='$hicolor'>{$title->getText()}</a>";
        }
        $links .= $currentRowP;
    }
 
	// sort and load No-Flash links 
	ksort ($linksArray);
	foreach ($linksArray as $row)
		$linksNoFlash .= $row;
 
	// if flash display, send both flash and flash-failure (html-only) data
	if ($flash) {
	$output = "
	<script type=\"text/javascript\" src=\"$scriptPath/extensions/Nimbus/swfobject.js\"></script>
	<div id=\"flashcontent\"><div class=\"" . implode( ' ', $cloudClasses ) . "\" style=\"{$cloudStyle}\">
		$linksNoFlash</div></div>
	<script type=\"text/javascript\">
		var so = new SWFObject(\"$scriptPath/extensions/Nimbus/tagcloud.swf\", \"tagcloud\", \"$flash_width\", \"$flash_height\", \"7\", \"#ffffff\");
		// uncomment next line to enable transparency
		so.addParam(\"wmode\", \"transparent\");
		so.addVariable(\"tcolor\", \"0x333333\");
		so.addVariable(\"mode\", \"tags\");
		so.addVariable(\"distr\", \"true\");
		so.addVariable(\"tspeed\", \"$speed\");
		so.addVariable(\"tagcloud\", \"<tags>$links</tags>\");
		so.write(\"flashcontent\");
	</script>
"; 
	}	
	// else use only html data
	else
            $output = $linksNoFlash;
 
	return $output;
}
 
/*
 * Return parameters from mediaWiki; 
 *	use Default if parameter not provided; 
 *	use '' or 0 if Default not provided
 */
function getMediaWikiVar( $input, $name, $isNumber = false ) {
    $defaults = array(
        'flash'           => 0,         // use flash? 0=false/1=true (0 for compatibility with WikiCategoryTagCloud)
        'min_size'        => 60,        // minimum text size (a percentage of normal)
        'increase_factor' => 150,       // difference between smallest & largest item fonts (percentage)
        'min_count'       => 0,         // minimum number of links to be considered for display
        'max_items'       => 30,        // maximum items to display in a cloud
        'point_factor'    => 175,       // relative sizing of flash fonts as a percentage of static fonts
        'speed'           => 150,	    // relative speed of sphere: 25 - 500 is "normal"
        'flash_width'     => 330,       // fixed-width of flash display area (generally wider than high for text)
        'flash_height'    => 230,       // fixed-height of flash display area
        'color'	          =>'0x002bb8', // item color
        'hicolor'         =>'0xcc2200', // item mouse-over color
        'exclude'         =>'CategoryName, Delete, Help',  // categories named here will not be considered for display
        'cloud_table'     =>'categorylinks', // Cloud Table Name
        'cloud_column'    =>'cl_to',    // Cloud Column Name, containing Wiki Page Titles
        'wanted_cloud'    => 0,         // Requested Items / Wanted Items Cloud? 0=false/1=true
);
 
    if (isset ($defaults[$name]))
        $default = $defaults[$name];
    else
        $default = ($isNumber) ? 0 : '';
 
    if ( preg_match( "/^\s*$name\s*=\s*(.*)/mi", $input, $matches ) ) {
        if ( $isNumber ) {
            return intval( $matches[1] );
        } 
        elseif ( $matches[1] != null)
             return htmlspecialchars( $matches[1] );
    }
    return $default;
};

See also[edit | edit source]

Notes and references[edit | edit source]

  1. http://code.google.com/p/swfobject
  2. http://www.debatrix.org/extensions/Nimbus/swfobject.js
  3. http://wordpress.org/extend/plugins/wp-cumulus/

Other resources[edit | edit source]

2013-01-15 extension code review