Extension:Nimbus

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

Release status:Extension status beta

Nimbus screenshot.png
ImplementationTemplate:Extension#type Tag
DescriptionTemplate:Extension#description Cumulus (flash) presentation of top categories, degrading to Text Category Cloud
Author(s)Template:Extension#username Mark Smaga (Msmagatalk)
Latest versionTemplate:Extension#version 1.1 (2010-01-06)
MediaWikiTemplate:Extension#mediawiki tested on 1.16.0beta3, 1.15.x and 1.14.0
Database changesTemplate:Extension#needs-updatephp No
LicenseTemplate:Extension#license creative commons
Download see installation instruction
ExampleTemplate:Extension#example
Hooks usedTemplate:Extension#hook
ParserFirstCallInitManual:Hooks/ParserFirstCallInit

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

Check usage and version matrix.

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]

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]

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]

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]

<?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]

Notes and references[edit]

  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]

2013-01-15 extension code review