MediaWiki parser and extension hooks
[edit] Approach
As always, I try to build on the work of others wherever possible.
[edit] MediaWiki hooks
MediaWiki provides several hooks that can be used to extend the functionality of the MediaWiki software. Assigning a function (known as an event handler) to a hook will cause that function to be called at the appropriate point in the main MediaWiki code, to perform whatever additional task(s) the developer thinks would be useful at that point. Each hook can have multiple handlers assigned to it, in which case it will call the functions in the order that they are assigned, with any modifications made by one function passed on to subsequent functions in the chain.
I suspect that most MediaWiki page-level hooks get called every time a page is loaded - including templates - so they can't be used for display-page processing, like building the actual list of citations. I've experimented by writing an extension that simply echo's a message when the extension is called.
[edit] Hook Testbed
The MediaWiki developer documentation typically ranges from sparse to MIA, so sometimes it's best to just stick some trace statements in the code and see what's going on internally.
[edit] Extending Extensions
For this wiki, I need some extended functionality:
- Cite.php does a great job for references within a single page, but it gets hopelessly confused with transclusion. I want to include references directly in transcluded sections, like quotations or image captions.
- Lst.php works well for named sections. I want to use named paragraphs too.
- I also want it to (optionally) include a link back to the original source.
[edit] Generic Extension Wrapper
Is it possible to write an extension-extension, an extension that adds to the functionality of an existing extension?For example, along with transcluded text, we might want to include a link back to the original source. Rather than rewriting the existing lst.php code, it would be cleaner to write some code that intercepts the {{#lst: tag handler, executes the original code, then appends the link before handing the result back to the parser.
[edit] Parser hooks
This information comes from browsing the source code for Parser.php.
-
ParserClearState: Called for each page, including template pagess
[edit] Page-display hooks
- OutputPageParserOutput: Called from
addParserOutputNoText. Called each time a block is going to be output, before the content is converted to HTML. - OutputPageBeforeHTML: Called each time a block of HTML is going to be output; could change the HTML.
[edit] Article-display hooks
- ArticlePageDataBefore: Called before fetching the page data from the database; could change parameters for the database lookup.
- ArticlePageDataAfter: Called after the page data is fetched from the database; could change the raw row data.
- ArticleAfterFetchContent: Called after the page data has been loaded from the database and wrapped with user and revision information; could change either the content or the wrapper information.
- ArticleViewHeader: Called after the page has been fetched (from database or the cache), before calling
$wgOut->addPrimaryWikiText
[edit] Development Notes
[edit] Quotations
I need to be able to include a particular block of text (typically, a quotation) from one page into another. This needs to be a parser function and not an XML-style tag because I need to have the system parse the resulting wikitext. I can't use a template with {{switch}} because this approach evaluates all the wikitext before doing the selection, which causes all kinds of weirdness with things like the <ref> extension.
MediaWiki.org:ParserBeforeStrip
[edit] Table of Contents
What's a good way to turn off section numbering (or numbering in TOC) on a single page?
.tocnumber { display: none; }
- No official way to do it
- A good fix would be to add a different __TOC__ keyword, like __TOCNONUMBER__ or __ALTTOC__.
- The parser checks the option switch Auto-number headings as it builds the page, so an extension would need to clear the flag at the start of the page, then restore it at the end.
- Is there a hook for this? The earliest parse hook is ParserBeforeStrip, and the last is ParserAfterTidy. A page-level hook could scan the page text for the __ALTTOC__ keyword, toggle the flag, and replace the tag with the official TOC one. Then on exit it would restore the original state ... but what about included pages?
3394,4
function formatHeadings( $text, $isMain=true ) { global $wgMaxTocLevel, $wgContLang; $doNumberHeadings = $this->mOptions->getNumberHeadings();
Line 298:
wfRunHooks( 'ParserBeforeStrip', array( &$this, &$text, &$this->mStripState ) );
wfRunHooks( 'ParserAfterTidy', array( &$this, &$text ) );
[edit] AfjRef
- How about calling one parse extension from another?
Parser.php 3912
function setFunctionHook($id, $callback, $flags = 0) { $oldVal = isset($this->mFunctionHooks[$id]) ? $this->mFunctionHooks[$id] : null; $this->mFunctionHooks[$id] = $callback;
2990
$funcArgs = array_map('trim', $args); $funcArgs = array_merge(array(&$this, trim(substr($part1, $colonPos + 1))), $funcArgs); $result = call_user_func_array($this->mFunctionHooks[$function], $funcArgs);
- So the extension would need
global $wgParser; $function = "ref"; $result = call_user_func_array($wgParser->mFunctionHooks[$function], $funcArgs);