Руководство:Функции парсера
Функции парсера, добавленные в MediaWiki 1.7, - тип расширения, которое близко интегрируется с парсером. Фразу "функции парсера" не следует путать с $ext-parser, которое является коллекцияей простых парсинговых функций. (см. $hlp-parser) Фразу "функция парсера" не следует путать с Расширение:ParserFunctions , которая представляет собой набор простых функций парсера. (Смотрите Справка:Расширение:Функции Парсера для этого.)
Описание
В то время как теги расширений обрабатывают необработанный текст и возвращают HTML в браузер, функции парсера могут 'взаимодействовать' с другими вики-элементами на странице. Например, вывод функций парсера может использоваться как шаблонный параметр или в конструкторе ссылок.
Типичный синтаксис парсера функции:
{{ #functionname: param1 | param2 | param3 }}
Для получения дополнительной информации см. Документацию по Parser::setFunctionHook ( $id, $callback, $flags = 0 )
. В этой документации указано:
- Callback-функция должна иметь вид:
function myParserFunction( &$parser, $arg1, $arg2, $arg3 ) { ... }
- Или с
SFH_OBJECT_ARGS
:function myParserFunction( $parser, $frame, $args ) { ... }
"
Создание функции синтаксического анализатора немного сложнее, чем создание нового тега, поскольку имя функции должно быть magic word, ключевым словом, поддерживающим псевдонимы и локализацию.
Простой пример
Ниже приведен пример расширения, которое создает функция парсера.
Запись переходит в 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 ) {
// Создайте функциональный крючок, связывающий волшебное слово "example" с renderExample()
$parser->setFunctionHook( 'example', [ self::class, 'renderExample' ] );
}
// Визуализируйте выходные данные {{#example:}}.
public static function renderExample( Parser $parser, $param1 = '', $param2 = '', $param3 = '' ) {
// Входные параметры - викитекст с развернутыми шаблонами.
// Вывод тоже должен быть с викитекстом.
$output = "param1 is $param1 and param2 is $param2 and param3 is $param3";
return $output;
}
}
Другой файл, 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'];
Стандартные функции
Для больше функций, может потребоваться разделение функций-ловушек для a_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' ] );
}
}
Кэширование
Как и в случае расширения тега, $parser->disableCache() Может использоваться для отключения кэша для динамического расширения. Это оказывает значительное негативное влияние на производительность, поэтому используйте его только в случае необходимости.
Интерфейс парсера
Контролирование вывода парсера
Чтобы викитекст, возвращаемые функцией парсер быть полностью разбираемый (в том числе расширение шаблонов), установите параметр noparse
, false при возвращении:
return [ $output, 'noparse' => false ];
It seems the default value for noparse
changed from false to true, at least in some situations, sometime around version 1.12.
И наоборот, чтобы ваш парсер функция возвращает HTML, который остается непроанализированным, а не обратно викитекст, используйте это:
return [ $output, 'noparse' => true, 'isHTML' => true ];
Однако, This is {{#example:hello | hi | hey }} a test. будут выпускать что-то вроде этого:
This is
param1-Привет и param2-hi и param3-эй, это тест.
Это происходит из-за жесткого кода "\n\n", предваряющая вывод HTML парсера функций. Чтобы избежать этого и убедиться, что HTML-код отображается встроенный в окружающий текст, вы можете использовать это:
return $parser->insertStripItem( $output, $parser->mStripState );
Именование
По умолчанию, MW добавляет хэш-символа (знака, "#") перед названием каждой функции парсера. Чтобы подавить это дополнение (и получить синтаксический анализатор функционирует без "#" префикс), включать "SFH_NO_HASH" константа в необязательные флаги аргумент setFunctionHook, как описано ниже.
При выборе имени без хэш-префикса обратите внимание, что трансклюзия страницы с именем, начинающимся с этого имени функции, за которым следует двоеточие, более невозможна. В частности, избегайте имен функций, равных имени пространства имен. В том случае, если interwiki transclusion [1] включен, также избегайте имен функций, равных префиксу interwiki.
The setFunctionHook hook
Дополнительные сведения об интерфейсе синтаксического анализатора смотрите в документации по setFunctionHook в разделе includes/Parser.РНР. Вот (возможно, датированная) копия этих комментариев:
function setFunctionHook( $id, $callback, $flags = 0 ) Параметры:
- string $id - The magic word ID
- mixed $callback - The callback function (and object) to use
- integer $flags - Optional, set it to the SFH_NO_HASH constant to call the function without "#".
Return value: The old callback function for this name, if any
Create a function, e.g., {{#sum:1|2|3}}
. The callback function should have the form:
function myParserFunction( $parser, $arg1, $arg2, $arg3 ) { ... }
The callback may either return the text result of the function, or an array with the text in element 0, and a number of flags in the other elements. The names of the flags are specified in the keys. Valid flags are:
- found
- The text returned is valid, stop processing the template. This is on by default.
- nowiki
- Wiki markup in the return value should be escaped
- noparse
- Unsafe HTML tags should not be stripped, etc.
- noargs
- Don't replace triple-brace arguments in the return value
- isHTML
- The returned text is HTML, armour it against wikitext transformation
Параметры
Функции синтаксического анализатора не поддерживают именованные параметры, как это делают шаблоны и расширения тегов, но иногда полезно подделать их. Пользователи часто привыкли использовать вертикальные полосы ( | ) для разделения аргументов, поэтому приятно иметь возможность делать это и в контексте функции синтаксического анализатора. Вот простой пример того, как это сделать:
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;
}
См. также
- Manual:Hooks/ParserFirstCallInit
- Manual:Расширения
- Руководство:Теги расширений
- Руководство:Волшебные слова
- Manual:Parser.php
- Extensions FAQ
- Справка:Расширение:Функции Парсера
- Расширение ParserFunctions - хорошо известный сборник функций парсера.
- Parser function hooks , an (incomplete) list of parser functions provided by core and extensions.
- Библиотека PHP Parser Hooks, которая предоставляет объектно-ориентированный интерфейс для декларативных крючков парсера