Parserfunktioner, som tilføjedes i MediaWiki version 1.7, er en type udvidelse, der er tæt knyttet til syntaks-analysen, ogsa kaldet parseren.
Udtrykket "parserfunktion" ma ikke forveksles med
Extension:ParserFunctions
, som er en samling af simple parserfunktioner.
(See
Help:Extension:ParserFunctions
for those.)
Beskrivelse
Whereas a
tag extension
is expected to take unprocessed text and return HTML to the browser, a parser function can 'interact' with other wiki elements in the page. For example, the output of a parser function could be used as a
template parameter
or in the construction of a
link
.
Den typiske syntaks for en parserfunktion er:
{{ #functionname: param1 | param2 | param3 }}
For more information, see
the documentation
for
Parser
::
setFunctionHook
(
$id
,
$callback
,
$flags
=
0
)
. This documentation states:
- The callback function should have the form:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
- Or with
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.
Oprettelse af en parserfunktion er lidt mere kompliceret end at skabe et nyt mærke, fordi funktionens navn skal være et
magisk ord
- et nøgleord, der understøtter aliaser og sprogversioner.
Simpelt eksempel
Nedenfor er et eksempel pa en udvidelse, der skaber en parserfunktion.
The registration goes into
extension.json
and the code into
src/ExampleExtensionHooks.php
respectively:
{
"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
{
// Register any render callbacks with the parser
public
static
function
onParserFirstCallInit
(
Parser
$parser
)
{
// Create a function hook associating the <code>example</code> magic word with renderExample()
$parser
->
setFunctionHook
(
'example'
,
[
self
::
class
,
'renderExample'
]
);
}
// Render the output of {{#example:}}.
public
static
function
renderExample
(
Parser
$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
;
}
}
En anden fil,
ExtensionName.i18n.php
, bør indeholde:
<?php
/**
* @license GPL-2.0-or-later
* @author Your Name (YourUserName)
*/
$magicWords
=
[];
/** English
* @author Your Name (YourUserName)
*/
$magicWords
[
'en'
]
=
[
'example'
=>
[
0
,
'example'
],
];
Med denne udvidelse aktiveret
- {{#example: hello | hi | hey}}
producerer
- param1 is hello and param2 is hi and param3 is hey
Denne magicWords tabel er ikke valgfri. Hvis den udelades, vil parserfunktionen simpelthen ikke virke og {{#example: hello | hi}} vil blive gengivet som om udvidelsen ikke er blevet installeret.
If only the language-specific array is initialized and not the magicWords array itself, this can cause localization errors as translations from other extensions leak into yours.
You can associate magic words inline in PHP rather than through a i18n file.
This is useful when defining hooks in
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
];
}
Længere funktioner
For længere funktioner vil du maske adskille krog-funktionerne til en _body.php eller .hooks.php fil og lave dem til en klasses statiske funktioner. Sa kan du hente klassen med
$wgAutoloadClasses
og kalde de statiske funktioner pa krogene:
Sæt dette ind i din
extension.json
fil:
"Hooks"
:
{
"ParserFirstCallInit"
:
"ExampleExtensionHooks::onParserFirstCallInit"
},
"AutoloadClasses"
:
{
"ExampleExtensionHooks"
:
"src/ExampleExtensionHooks.php"
}
Sa sæt dette i din
MyExtension.hooks.php
fil:
class
ExampleExtensionHooks
{
public
static
function
onParserFirstCallInit
(
Parser
$parser
)
{
$parser
->
setFunctionHook
(
'example'
,
[
self
::
class
,
'renderExample'
]
);
}
}
Parser brugergrænseflade
Styring af systemanalyse-resultat
For at fa wikiteksten, der returneres af din parserfunktion, til være fuldt systemanalyseret (med udvidelse af skabeloner), skal du indstille
noparse
til false ved returneringen:
return
[
$output
,
'noparse'
=>
false
];
Det ser ud til at standardværdien for
noparse
er ændret fra false til true, i hvert fald i nogle situationer, omkring version 1.12.
Omvendt, for at fa din parserfunktion til at returnere ikke-gennemgaet HTML i stedet for wikitekst, brug dette:
return
[
$output
,
'noparse'
=>
true
,
'isHTML'
=>
true
];
Navngivning
Som standard tilføjer MW en hash karakter (nummertegn, "#") til navnet af hver parserfunktion. For at undertrykke denne tilføjelse (og opna en parser funktion uden "#" præfiks), indsæt
SFH_NO_HASH
konstant i den valgfri flag-argument til setFunctionHook, som beskrevet
nedenfor
.
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
.
Nar du vælger et navn uden et hash præfiks, vær opmærksom pa at indlejring af en side med et navn, der starter med dette funktionsnavn efterfulgt af et kolon, er ikke længere muligt. Undga især funktionsnavne svarende til et navnerums-navn. I tilfælde af at interwiki indlejring
[1]
er aktiveret, undga da ogsa funktionsnavne svarende til et interwiki præfiks.
setFunctionHook krogen
For flere oplysninger om grænsefladen ind i parseren, se dokumentationen for setFunctionHook i includes/Parser.php.
Her er en (muligvis dateret) kopi af disse bemærkninger:
function setFunctionHook( $id, $callback, $flags = 0 )
Parametre:
- string $id - det magiske ord ID
- mixed $callback - tilbagekalds-funktionen (og objektet) at bruge
- integer $flags - valgfri, sættes til
SFH_NO_HASH
konstanten, for at kalde funktionen uden "#".
- 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).
Returværdi:
navnets gamle tilbagekalds-funktion, hvis der er nogen
Opret en funktion, for eks.
{{#sum:1|2|3}}
. Tilbagekalds-funktionen bør have formen:
function
myParserFunction
(
$parser
,
$arg1
,
$arg2
,
$arg3
)
{
...
}
Tilbagekaldet kan enten returnere tekstresultatet af funktionen, eller en tabel med teksten i element 0, og et antal flag i de andre elementer. Navnene pa flagene er specificeret i nøglerne. Gyldige flag er:
Name
|
Type
|
Default
|
Description
|
found
|
Boolean
|
true
|
Den returnerede tekst er gyldig, stop behandlingen af skabelonen. Dette er som standard aktiveret.
|
text
|
?
|
?
|
The text to return from the function.
If isChildObj or isLocalObj are specified, this should be a DOM node instead.
|
noparse
|
Boolean
|
true
|
Usikre HTML-mærker bør ikke gennemgas osv.
|
isHTML
|
Boolean
|
?
|
Den returnerede tekst er HTML og skal værnes mod wikitekst forandring
But see discussion
|
nowiki
|
Boolean
|
usually
false
|
Wiki-opmærkning i resultatet skal udelades
|
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.
Navngivne parametre
Parserfunktioner understøtter ikke navngivne parametre pa samme made som skabeloner og mærke-udvidelser, men det er til tider nyttigt at lade som om. Brugerne er ofte vant til at bruge lodrette streger ( | ) til at adskille argumenter, sa det er rart ogsa at kunne gøre det i parserfunktionens kontekst. Her er et simpelt eksempel pa hvordan det gøres.
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
;
}
Se ogsa
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| ]]