Extension:Terminology
From MediaWiki.org
|
Release status: stable |
|
|---|---|
| Implementation | Extended syntax |
| Description | Enable a Glossary or define Terminology within MediaWiki using tooltips. |
| Author(s) | BarkerJr with modifications by Benjamin Kahn (xkahn <at> zoned <dot> net) |
| Last Version | 2007.12.16+20090529Patches (8-28-08) |
| MediaWiki | 1.6 (and above) |
| License | LGPL 2+ |
| Download | See files below |
|
check usage (experimental) |
|
Contents |
[edit] Related Extensions
An alternative version of this extension can be found at Extension:Glossary
[edit] What can this extension do?
Ever been reading a technical article with lots and lots of acronyms? Unless you know all the terminology they are using, it can be really frustrating trying to understand what the author means.
This extension allows wiki authors to define a list of acronyms and their definitions on a special page. Whenever that acronym is found, it will be highlighted and mousing over it will reveal the definition in a tooltip.
Additionally, using Walter Zorn's "JavaScript, DHTML Tooltips" library (found at: http://www.walterzorn.com/tooltip/tooltip_e.htm ) you can customize the appearance of the tooltips.
[edit] Usage
By default, the page "Terminology" without a namespace will be used as the source of acronyms and their definitions. It's also possible to modify the extension to put the definitions in a protected namespace.
[edit] Changelog
- Patches from May 29, 2009:
- Better support for the FCKEditor extension
- Do not show underlines when printing wiki pages
- Patches from Aug 28, 2008:
- Make the regex case sensitive for acronyms (Thanks Abrillon)
- Add support for the FCKEditor extension
- Allow a single newline in between the acronym and its definition
[edit] Installation
1. Create the file:
[edit] For PHP5: extensions/terminology.php
<?php /* * Copyright (C) 2007 BarkerJr and (C) 2008 Benjamin Kahn * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * For nicer tooltips, download JavaScript, DHTML Tooltips from Walter Zorn at * http://www.walterzorn.com/tooltip/tooltip_e.htm and extract it to $wgScriptPath/extensions/tooltip/ * * Use definition-lists in the Terminology page. Place one definition on each line. For example: * ;CS-S:CounterStrike Source, a game by Valve * ;HTML:HyperText Markup Language */ $wgExtensionCredits['parserhook'][] = array( 'name' => 'Terminology', 'description' => 'Provides tooltips from the [[Terminology]] defined for all instances of the given term', 'version' => '2007.12.16+20080828Patches', 'author' => 'BarkerJr modified by Benjamin Kahn (xkahn@zoned.net)' ); $wgExtensionFunctions[] = 'terminologySetup'; function terminologySetup() { global $wgOut, $wgScriptPath; $wgOut->addHTML("<style text=\"text/css\" media=\"screen\"><!-- .terminologydef {border-bottom: 1px dashed green;} --></style>"); if (is_file ('extensions/tooltip/wz_tooltip.js')) { $wgOut->addHTML("<script type='text/javascript' src='$wgScriptPath/extensions/tooltip/wz_tooltip.js'></script>"); } } $wgHooks['ParserBeforeTidy'][] = 'terminologyParser'; function terminologyParser(&$parser, &$text) { global $wgRequest; $action = $wgRequest->getVal( 'action', 'view' ); if ($action=="edit" || $action=="ajax") return false; $rev = Revision::newFromTitle(Title::makeTitle(null, 'Terminology')); if ($rev) { $content = $rev->getText(); if ($content != "") { $changed = false; $doc = new DOMDocument(); @ $doc->loadHTML('<meta http-equiv="content-type" content="charset=utf-8"/>' . $text); $c = explode("\n", $content); reset($c); while (list($key, $entry) = each($c)) { $terms = explode(':', $entry, 2); if ($terms[0][0] == ';') { // It's possible that the definition is on the next line if (count($terms) == 1) { list($k1, $e1) = each($c); if ($e1[0] == ':') { $term = trim(substr($terms[0], 1)); $definition = trim(substr($e1, 1)); } else { continue; } } elseif (count($terms) == 2) { $term = trim(substr($terms[0], 1)); $definition = trim($terms[1]); } else { continue; } if (terminologyParseThisNode($doc, $doc->documentElement, $term, $definition)) { $changed = true; } } } if ($changed) { $text = $doc->saveHTML(); } } } return true; } function terminologyParseThisNode($doc, $node, $term, $definition) { $changed = false; if ($node->nodeType == XML_TEXT_NODE) { $texts = preg_split('/\b('.preg_quote($term).'s?)\b/u', $node->textContent, -1, PREG_SPLIT_DELIM_CAPTURE); if (count($texts) > 1) { $container = $doc->createElement('span'); for ($x = 0; $x < count($texts); $x++) { if ($x % 2) { $span = $doc->createElement('span', $texts[$x]); if (!is_file ('extensions/tooltip/wz_tooltip.js')) { $span->setAttribute('title', $term . ": " . $definition); $span->setAttribute('class', 'terminologydef'); } else { $bad = array ("\"", "'"); $good = array ("\\\"", "\'"); $span->setAttribute('onmouseover', "Tip('".str_replace ($bad, $good, $definition)."', STICKY, true, DURATION, -1000)"); $span->setAttribute('class', 'terminologydef'); $span->setAttribute('onmouseout', "UnTip()"); } $span->setAttribute('style', 'cursor:help'); $container->appendChild($span); } else { $container->appendChild($doc->createTextNode($texts[$x])); } } $node->parentNode->replaceChild($container, $node); $changed = true; } } elseif ($node->hasChildNodes()) { // We have to do this because foreach gets confused by changing data $nodes = $node->childNodes; $previousLength = $nodes->length; for ($x = 0; $x < $nodes->length; $x++) { if ($nodes->length <> $previousLength) { $x += $nodes->length - $previousLength; } $previousLength = $nodes->length; $child = $nodes->item($x); if (terminologyParseThisNode($doc, $child, $term, $definition)) { $changed = true; } } } return $changed; }
[edit] For PHP4: extensions/terminology.php
<?php /* * Copyright (C) 2007 BarkerJr and (C) 2008 Benjamin Kahn * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* * For nicer tooltips, download JavaScript, DHTML Tooltips from Walter Zorn at * http://www.walterzorn.com/tooltip/tooltip_e.htm and extract it to $wgScriptPath/extensions/tooltip/ * * Use definition-lists in the Terminology page. Place one definition on each line. For example: * ;CS-S:CounterStrike Source, a game by Valve * ;HTML:HyperText Markup Language */ $wgExtensionCredits['parserhook'][] = array( 'name' => 'Terminology', 'description' => 'Provides tooltips from the [[Terminology]] defined for all instances of the given term', 'version' => '2007.12.16+20080828Patches', 'author' => 'BarkerJr modified (and ported to PHP4) by Benjamin Kahn (xkahn@zoned.net)' ); $wgExtensionFunctions[] = 'terminologySetup'; function terminologySetup() { global $wgOut, $wgScriptPath; $wgOut->addHTML("<style text=\"text/css\" media=\"screen\"><!-- .terminologydef {border-bottom: 1px dashed green;} --></style>"); if (is_file ('extensions/tooltip/wz_tooltip.js')) { $wgOut->addHTML("<script type='text/javascript' src='$wgScriptPath/extensions/tooltip/wz_tooltip.js'></script>"); } } $wgHooks['ParserBeforeTidy'][] = 'terminologyParser'; function terminologyParser(&$parser, &$text) { global $wgRequest; $action = $wgRequest->getVal( 'action', 'view' ); if ($action=="edit" || $action=="ajax") return false; $rev = Revision::newFromTitle(Title::makeTitle(null, 'Terminology')); if ($rev) { $content = $rev->getText(); if ($content != "" && $text != "") { $changed = false; @ $doc = xmldoc ($text); $c = explode("\n", $content); reset($c); while (list($key, $entry) = each($c)) { $terms = explode(':', $entry, 2); if ($terms[0][0] == ';') { // It's possible that the definition is on the next line if (count($terms) == 1) { list($k1, $e1) = each($c); if ($e1[0] == ':') { $term = trim(substr($terms[0], 1)); $definition = trim(substr($e1, 1)); } else { continue; } } elseif (count($terms) == 2) { $term = trim(substr($terms[0], 1)); $definition = trim($terms[1]); } else { continue; } if (terminologyParseThisNode($doc, $doc->root(), $term, $definition)) { $changed = true; } } } if ($changed) { $text = $doc->dump_mem(true); } } } return true; } function terminologyParseThisNode($doc, $node, $term, $definition) { $changed = false; if ($node->node_type() == XML_TEXT_NODE) { $texts = preg_split('/\b('.preg_quote($term).'s?)\b/u', $node->get_content(), -1, PREG_SPLIT_DELIM_CAPTURE); if (count($texts) > 1) { $container = $doc->create_element('span'); for ($x = 0; $x < count($texts); $x++) { if ($x % 2) { $span = $doc->create_element('span'); $span->set_content($texts[$x]); if (!is_file ('extensions/tooltip/wz_tooltip.js')) { $span->set_attribute('title', $term . ": " . $definition); $span->set_attribute('class', 'terminologydef'); } else { $bad = array ("\"", "'"); $good = array ("\\\"", "\'"); $span->set_attribute('onmouseover', "Tip('".str_replace ($bad, $good, $definition)."', STICKY, true, DURATION, -1000)"); $span->set_attribute('onmouseout', "UnTip()"); $span->set_attribute('class', 'terminologydef'); } $span->set_attribute('style', 'cursor:help'); $container->append_child($span); } else { $container->append_child($doc->create_text_node($texts[$x])); } } $parent = $node->parent_node(); $parent->replace_child($container, $node); $changed = true; } } elseif ($node->has_child_nodes()) { // We have to do this because foreach gets confused by changing data $nodes = $node->child_nodes(); $previousLength = count($nodes); for ($x = 0; $x < count($nodes); $x++) { if (count($nodes) <> $previousLength) { $x += count($nodes) - $previousLength; } $previousLength = count($nodes); $child = $nodes[$x]; if (terminologyParseThisNode($doc, $child, $term, $definition)) { $changed = true; } } } return $changed; }
[edit] LocalSettings.php
2. Add the following to the end of your LocalSettings.php:
require_once( "$IP/extensions/terminology.php" );
3. (Optional) If you wish to use the Javascript-based tooltips, you need to download Walter Zorn's "JavaScript, DHTML Tooltips" library. (found at: http://www.walterzorn.com/tooltip/tooltip_e.htm ) Create the directory: extensions/tooltip.
mkdir -p extensions/tooltip
And uncompress the archive "wz_tooltip.zip" into that directory. You should have the latest version of the library (version 5.13 at the time of this writing.) (At the end, you should have 3 files: extensions/tooltip/tip_centerwindow.js, extensions/tooltip/tip_followsscroll.js, and extensions/tooltip/wz_tooltip.js )
4. Create the page "Terminology"
5. Add one line to this page for each acronym. Each line should start with a ';' (semicolon), then the text to be replaced followed by a ':' (colon) followed by the text to replace it with.
[edit] Sample Terminology Page
Support single line definitions ;FTP:File Transport Protocol ;AAAAA:American Association Against Acronym Abuse ;ACK:Acknowledge ;AFAIK:As Far As I Know ;AWGTHTGTATA:Are We Going To Have To Go Through All This Again And multi-line definitions ;HTTP :HyperText Transfer Protocol
[edit] Parameters
1. To lock down the terminology, modify the terminology.php file.
Find the line:
$rev = Revision::newFromTitle(Title::makeTitle(null, 'Terminology'));
and change it to:
$rev = Revision::newFromTitle(Title::makeTitle(8, 'Terminology'));
The Terminology Page will now be located at:
MediaWiki:Terminology
You can also change the name of the "Terminology" page by replacing the quoted name with something else.
2. You can modify the options of the javascript tooltip style by editing the line (89) with the options "STICKY, true, DURATION, -1000" to suit your needs.
3. You can change the number of times a matched word will be defined. (The default is every time.) Find the line that says:
$texts = preg_split('/\b('.preg_quote($term).'s?)\b/u', $node->textContent, -1, PREG_SPLIT_DELIM_CAPTURE);
and change the "-1" to 1 or 2.
[edit] Known problems
- Conflicts with the FCKeditor extension.
- To correct this issue, add the __NORICHEDITOR__ magic word to the top of the Terminology page. This will cause it to never use FCKeditor to edit the page.
- Any empty lines in the Terminology page will cause "Notice: Uninitialized string offset" errors displayed on Wiki pages.
- To correct this issue, change $terms[0][0] to @$terms[0][0] on line number 62 of extensions/terminology.php.
- PHP 4.3.0 and newer
- Changes to the xmldoc API require:
- replace
- Changes to the xmldoc API require:
@ $doc = xmldoc ($text);
with
$doc = domxml_open_mem('<r>'.$text.'</r>');
-
-
- replace
-
$text = $doc->dump_mem(true);
with
$text = substr($doc->dump_mem(true), 25, -5 );
-
-
- append
-
elseif($node->node_name() == 'a') { // <a /> nodes confuse browsers, that expect <a ></a> $padding = $doc->create_text_node(''); $node->append_child( $padding ); }
to terminologyParseThisNode, before return $changed