Last modified: 2011-03-13 18:05:07 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T16204, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 14204 - Extension data: Optionally include example installation + example usage.
Extension data: Optionally include example installation + example usage.
Status: RESOLVED WONTFIX
Product: MediaWiki
Classification: Unclassified
General/Unknown (Other open bugs)
1.13.x
All All
: Lowest enhancement (vote)
: ---
Assigned To: Nobody - You can work on this!
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2008-05-21 06:55 UTC by Nick Jenkins
Modified: 2011-03-13 18:05 UTC (History)
2 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments

Description Nick Jenkins 2008-05-21 06:55:54 UTC
It could be handy for users and for testers if extensions could optionally include an example of the minimal additions required to LocalSettings.php for installing them, and an example of how to use the extension (for Tag extensions or Parser Function extensions that alter wiki syntax). This is partly a problem of agreeing on a good convention, and partly a technical problem.

One possible way might be (using the ImageMap extension as an example) if two elements were added to the $wgExtensionCredits array:
-------------------------------
$wgExtensionCredits['parserhook']['ImageMap'] = array(
        'name'           => 'ImageMap',
        'svn-date' => '$LastChangedDate: 2008-05-06 21:59:58 +1000 (Tue, 06 May 2008) $',
        'svn-revision' => '$LastChangedRevision: 34306 $',
        'author'         => 'Tim Starling',
        'url'            => 'http://www.mediawiki.org/wiki/Extension:ImageMap',
        'description'    => 'Allows client-side clickable image maps using <nowiki><imagemap></nowiki> tag.',
        'descriptionmsg' => 'imagemap_desc',
+        'usage-example'  => "<imagemap>\nImage:Framing_hammer_956.jpg|\nrect 1 1 299 218 [[Use a Hammer Safely]]\ndesc none\n</imagemap>",
+        'basic-install'  => 'require_once( "$IP/extensions/ImageMap/ImageMap.php" );',
);
-------------------------------

... or alternatively, put all of this configuration information into a standard INI file name - e.g. "config.ini" - as having a standard file name containing this type of data could be useful to testers, and for testing software, which could now know how to install and smoketest an extension. An example config.ini could be:
-------------------------------
name = ImageMap
svn-date = "$LastChangedDate: 2008-05-06 21:59:58 +1000 (Tue, 06 May 2008) $"
svn-revision = "$LastChangedRevision: 34306 $"
author = "Tim Starling"
url = "http://www.mediawiki.org/wiki/Extension:ImageMap"
description = "Allows client-side clickable image maps using <nowiki><imagemap></nowiki> tag."
descriptionmsg = "imagemap_desc"
usage-example = "<imagemap>
Image:Framing_hammer_956.jpg|
rect 1 1 299 218 [[Use a Hammer Safely]]
desc none
</imagemap>"
basic-install = "require_once( \"$IP/extensions/ImageMap/ImageMap.php\" );"
-------------------------------

... and then use a line like to give current behaviour:
-------------------------------
$wgExtensionCredits['parserhook']['ImageMap'] = parse_ini_file( 'config.ini' );
-------------------------------

Note - the main problem with trying to give current behaviour in the above line is a bug in older versions of PHP with parse_ini_file: I have observed that the parse_ini_file in PHP 5.1.2 does not properly handle escaped quotes (as in the "basic-install" line above), and neither do builds snaps.php.net builds from March 2007, but it works correctly with snaps.php.net builds now, so at some point between March 2007 and now this PHP bug was fixed.
Comment 1 Brion Vibber 2008-05-22 18:15:38 UTC
How about a nice README file?
Comment 2 Nick Jenkins 2008-05-23 00:29:49 UTC
> How about a nice README file?

