Extension talk:UnitsFormatter
Unit Names
editOne area which probably needs some work is in the names of units. For example, can we do something less cumbersome than "British gallons" and "US gallons", while still being unambiguous? One huge piece of nastiness in the unit table is the calories and BTUs. It would make sense to have one unit just called "calorie", but I could not find any evidence that there is one particular version which is predominant. Any ideas? JohanTheGhost 16:15, 21 June 2007 (UTC)
- I would love it if you could include a user preference that allowed for always using the abbreviation instead of the full unit name for the primary unit. I administrate a wiki that has a lot of plant data with leaf measurements, and seeing the full names of centimeters and inches over and over makes the reading more cumbersome than seeing the abbreviations. Overall, though, I love this extension!
- --76.215.127.150 (WildeRix) 21:02, 13 July 2007 (UTC)
Parser Function
editI think this extension would be useful as a Parser Function in addtion to (or instead of) an extension tag. The calling could be akin to {{#unit:7.2 usgal}}
. This way you gain the ability to interpret template parameters and extend the functionality. --Jimbojw 16:42, 21 June 2007 (UTC)
- Aha! That nicety (interpreted parameters) had escaped me. I actualy started with it as a function (
{{#unit:67|c|1|k}}
for 67 celcius, 1 digit, alternate units kelvin), but thought a tag would be less cumbersome. Of course, I could call the parser to process the input at the beginning -- is a function more efficient than that?
- Or how about:
{{#unit:7.2 usgal l|naut}}
- ie.
- scrap the "digits" parameter, just use the input precision (which I do by default anyhow)
- alt units just specified as additional units (here us gal and litres)
- second parameter for realm
- ...? JohanTheGhost 18:27, 21 June 2007 (UTC)
- Any progress with this? I'm working on a cooking wiki project at the moment, and being able to nest parser functions/access template parameters would really help (we're making all of our recipe amounts for single serves and then multiplying that by a template param to get the amount needed for how big the meal would be).
- I'm also using DPL at the moment and rather than having explicit parameters when used in parser function mode, they do it like this (I haven't looked at the code yet, but I expect they split the string around the = and switch on the parameter name):
{{#dpl: param1=foo | param2=bar}}
- - Cheese 4th October 2007
Solution
edit- I had a bit of a go at it, and I've got it up to where it does what I need. Here's the code:
- Add this into __construct()
//Add function hooks - Cheese
$wgParser->setFunctionHook('unit', array (&$this, 'unitFunction') );
- And this wherever suits
/**
* Handler for {{#unit:}} function
* Reads given params and calls unit(), supplying defaults where necessary
* - Cheese
*/
public function unitFunction(&$parser)
{
$value = 0; //Default numeric value
$unit = 'm'; //Default unit.
$realm = null; //Default realm
$digits = ''; //Default number of decimal placces to display
$alt = null; //Default aditional units to display
$showErrors = false; //Default showErrors value
$errors = '';
$arghCount = func_num_args();
if ($arghCount < 2)
{
//No arguments specified!
$errors = $errors."*Error: UnitsFormatter - no arguments specified\n";
}
$arghList = func_get_args();
//Extract all the useful params
for ($i = 1; $i < $arghCount; $i++)
{
$temp = explode("=", $arghList[$i]);
if (trim($temp[0]) == "value")
{
$value = trim($temp[1]);
}
else if (trim($temp[0]) == "unit")
{
$unit = trim($temp[1]);
}
else if (trim($temp[0]) == "realm")
{
$realm = trim($temp[1]);
}
else if (trim($temp[0]) == "digits")
{
$digits = trim($temp[1]);
}
else if (trim($temp[0]) == "extra")
{
$alt = trim($temp[1]);
}
else if (trim($temp[0]) == "errors")
{
$showErrors = true;
}
else
{
//We don't know what to do with this one
$errors = $errors."*Error: UnitsFormatter - unrecognised parameter ".$arghList[$i]."\n";
}
}
//If we're showing errors, then ummm show the errors
if ($showErrors)
{
return $this->unit($value, $unit, $realm, $digits, $alt)."\n".$errors;
}
return $this->unit($value, $unit, $realm, $digits, $alt);
}
- I've not done any PHP before, so it may not be the most elegant way of doing it - eg: how efficient is trim() in this sort of situation?
- - Cheese 5th October 2007
Scaling
editAny thoughts on converting the output to an appropriate unit in the native (author specified) measurement system? One of the things I needed a parser function for was so that I could convert values that were dynamically generated a template param.
eg:
{{#unit: value = {{#expr: {{{1}}} * 500}} | unit = g}}
It's all working fantastically, except that 80,000 grams would maybe be a bit superfluous. It'd be simple enough for metric to convert anything that returned true for (value / 100) > 1 to the next unit up, but non metric measurements would be a bit more complex.
- Cheese 5th October 2007
This extension doesn't work
editIn the header, this extension didn't work for my installation (MediaWiki 1.21). Hope that helps for anyone downloading this. NemesisAT (talk) 20:24, 31 August 2013 (UTC)