Fonctions d'analyse
Les fonctions d'analyse syntaxique (fonctions parseur), ajoutées dans MediaWiki 1.7, sont un type d'extension en relation directe avec l'analyseur syntaxique (parseur). L'expression "fonction parseur" ne doit pas être confondue avec Extension:ParserFunctions , qui est une collection de fonctions parseur simples (voir Aide:Extension:Fonctions d'analyse pour plus d'informations).
Description
Alors qu'une extension de balise est conçue pour prendre le texte non traité et retourner le code HTML résultant vers le navigateur, une fonction d'analyse syntaxique (parseur) peut « interagir » avec d'autres éléments wiki dans la page. Par exemple, le résultat d'une fonction d'analyse syntaxique peut être utilisé comme paramètre de modèle ou pour construire un lien.
La syntaxe typique pour une fonction parseur est :
{{ #functionname: param1 | param2 | param3 }}
Pour plus d'informations, voir la documentation de Parser::setFunctionHook ( $id, $callback, $flags = 0 )
. Cette documentation dit que :
- La fonction de rappel (callback) doit ressembler à :
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
- ou avec
SFH_OBJECT_ARGS
:function myParserFunction( $parser, $frame, $args ) { ... }
La première version de l'appel passe tous les arguments en tant que texte brut.
Le second passe tous les arguments dans un tableau de PPNode , sauf le premier ($args[0]
), qui est actuellement du texte bien que cela puisse changer à l'avenir.
Ceci représente le wikicode non développé.
Le paramètre $frame
peut être utilisé pour étendre ces arguments selon les besoins.
Ceci est utilisé habituellement pour le traitement conditionnel pour que le cas true
soit évalué avec une fonction d'analyse de type if-
ou switch-like
.
L'objet de trame peut également remonter l'arborescence du document pour obtenir les informations concernant l'appelant et possède des fonctions pour déterminer et gérer la profondeur des appels, la durée de validité, et indiquer si le résultat de la fonction d'analyse est volatile.
Créer une fonction parseur est légèrement plus compliqué que de créer une nouvelle balise car le nom de la fonction doit être un mot magique, un mot clé qui supporte les alias et la localisation.
Exemple simple
Ci-dessous, un exemple d'extension qui créée une fonction parseur.
L'enregistrement va respectivement dans extension.json et le code dans 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 {
// Enregistrement et rendu des fonctions de rappel ( callbacks) avec l'analyseur syntaxique
public static function onParserFirstCallInit( Parser $parser ) {
// Créer une fonction d'accroche en associant le mot magique <code>example</code> avec renderExample()
$parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
}
// Rendu du résultat de {{#example:}}.
public static function renderExample( Parser $parser, $param1 = '', $param2 = '', $param3 = '' ) {
// Les paramètres d'entrée sont du texte wiki avec des modèles étendus.
// La sortie devrait être également un wikitext.
$output = "param1 is $param1 and param2 is $param2 and param3 is $param3";
return $output;
}
}
Un autre fichier, ExampleExtension.i18n.php, dans le répertoire de votre extension (et non pas dans le dossier src/) doit contenir :
<?php
/**
* @license GPL-2.0-or-later
* @author Votre nom (YourUserName)
*/
$magicWords = [];
/** English
* @author Votre nom (YourUserName)
*/
$magicWords['en'] = [
'example' => [ 0, 'example' ],
];
Avec cette extension activée,
- {{#example: hello | hi | hey}}
produit :
- param1 vaut hello et param2 vaut hi et param3 vaut hey
LocalSettings.php
MediaWiki\MediaWikiServices::getInstance()->getContentLanguage()->mMagicExtensions['wikicodeToHtml'] = ['MAG_CUSTOM', 'custom'];
Dans LocalSettings.php
Les mots magiques, et les fonctions d'analyse qui leur sont associées, peuvent être définies entièrement dans 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];
}
Fonctions complexes
Pour les fonctions plus complexes, vous pouvez séparer les fonctions d'accroche dans un fichier _body.php ou un fichier .hooks.php et les définir en tant que fonctions statiques de classe. Ensuite, vous pouvez charger cette classe avec $wgAutoloadClasses et appeler les fonctions statiques dans les accroches; par exemple :
Mettre ceci dans votre fichier extension.json
:
"Hooks": {
"ParserFirstCallInit": "ExampleExtensionHooks::onParserFirstCallInit"
},
"AutoloadClasses": {
"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
}
- Voir: écrire un gestionnaire d'événements pour d'autres styles.
Puis mettre ceci dans votre fichier src/ExampleExtensionHooks.php
:
class ExampleExtensionHooks {
public static function onParserFirstCallInit( Parser $parser ) {
$parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
}
}
Interface Parser
Contrôler l'analyse de la sortie
Pour que le texte wiki renvoyé par la fonction d'analyse soit complètement analysé (en incluant l'expansion des modèles), mettez l'option noparse
à false
lors du retour :
return [ $output, 'noparse' => false ];
Il semblerait que la valeur par défaut de noparse
ait changé de false
à true
, tout du moins dans certaines situations, parfois aux alentours de la version 1.12.
Inversement, pour faire en sorte que le code HTML renvoyé par votre fonction parseur reste non analysé, plutôt que d'utiliser du wikicode, utilisez ceci :
return [ $output, 'noparse' => true, 'isHTML' => true ];
Nommage
Par défaut, MediaWiki ajoute un caractère dièse (signe dièse , #
) au nom de chaque fonction d'analyse.
Pour supprimer cet ajout (et obtenir une fonction d'analyse syntaxique sans préfixe #
),
incluez la constante SFH_NO_HASH dans l'argument flags pour setFunctionHook, comme décrit ci-dessous .
Lorsque l'on choisit un nom sans préfixe #, notez que la transclusion d'une page avec un nom commençant par le nom de cette fonction suivi par deux points n'est plus possible. En particulier, évitez les noms de fonction identiques à un nom d'espace de noms. Dans le cas où cette transclusion interwiki [1] est activée, évitez également les noms de fonctions identiques à un préfixe interwiki.
L'accroche setFunctionHook
Pour plus de détails sur l'interface dans l'analyseur syntaxique, consultez la documentation de setFunctionHook dans le fichier includes/Parser.php. Voici une copie (peut-être ancienne) de ces observations :
fonction setFunctionHook( $id, $callback, $flags = 0 )
Paramètres :
- string $id - L'identificateur (ID) du mot magique
- mixte $callback - La fonction de rappel (et l'objet) à utiliser
- entier $flags - Optionnel. Valeurs :
- constante SFH_NO_HASH (1) pour appeler la fonction sans le
#
. - SFH_OBJECT_ARGS (2) pour passer un objet PPFrame et un tableau d'arguments à la place d'une série d'arguments de fonction, voir [#Description|ci-dessus]].
- 0 est la valeur par défaut (pas d'option).
- constante SFH_NO_HASH (1) pour appeler la fonction sans le
Code retour : L'ancienne fonction de rappel pour ce nom, le cas échéant.
Créer une fonction, par exemple {{#sum:1|2|3}}
. La fonction de rappel doit avoir la forme :
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
Le rappel peut renvoyer le résultat de la fonction sous la forme d'une chaîne de caractères, ou un tableau avec le texte dans l'élément 0 et un certain nombre de drapeaux pour les autres éléments. Les noms des drapeaux sont spécifiés dans les clés. Les drapeaux valides sont :
Nom | Type | Valeur par défaut | Description |
---|---|---|---|
found | booléen | true
|
true si le texte renvoyé est valide et que le traitement du modèle doit s'arrêter.
|
text | ? | ? | texte à renvoyer par la fonction. Si isChildObj ou isLocalObj sont fournis, alors ceci doit être un noeud du DOM. |
noparse | booléen | true
|
true si le texte ne doit pas être pré-traité comme une arborescence DOM, par exemple si les balises HTML dangereuses ne doivent pas être supprimées, etc.
|
isHTML | booléen | ? | true si le texte renvoyé est au format HTML et doit être protégé le contre la transformation en wikicode. Mais voir la discussion
|
nowiki | booléen | habituellement false
|
true si le balisage wiki dans la valeur de retour (textuelle) doit être échappé.
|
isChildObj | booléen | ? | true si le texte est un noeud du DOM devant être développé dans une frame fille.
|
isLocalObj | booléen | ? | true si le texte est un nœud du DOM devant être développé dans la frame actuelle. La valeur par défaut dépend des autres valeurs et des résultats.
|
preprocessFlags | ? | false
|
options PPFrame facultatives à utiliser lors de l'analyse du texte renvoyé. Ceci ne s'applique que si noparse vaut false .
|
title | ? | false
|
objet Title qui a fourni le texte. |
forceRawInterwiki | booléen | ? | true si la transclusion interwiki doit être forcée en mode à plat (raw) et non pas comme rendu.
|
Fonctions d'analyse coûteuses
Certaines fonctions de l'analyseur représentent une utilisation importante des ressources du wiki et doivent être marquées comme étant coûteuses. Le nombre de fonctions d'analyse coûteuses sur une page donnée est limité par la valeur de $wgExpensiveParserFunctionLimit . Ce qui est coûteux est laissé à la fonction elle-même, mais généralement, tout ce qui est susceptible de causer un retard qui va au-delà du simple traitement des données doit être pris en compte. Cela inclut des opérations comme la lecture ou l'écriture dans les bases de données, le lancement synchrone d'un script du shell ou la manipulation de fichiers. D'autre part, toutes les fonctions ainsi identifiées ne devraient pas nécessairement être étiquetées. Semantic MediaWiki par exemple, ne marque qu'une portion de ses lectures en base de données comme coûteuses. Cela est dû au fait que sur certaines pages à forte intensité de données, on pourrait facilement dépasser les limites normales des fonctions d'analyse coûteuses. Pour ces cas, la possibilité de réduire les performances de manière perceptible alors que la fonction n'a pas été marquée comme étant coûteuse est liée au bénéfice d'avoir la fonctionnalité offerte par SMW.
Pour indiquer dans le corps d'une fonction que celle-ci est coûteuse, utiliser $result = $parser->incrementExpensiveFunctionCount();
.
Le code retour sera false
si les limites de la fonction consommatrice ont été atteintes ou dépassées.
Paramètres nommés
Les fonctions d'analyse syntaxique ne prennent pas en charge les paramètres nommés comme le font les modèles et les balises d'extensions, mais il est parfois utile de les imiter. Les utilisateurs sont souvent habitués à utiliser des barres verticales ( |
) pour séparer les arguments, il est donc aussi intéressant de pouvoir le faire dans le contexte de la fonction de l'analyseur syntaxique. Voici un exemple simple pour illustrer ceci :
function ExampleExtensionRenderParserFunction( &$parser ) {
// Supposons que l'utilisateur appelle la fonction d'analyse ainsi :
// {{#myparserfunction: foo=bar | apple=orange | banana }}
$options = extractOptions( array_slice( func_get_args(), 1 ) );
// Vous disposez alors d'un tableau qui ressemble à :
// [foo] => 'bar'
// [apple] => 'orange'
// [banana] => true
// continuez la suite de votre code...
}
/**
* Convertit un tableau de valeurs sous la forme [0] => ''name=value''
* dans un tableau associatif de réels sous forme => valeur
* S'il n'y a pas de signe = , alors la valeur assignée est true ainsi : [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;
}
Voir aussi
Généralités et guides associés :
- Développement d'extensions ou pour d'autres informations générales sur les extensions, voir Extensions et FAQ des extensions .
- Extensions de balise
- Manuel:Mots Magiques
Code :
- Manuel:Parser.php
- Manuel:Hooks/ParserFirstCallInit
- Parser function hooks - liste (incomplète) des fonctions d'analyse fournies par le noyau et les extensions
- La bibliothèque PHP Parser Hooks fournit une interface orientée objet pour les accroches déclaratives de l'analyseur syntaxique
- Manual:Extension data
Exemples :
- Extension des fonctions Parseur est une collection bien connue des fonctions d'analyse syntaxique.
- Aide:Extension:Fonctions d'analyse
- Catégorie:Extensions des fonctions de l'analyseur syntaxique