A nice README is perfect for humans, but not so good for software (unless there's a standard format). So just to clarify, this is so software can say "okay, this extension can be installed like so, and to get the extension to do something, I do X". Potential applications are for testing, and perhaps for some sort of web interface to make basic extension installation and telling-if-it-is-working possible using a GUI rather than via the command line. Most of my waffle above is talking about possible implementation details, but I probably should have outlined the reasons first :-)
Comment 3 Daniel Friesen 2008-05-23 17:17:56 UTC
INI Files are ugly. And even if they were used, with how badly PHP works with them we'd be using a custom wfParseIni function rather than using PHP's built in.

XML files are nicer, and more extensible. But the PHP support again isn't that great. Though, there is a PHP.XPath project on SourceForge which has a great library which works in both PHP4 and PHP5 that allows XPath to be used with absolutely no extra builtin PHP dependencies.

But honestly we shouldn't be doing this kind of stuff with the aim of GUI installation. Installing by a GUI needs a whole hellovalotta more data than what wgExtensionCredits contains or is meant to contain. You need everything from dependencies on other Extensions, to Dependencies on PHP builtins. And various other info including exactly what configuration options you have, and exactly what type and what kind of input can be put into them.

Before you even think of extending into another format, ask yourself why it is you need another format.
The answer to that is likely "Because I would need to load the Extension's file to get that info and that would install the extension".
That is what needs to be solved, not how extension credits are stored.

What language would we be building a GUI? PHP. Command line stuff would also be PHP. Basically there's little reason for anything other than PHP to be used for anything like installation or anything related to extensions. So what we need is not another format that is hard to make use of in PHP, it's a way to get extension data without actually loading the internals of the extension.

Something I've been pitching for awhile is a builtin Extension class, and a set of things which would make installation of extensions something more builtin.

<pre><?php
class WikiCode extends Extension {
	
	/**
	 * Static info functions
	 */
	static function getExtensionCredit( $credit, $lang = null ) {
		switch( $credit ) {
			case 'type':return 'parserhook';
			case 'name':return __CLASS__;
			case 'author':return array(
				'realname' => 'Daniel Friesen',
				'url' => 'http://wiki-tools.com/wiki/User:Dantman',
				'email' => 'dan_the_man@telus.net
			case 'version':return '1.0a';
			case 'svn-date':return '$LastChangedDate: 2008-05-06 21:59:58 +1000 (Tue, 06 May 2008) $';
			case 'svn-revision':return '$LastChangedRevision: 34306 $';
			case 'url':return 'http://wiki-tools.com/wiki/WikiCode';
			case 'description':
				require self::getExtensionFile( 'i18n.description.inc' );
				return $description[$lang];
				break;
		}
	}
	
	static function getExtensionMessagePrefixes() {
		return 'wikicode';
	}
	
	static function getExtensionFile( $file = null ) {
		static $eIP = dirname(__FILE__);
		if( isset($file) ) return "$eIP/$file";
		return $eIP;
	}
	
	/**
	 * Config variables
	 */
	var $cUseUncacheableFunctions = true;
	var $cUseStringFunctions      = true;
	var $cUseRegex                = true;
	
	
	/**
	 * Config limits
	 */
	var $cLimitTitleQuery         = 100;  // Limit to how many queries for titles may be made.
	var $cLimitTimeChars          = 6000; // 
	var $cLimitStringSearch       = 30;   // 
	var $cLimitStringReplace      = 30;   // 
	var $cLimitStringPad          = 100;  // 
	var $cLimitLoopCount          = 100;  // Total limit to how many loops may be made in a page.
	
	/**
	 * Instanced extension
	 */
	function __construct() {
		global $wgAutoloadClasses, $wgHooks, $wgExtensionMessagesFiles;
		$eIP = self::getExtensionFile();
		
		$wgAutoloadClasses['ExprError']  = "$eIP/Expr.php";
		$wgAutoloadClasses['ExprParser'] = "$eIP/Expr.php";
		// Create autoloads for the individual WikiCode groups
		foreach( array(
			'Logic', 'Loop', 'Page', 'Math', 'String', 'Time', 'Error',
			'Limiter'
		) as $group ) {
			$wgAutoloadClasses[__CLASS__.'_'.$group"] = "$eIP/FunctionClasses/{$group}.php";
		}
		
		$wgHooks['ParserGetHooks'][] = __CLASS__.'::SetupParserFunctionsForParser';
		
		$wgExtensionMessagesFiles[__CLASS__] = "$eIP/i18n.inc";
		
		return true; // Extension OK
	}
	
	function SetupParserFunctionsForParser( $parser ) {
		$parser->setFunctionHook( 'fi', array( __CLASS__.'_Logic', 'ifHook' ) );
		return true;
	}
	
	function SetupLanguageMagic( &$magicWords, $langCode ) {
		# English is used as a fallback, and the English synonyms are
		# used if a translation has not been provided for a given word
		$localWords = array();
		require self::getExtensionFile( 'i18n.magic.inc' );
		foreach( $words['en'] as $key => $value ) {
			if( isset($localWords[$key]) && is_array($localWords[$key]) ) {
				$localWords[$key] = array_merge( (array) $localWords[$key], (array) $value );
			} else {
				$localWords[$key] = (array) $value;
			}
		}
		if( $langCode != 'en' && isset($words[$langCode]) ) {
			foreach( $words[$langCode] as $key => $value ) {
				$localWords[$key] = array_merge( (array) $localWords[$key], (array) $value );
			}
		}
		foreach( $localWords as $word => $trans ) {
			$magic = $trans;
			array_unshift( $magic, 0 );
			$magicWords[$word] = $magic;
		}
		return true;
	}
}</pre>

That would be stored in WikiCode/Extension.inc
Say for some reason you stored your extension in /var/mediawiki/extensions
And you also used my 'wiki-tools' subdirectory.
Then to load the extension, you would be using:
$wgExtensionPaths[] = '/var/mediawiki/extensions';
$wgExtensionPaths[] = '/var/mediawiki/extensions/wiki-tools';
$wgLoadExtensions['WikiCode'] = array(
	'LimitTitleQuery' => 250
);

MediaWiki would load the extension when it is ready to. Additionally the $cLimitTitleQuery config there would be set to 250.
If you didn't notice it, the __construct() is basically equivalent to the $wgExtensionFunctions. And there are a few of my other proposals in there, extension message prefixes, and a hook for loading parserfunctions into the parser.
In short you could even track down a list of their extensions and the info, by grabbing the list of directories inside of the $wgExtensionPaths paths (Each being a name), and then checking if any contain a Extension.inc file, and then including that and calling $name::getExtensionCredit for any piece of info you need.
So static calls are info about the extension (Loading the file doesn't need to mean installation), and an instance is an installed extension. On a side note useful extension functions can also be programmed into the Extension class.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links