Handboek:Parserfuncties

From mediawiki.org
This page is a translated version of the page Manual:Parser functions and the translation is 87% complete.
MediaWiki extensions

Een parserfunctie, toegevoegd in MediaWiki 1.7, is een soort extensie die nauw integreert met de parser. De uitdrukking "parserfunctie" moet niet worden verward met Extension:ParserFunctions , wat een verzameling eenvoudige parserfuncties is. (Zie voor die Help extension ParserFunctions .)

Beschrijving

Terwijl van een tag extensie wordt verwacht dat die onbewerkte tekst neemt en HTML terugstuurt naar de browser, kan een parserfunctie 'samenwerken' met andere wiki-elementen op de pagina. De uitvoer van een parserfunctie kan bijvoorbeeld worden gebruikt als een sjabloon-parameter of bij de constructie van een link.

De typische syntaxis voor een parserfunctie is:

{{ #functionname: param1 | param2 | param3 }}

Zie the documentation voor meer informatie voor Parser::setFunctionHook ( $id, $callback, $flags = 0 ). In deze documentatie staat:

De functie callback moet de vorm hebben:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
Of met SFH_OBJECT_ARGS:
function myParserFunction( $parser, $frame, $args ) { ... }

De eerste variant van de aanroep geeft alle argumenten door als gewone tekst. De tweede geeft alle argumenten door als een array van PPNode s, behalve de eerste ($args[0]), die nu tekst is, hoewel dit in de toekomst kan veranderen. Deze vertegenwoordigen de niet uitgebreide wikitext. De parameter $frame kan worden gebruikt om deze argumenten naar behoefte te vergroten. Dit wordt vaak gebruikt voor voorwaardelijke verwerking zodat alleen het geval "true" wordt geëvalueerd met een if- of switch-achtige parserfunctie. Het frame-object kan ook de documentboom doornemen om informatie over de caller te krijgen en heeft functies om de call depth, time-to-live, en of het resultaat van de parserfunctie vluchtig is te bepalen en te beheren.

Het maken van een parserfunctie is iets ingewikkelder dan het maken van een nieuwe tag, omdat de functienaam een magisch woord moet zijn, een trefwoord dat aliassen en lokalisatie ondersteunt.

Eenvoudig voorbeeld

Hieronder is een voorbeeld van een extensie die een parserfunctie creëert.

De registratie gaat respectievelijk in extension.json en de code in src/ExampleExtensionHooks.php:

{
	"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
}
<?php
class ExampleExtensionHooks {
   // Registreer alle callbacks met de parser
   public static function onParserFirstCallInit( Parser $parser ) {

      // Maak een functie hook die het magische woord "example" associeert met renderExample()
      $parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
   }

   // De uitvoer van {{#example:}} opbouwen.
   public static function renderExample( Parser $parser, $param1 = '', $param2 = '', $param3 = '' ) {

      // De invoerparameters zijn wikitext met uitgebreide sjablonen.
      // De uitvoer moet ook wikitext zijn.
      $output = "param1 is $param1 and param2 is $param2 and param3 is $param3";

      return $output;
   }
}

Een ander bestand, ExampleExtension.i18n.php, in uw map extension (Niet in de submap src/) moet bevatten:

<?php
/**
 * @license GPL-2.0-or-later
 * @author Uw naam (YourUserName)
 */

$magicWords = [];

/** English
 * @author Uw naam (YourUserName)
 */
$magicWords['en'] = [
   'example' => [ 0, 'example' ],
];

Met deze extension ingeschakeld,

  • {{#example: hello | hi | hey}}

resultaat:

  • param1 is hello en param2 is hi en param3 is hey
Dit array magicWords is niet optioneel. Als het wordt weggelaten, zal de parserfunctie gewoon niet werken; Het {{#example: hello | hi}} wordt weergegeven alsof de extensie niet is geïnstalleerd. Als alleen het taalspecifieke array wordt geïnitialiseerd en niet het array magicWords zelf, kan dit lokalisatiefouten veroorzaken omdat vertalingen van andere extensies in de uwe lekken. U kunt magische woorden inline in PHP associëren, liever dan via een i18n bestand. Dit is handig bij het definiëren van hooks in LocalSettings.php
MediaWiki\MediaWikiServices::getInstance()->getContentLanguage()->mMagicExtensions['wikicodeToHtml'] = ['MAG_CUSTOM', 'custom'];

Binnen LocalSettings.php

Magische woorden en hun parserfuncties voor afhandeling kunnen volledig worden gedefinieerd 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];
}

Langere functies

Voor langere functies, kunt u de hook functies opdelen naar een _body.php of .hooks.php bestand en ze statische functies van een class maken. Dan kunt u de class laden met $wgAutoloadClasses en de statische functies in de hooks aanroepen; bijvoorbeeld:

Zet dit in uw extension.json bestand:

"Hooks": {
	"ParserFirstCallInit": "ExampleExtensionHooks::onParserFirstCallInit"
},
"AutoloadClasses": {
	"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
}

Zet dan dit in uw src/ExampleExtensionHooks.php bestand:

class ExampleExtensionHooks {
      public static function onParserFirstCallInit( Parser $parser ) {
           $parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
      }
}

Parser interface

Het parsen van de uitvoer controleren

Om de wikitext die door uw parserfunctie wordt teruggestuurd volledig te laten analyseren (inclusief extensie van sjablonen), stel de optie noparse op false bij het retourneren:

return [ $output, 'noparse' => false ];

Het lijkt erop dat de standaardwaarde voor noparse veranderde van false naar true, in sommige situaties, ergens rond versie 1.12.

Omgekeerd, om uw parserfunctie HTML terug te laten geven die niet is verwerkt, in plaats van wikitext, gebruik dit:

return [ $output, 'noparse' => true, 'isHTML' => true ];

Naamgeving

Standaard voegt MW een hash-teken (nummerteken, "#") toe aan de naam van elke parserfunctie. Als u die toevoeging wilt onderdrukken (en een parserfunctie zonder voorvoegsel '#' wilt verkrijgen), neemt u de constante SFH_NO_HASH op in het argument optionele flags voor setFunctionHook, zoals hieronder beschreven.

Bij het kiezen van een naam zonder een hashprefix, is het niet langer mogelijk om een pagina met een naam die begint met die functienaam gevolgd door een dubbele punt te transcluderen. Vermijd met name functienamen die gelijk zijn aan een namespace. In het geval dat interwiki transclusion [1] is ingeschakeld, vermijdt u ook functienamen die gelijk zijn aan een interwiki prefix.

De hook setFunctionHook

Voor meer informatie over de interface in de parser, zie de documentatie over setFunctionHook in includes/Parser.php. Hier is een (mogelijk gedateerde) kopie van die opmerkingen:

functie setFunctionHook( $id, $callback, $flags = 0 )

Parameters:

  • string $id - Het magische woord ID
  • mixed $callback - De te gebruiken functie met object (na de aanroep, callback)
  • integer $flags - Optioneel. Waarden:
  • SFH_NO_HASH (1) constante, als de functie wordt aangeroepen zonder de "#".
  • SFH_OBJECT_ARGS (2) als u een PPFrame-object en array van argumenten doorgeeft in plaats van een reeks functieargumenten, zie daarvoor hierboven.
  • De standaard is 0 (geen flags).

Returnwaarde: De eventuele oude callback functie voor deze naam

Een functie maken, bijvoorbeeld {{#sum:1|2|3}}. De callback-functie moet de volgende vorm hebben:

function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }

Het resultaat kan het tekstresultaat van de functie zijn of een matrix met de tekst in element 0 en een aantal flags in de andere elementen. De namen van de flags staan in de keys. Geldige flags zijn:

Naam Type Standaard Beschrijving
found Boolean true true als de teruggegeven tekst geldig is en het verwerken van het sjabloon moet worden gestopt.
text ? ? De tekst om terug te geven door de functie. Als isChildObj of isLocalObj worden gespecificeerd, moet dit in plaats daarvan een DOM-node zijn.
noparse Boolean true true als tekst niet vooraf moet worden verwerkt naar een DOM-tree, bijvoorbeeld als onveilige HTML-tags niet moeten worden verwijderd, enz.
isHTML Boolean ? true als de teruggegeven tekst HTML is en moet worden beschermd tegen wikitext-transformatie. Maar bekijk de discussie
nowiki Boolean meestal false true als de wiki-opmaak in de returnwaarde (tekst) moet worden beschermd (escaped).
isChildObj Boolean ? true als de tekst een DOM-node is die uitbreiding nodig heeft in een subframe.
isLocalObj Boolean ? true als de tekst een DOM-node is die uitbreiding nodig heeft in het huidige frame. De standaardwaarde is afhankelijk van andere waarden en resultaten.
preprocessFlags ? false Optionele flags PPFrame om te gebruiken bij het analyseren van de ontvangen tekst. Dit geldt alleen als noparse false is.
title ? false Het object Title waar de tekst vandaan kwam.
forceRawInterwiki Boolean ? true als de transclusion tussen wiki's in de raw-modus moet worden uitgevoerd en er geen opbouw nodig is.

Dure parserfuncties

Sommige parserfuncties zorgen voor een significant gebruik van de middelen van een wiki en moeten als "duur" worden gezien. Het aantal dure parserfuncties op een bepaalde pagina wordt beperkt door de instelling $wgExpensiveParserFunctionLimit . Wat als duur telt, wordt overgelaten aan de functie zelf, maar meestal moet alles worden overwogen dat waarschijnlijk een vertraging veroorzaakt die verder gaat dan een eenvoudige verwerking van gegevens. Dit omvat zaken als een database lezen / schrijven, een shellscript synchroon lanceren of bestandsmanipulatie. Aan de andere kant moeten niet al zulke functies noodzakelijkerwijs worden getagged. Semantische MediaWiki, bijvoorbeeld, geeft slechts een percentage van de database leesopdrachten als duur aan. Dit komt doordat op bepaalde data-intensive pagina's het gemakkelijk de normale limiet voor dure parserfuncties overschrijdt. In gevallen als deze is het potentieel voor een merkbaar langzamere prestaties die niet als duur worden gemarkeerd, een compromis met het hebben van de functionaliteit die Semantische MediaWiki biedt.

Om uw parserfunctie te markeren als duur, vanuit de code van de functie, gebruik $result = $parser->incrementExpensiveFunctionCount();. De returnwaarde zal false zijn als de limiet voor dure functies is bereikt of is overschreden.

Parameters met een naam

Parser functions do not support named parameters the way templates and tag extensions do, but it is occasionally useful to fake it. Users are often accustomed to using vertical bars ( | ) to separate arguments, so it's nice to be able to do that in the parser function context, too. Here's a simple example of how to accomplish this:

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;
}

See also

General and related guides:

Code:

  • The Parser Hooks PHP library, which provides an object orientated interface for declarative parser hooks

Examples:

Category:Parser function extensions[[::Category:Parser function extensions| ]]