Manual:Parser-Funktionen
Parser-Funktionen, die in MediaWiki 1.7 hinzugefügt wurden, sind eine Art Erweiterung, die eng mit dem Parser integriert sind. The phrase "parser function" should not be confused with Erweiterung:ParserFunctions , which is a collection of simple parser functions. (Siehe Hilfe:Erweiterung:ParserFunktionen für diese.)
Beschreibung
Während eine Tag Extension unverarbeiteten Text in HTML-Code verwandelt, kann eine Parser Function mit anderen Wiki-Elementen auf der Seite „interagieren“. Die Ausgabe einer Parser Function kann beispielsweise als Parameter für eine Vorlage oder für die Konstruktion eines Links genutzt werden.
Die typische Syntax für eine Parserfunktion lautet:
{{ #functionname: param1 | param2 | param3 }}
Für weitere Informationen, siehe die Dokumentation für Parser::setFunctionHook ( $id, $callback, $flags = 0 )
. Diese Dokumentation führt aus:
- Die Callback-Funktion sollte diese Form haben:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
- Oder mit
SFH_OBJECT_ARGS
:function myParserFunction( $parser, $frame, $args ) { ... }
The first variant of the call passes all arguments as plain text.
The second passes all arguments as an array of PPNode s, except for the first ($args[0]
), which is currently text, though this may change in the future.
These represent the unexpanded wikitext.
The $frame
parameter can be used to expand these arguments as needed.
This is commonly used for conditional processing so that only the true
case is evaluated with an if-
or switch-like
parser function.
The frame object can also climb up the document tree to get information about the caller and has functions to determine and manage call depth, time-to-live, and whether the result of the parser function is volatile.
Die Erstellung einer Parserfunktion ist etwas komplizierter als die Schaffung eines neuen Tag, weil der Name der Funktion ein magisches Wort sein muss — ein Schlüsselwort, das Aliase und Lokalisierung unterstützt.
Einfaches Beispiel
Hier ist ein Beispiel einer Erweiterung zur Erstellung einer Parser Function.
Die Registrierung geht in 'extension.json' und der Code in 'src/ExampleExtensionHooks.php' ein:
Standard: | Using the HookHandler interface: |
---|---|
extension.json | |
{
"name": "ExampleExtension",
"author": "Me",
"version": "1.0.0",
"url": "https://www.mediawiki.org/wiki/Extension:ExampleExtension",
"descriptionmsg": "exampleextension-desc",
"license-name": "GPL-2.0-or-later",
"type": "parserhook",
"MessagesDirs": {
"ExampleExtension": [
"i18n"
]
},
"AutoloadClasses": {
"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
},
"ExtensionMessagesFiles": {
"ExampleExtensionMagic": "ExampleExtension.i18n.php"
},
"Hooks": {
"ParserFirstCallInit": "ExampleExtensionHooks::onParserFirstCallInit"
},
"manifest_version": 1
}
|
{
"name": "ExampleExtension",
"author": "Me",
"version": "1.0.0",
"url": "https://www.mediawiki.org/wiki/Extension:ExampleExtension",
"descriptionmsg": "exampleextension-desc",
"license-name": "GPL-2.0-or-later",
"type": "parserhook",
"MessagesDirs": {
"ExampleExtension": [
"i18n"
]
},
"AutoloadClasses": {
"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
},
"ExtensionMessagesFiles": {
"ExampleExtensionMagic": "ExampleExtension.i18n.php"
},
"Hooks": {
"ParserFirstCallInit": "onParserFirstCallInit"
},
"HookHandlers": {
"ExampleExtensionHooks": {
"class": "MediaWiki\\Extension\\ExampleExtension\\Hooks"
}
},
"manifest_version": 1
}
|
ExampleExtensionHooks.php | |
<?php
class ExampleExtensionHooks {
// Registrieren Sie alle Render-Callbacks mit dem Parser
public static function onParserFirstCallInit( Parser $parser ) {
// Erstellen Sie einen Funktions-Hook, der das Zauberwort "example" mit renderExample() verknüpft.
$parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
}
// Darstellung der Ausgabe von {{#example:}}.
public static function renderExample( Parser $parser, $param1 = '', $param2 = '', $param3 = '' ) {
// Die Eingabeparameter sind Wikitext erweitert mit Vorlagen.
// Die Ausgabe sollte ebenfalls Wikitext sein.
$output = "param1 is $param1 and param2 is $param2 and param3 is $param3";
return $output;
}
}
|
<?php
class ExampleExtensionHooks implements ParserFirstCallInitHook {
// Register any render callbacks with the parser
public function onParserFirstCallInit( $parser ) {
// Create a function hook associating the <code>example</code> magic word with renderExample()
$parser->setFunctionHook( 'example', [ $this, 'renderExample' ] );
}
// Render the output of {{#example:}}.
public function renderExample( $parser, $param1 = '', $param2 = '', $param3 = '' ) {
// The input parameters are wikitext with templates expanded.
// The output should be wikitext too.
$output = "param1 is $param1 and param2 is $param2 and param3 is $param3";
return $output;
}
}
|
Eine weitere Datei, ExampleExtension.i18n.php, in Deinem Erweiterungsverzeichnis (nicht im Unterverzeichnis src/) sollte enthalten:
<?php
/**
* @license GPL-2.0-or-later
* @author Your Name (YourUserName)
*/
$magicWords = [];
/** English
* @author Your Name (YourUserName)
*/
$magicWords['en'] = [
'example' => [ 0, 'example' ],
];
Wenn diese Erweiterung aktiviert ist,
- {{#example: hello | hi | hey}}
bewirkt:
- param1 ist hello und param2 ist hi und param3 ist hey
LocalSettings.php
MediaWiki\MediaWikiServices::getInstance()->getContentLanguage()->mMagicExtensions['wikicodeToHtml'] = ['MAG_CUSTOM', 'custom'];
Within LocalSettings.php
Magic words and their handling parser functions can be defined entirely in LocalSettings.php.
$wgHooks['ParserFirstCallInit'][] = function ( Parser $parser )
{
MediaWiki\MediaWikiServices::getInstance()->getContentLanguage()->mMagicExtensions['wikicodeToHtml'] = ['wikicodeToHtml', 'wikicodeToHtml'];
$parser->setFunctionHook( 'wikicodeToHtml', 'wikicodeToHtml' );
};
function wikicodeToHtml( Parser $parser, $code = '' )
{
$title = $parser->getTitle();
$options = $parser->Options();
$options->enableLimitReport(false);
$parser = $parser->getFreshParser();
return [$parser->parse($code, $title, $options)->getText(), 'isHTML' => true];
}
Umfangreichere Funktionen
Für umfangreichere Funktionen, können Sie die Hook-Funktionen in eine _body.php oder Hooks.php-Datei aufteilen und mit statischen Funktionen einer Klasse arbeiten. Dann können Sie die Klasse mit $wgAutoloadClasses laden und in den Hooks die statischen Funktionen aufrufen, z.B.:
Schreiben Sie dies in die Datei extension.json
:
"Hooks": {
"ParserFirstCallInit": "ExampleExtensionHooks::onParserFirstCallInit"
},
"AutoloadClasses": {
"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
}
- Siehe Schreiben eines Event-Handlers für weitere Stile.
Und dies in die Datei src/ExampleExtensionHooks.php
:
class ExampleExtensionHooks {
public static function onParserFirstCallInit( Parser $parser ) {
$parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
}
}
Parserschnittstelle
Steuerung des Parsens der Ausgabe
Um den Wikitext Ihrer Parser Function vollständig geparst zurückgeben zu lassen (einschließlich Erweiterung der Vorlagen), setzen Sie die noparse
-Option bei der Rückgabe auf false:
return [ $output, 'noparse' => false ];
Wie es scheint, wurde der Standardwert für noparse
irgendwann um Version 1.12 von false auf true geändert.
Umgekehrt, damit Ihre Parser Function anstelle von Wikitext HTML zurückgibt, das ungeparst bleibt, benutzen Sie dies:
return [ $output, 'noparse' => true, 'isHTML' => true ];
Benennung
Standardmäßig fügt MW ein Raute-Zeichen („#“) zum Namen der jeweiligen Parserfunktion hinzu.
To suppress that addition (and obtain a parser function with no #
prefix), include the SFH_NO_HASH constant in the optional flags argument to setFunctionHook, as described below.
Bei der Wahl eines Namens ohne einen Hash-Präfix, beachten Sie, dass die Vorlageneinbindung einer Seite, deren Name mit dem der Funktion gefolgt von einem Doppelpunkt identisch ist, nicht mehr möglich ist. Vermeiden Sie insbesondere Funktionsnamen gleich einem Namensraum-Namen. Für den Fall, dass Interwiki-Vorlageneinbindung [1] aktiviert ist, vermeiden Sie auch Funktionsnamen die einem Interwiki-Präfix entsprechen.
Der setFunctionHook Hook
Weitere Einzelheiten zur Parser-Schnittstelle finden Sie in der Dokumentation zu setFunctionHook in includes/Parser.php. Hier ist eine (möglicherweise veraltete) Kopie der dortigen Dokumentation:
function setFunctionHook( $id, $callback, $flags = 0 )
Parameter:
- string $id - Die ID des magischen Worts
- mixed $callback - Die Callback-Funktion (oder das Objekt), die/das verwendet werden sollte
- integer $flags - Optional, auf die SFH_NO_HASH-Konstante setzen, um die Funktion ohne „#“ aufrufen zu können.
- SFH_NO_HASH (1) constant if you call the function without
#
. - SFH_OBJECT_ARGS (2) if you pass a PPFrame object and array of arguments instead of a series of function arguments, for which see above.
- Defaults to 0 (no flags).
- SFH_NO_HASH (1) constant if you call the function without
Rückgabewert: Die alte Callback-Funktion für diesen Namen, wenn überhaupt
Erstelle eine Funktion, z.B. {{#sum:1|2|3}}
. Die Callback-Funktion sollte diese Form haben:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
Die Callback-Funktion kann entweder das Textergebnis der Funktion zurückgeben, oder ein Array mit dem Text in Element 0, und eine Anzahl von Flags in den anderen Elementen. Die Namen der Flags werden in den Schlüsseln angegeben. Gültige Flags sind
Name | Type | Default | Description |
---|---|---|---|
found | Boolean | true
|
Der zurückgegebene Text ist gültig, Ausführen der Vorlage anhalten. Dies ist standardmäßig aktiviert. |
text | ? | ? | The text to return from the function. If isChildObj or isLocalObj are specified, this should be a DOM node instead. |
noparse | Boolean | true
|
Unsichere HTML-Tags sollten nicht entfernt werden, usw. |
isHTML | Boolean | ? | Der zurückgegebene Text ist HTML, schütze es gegen Wikitext-Transformationen But see discussion |
nowiki | Boolean | usually false
|
Wiki-Markup im Rückgabewert sollte maskiert werden |
isChildObj | Boolean | ? | true if the text is a DOM node needing expansion in a child frame.
|
isLocalObj | Boolean | ? | true if the text is a DOM node needing expansion in the current frame. The default value depends on other values and outcomes.
|
preprocessFlags | ? | false
|
Optional PPFrame flags to use when parsing the returned text. This only applies when noparse is false .
|
title | ? | false
|
The Title object where the text came from. |
forceRawInterwiki | Boolean | ? | true if interwiki transclusion must be forced to be done in raw mode and not rendered.
|
Expensive parser functions
Some parser functions represent a significant use of a wiki's resources and should be marked as "expensive". The number of expensive parser functions on any given page is limited by the $wgExpensiveParserFunctionLimit setting. What counts as expensive is left up to the function itself, but typically, anything that is likely to cause a delay that extends beyond simple processing of data should be considered. This includes things like database reads and writes, launching a shell script synchronously, or file manipulation. On the other hand, not all such functions should necessarily be tagged. Semantic MediaWiki, for example, only marks a percentage of its database reads as expensive. This is due to the fact that on certain data-intensive pages, it could easily overflow the normal expensive parser function limits. In cases like this, the potential for noticeably slower performance that doesn't get flagged as expensive is a trade-off to having the functionality that SMW offers.
To mark your parser function as expensive, from within the body of the function's code, use $result = $parser->incrementExpensiveFunctionCount();
.
The return value will be false
if the expensive function limit has been reached or exceeded.
Benannte Parameter
Parser Function unterstützen benannte Parameter nicht auf die gleiche Weise wie Vorlagen und Tag Extensions, aber es kann manchmal nützlich sein, dieses Verhalten zu simulieren. Benutzer sind oft daran gewöhnt, senkrechte Striche (|) zu verwenden, um Parameter zu trennen, sodass es auch im Kontext von Parser Function sinnvoll sein kann, dies zu ermöglichen. Hier ist ein einfaches Beispiel, wie das erreicht werden kann:
function ExampleExtensionRenderParserFunction( &$parser ) {
// Suppose the user invoked the parser function like so:
// {{#myparserfunction: foo=bar | apple=orange | banana }}
$options = extractOptions( array_slice( func_get_args(), 1 ) );
// Now you've got an array that looks like this:
// [foo] => 'bar'
// [apple] => 'orange'
// [banana] => true
// Continue writing your code...
}
/**
* Converts an array of values in form [0] => "name=value"
* into a real associative array in form [name] => value
* If no = is provided, true is assumed like this: [name] => true
*
* @param array string $options
* @return array $results
*/
function extractOptions( array $options ) {
$results = [];
foreach ( $options as $option ) {
$pair = array_map( 'trim', explode( '=', $option, 2 ) );
if ( count( $pair ) === 2 ) {
$results[ $pair[0] ] = $pair[1];
}
if ( count( $pair ) === 1 ) {
$results[ $pair[0] ] = true;
}
}
return $results;
}
Siehe auch
General and related guides:
- Manual: Entwickeln von Erweiterungen , or for more general information about extensions, see Handbuch:Erweiterungen and Erweiterungen-FAQ .
- Handbuch:Tag Erweiterungen
- Handbuch:Magische Wörter
Code:
- Handbuch:Parser.php
- Handbuch:Hooks/ParserFirstCallInit
- Parser function hooks - an (incomplete) list of parser functions provided by core and extensions
- The Parser Hooks PHP library, which provides an object orientated interface for declarative parser hooks
Examples:
- Die ParserFunctions-Erweiterung ist eine bekannte Sammlung von Parserfunktionen.
- Hilfe:Erweiterung:ParserFunktionen
- Kategorie:Parserfunktionserweiterungen