Manual:解析器函数
解析器函数(Parser function),加入于MediaWiki 1.7,是一种与解析器紧密集成的扩展。 短语“解析器函数”不应与Extension:解析器函數 混淆,后者是简单解析器函数的集合。 (请参阅Help:Extension:解析器函數 。)
描述
解析器函数的典型语法是:
{{ #functionname: param1 | param2 | param3 }}
有关更多信息,请参阅文档的Parser::setFunctionHook ( $id, $callback, $flags = 0 )
。本文档说明:
- 回調函數應具有以下形式:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
- 或者
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.
創建解析器函數比創建新標記稍微複雜一些,因為函數名稱必須是魔術字,這是一個支持別名和本地化的關鍵字。
简单例子
下面是一個創建解析器函數的擴展示例。
註冊分別進入extension.json和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 {
// 使用解析器註冊任何渲染回調
public static function onParserFirstCallInit( Parser $parser ) {
// 創建一個函數鉤子,將“示例”魔術詞與renderExample()相關聯
$parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
}
// 渲染{{#example:}}的輸出。
public static function renderExample( Parser $parser, $param1 = '', $param2 = '', $param3 = '' ) {
// 輸入參數是擴展了模板的wikitext,。
// 輸出也應該是wikitext。
$output = "param1 is $param1 and param2 is $param2 and param3 is $param3";
return $output;
}
}
擴展目錄(不在src/子目錄中)的另一個文件ExampleExtension.i18n.php應該包含:
<?php
/**
* @license GPL-2.0-or-later
* @author Your Name (YourUserName)
*/
$magicWords = [];
/** English
* @author Your Name (YourUserName)
*/
$magicWords['en'] = [
'example' => [ 0, 'example' ],
];
啟用此擴展程序後,
- {{#example: hello | hi | hey}}
生产:
- param1 is hello and param2 is hi and param3 is 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];
}
较长的函数
對於更長的函數,您可能希望將鉤子函數拆分為_body.php或.hooks.php文件,並使它們成為類的靜態函數。 然後你可以用$wgAutoloadClasses 加載類並在鉤子中調用靜態函數; 例如。:
把它放在你的extension.json
文件中:
"Hooks": {
"ParserFirstCallInit": "ExampleExtensionHooks::onParserFirstCallInit"
},
"AutoloadClasses": {
"ExampleExtensionHooks": "src/ExampleExtensionHooks.php"
}
- 請參閱:編寫事件處理程序以獲取其他樣式。
然後把它放在你的src/ExampleExtensionHooks.php
文件中:
class ExampleExtensionHooks {
public static function onParserFirstCallInit( Parser $parser ) {
$parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
}
}
解析器接口
控制輸出的解析
要使解析器函數返回的wiki文本得到完全解析(包括擴展模板),請在返回時將noparse
選項設置為false:
return [ $output, 'noparse' => false ];
至少在某些情況下,有時是1.12版本左右,似乎noparse
的默認值從false變為true。
相反,要使您的解析器函數返回仍未解析的超文本標記語言,而不是返回wiki文本,請使用以下命令:
return [ $output, 'noparse' => true, 'isHTML' => true ];
命名
默认情况下,MW 会在每个解析器函数的名称中添加一个哈希字符(数字符号,“#”)。 要抑制该添加(并获得没有“#”前缀的解析器函数),请在 setFunctionHook 的可选标志参数中包含 SFH_NO_HASH 常量,如 below 所述。
在選擇沒有哈希前綴的名稱時,請注意,不再可能刪除名稱以該函數名稱開頭後跟冒號的頁面。 特別是,避免使用等於命名空間名稱的函數名稱。 在啟用interwiki transclusion [1] 的情況下,還要避免使用等於interwiki前綴的函數名稱。
setFunctionHook掛鉤
有關解析器接口的更多詳細信息,請參閱includes/Parser.php.中setFunctionHook的文檔。 這是這些評論的副本(可能是註明日期):
function setFunctionHook( $id, $callback, $flags = 0 )
参数:
- string $id - 魔術字標識符
- mixed $callback - 要使用的回調函數(和對象)
- integer $flags - 可選,將其設置為SFH_NO_HASH常量,以調用不帶“#”的函數。
- 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
返回值:此名稱的舊回調函數(如果有)
創建一個函數,例如{{#sum:1|2|3}}
。 回調函數應具有以下形式:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
回調可以返回函數的文本結果,也可以返回帶有文本的數組 在元素0中,以及其他元素中的許多標誌。 標誌的名稱是 在鍵中指定。 有效標誌是:
Name | Type | Default | Description |
---|---|---|---|
found | Boolean | true
|
返回的文本有效,停止處理模板。 默認情況下啟用此選項。 |
text | ? | ? | The text to return from the function. If isChildObj or isLocalObj are specified, this should be a DOM node instead. |
noparse | Boolean | true
|
不應剝離不安全的HTML標籤等。 |
isHTML | Boolean | ? | 返回的文本是HTML,裝備它反對wikitext轉換 But see discussion |
nowiki | Boolean | usually false
|
應該轉義返回值中的Wiki標記 |
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.
命名參數
解析器函數不像模板和標記擴展那樣支持命名參數,但偶爾會偽造它。 用戶通常習慣使用豎線(|)來分隔參數,因此能夠在解析器函數上下文中做到這一點也很好。 以下是如何完成此操作的簡單示例:
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;
}
参见
General and related guides:
- Manual:开发扩展 , or for more general information about extensions, see Manual:扩展 and Extensions FAQ .
- Manual:标签扩展
- Manual:魔术字
Code:
- 手册:Parser.php
- Manual:Hooks/ParserFirstCallInit
- Parser function hooks - an (incomplete) list of parser functions provided by core and extensions
- Parser Hooks PHP 库,为声明性解析器钩子提供面向对象的接口
- Manual:Extension data
Examples:
- ParserFunctions擴展是一個眾所周知的解析器函數集合。
- Help:Extension:解析器函數
- 分类:解析器函数扩展