Open main menu

Manual:パーサー関数

This page is a translated version of the page Manual:Parser functions and the translation is 90% complete.
Outdated translations are marked like this.
Other languages:
Bahasa Indonesia • ‎Deutsch • ‎English • ‎Tiếng Việt • ‎dansk • ‎español • ‎français • ‎polski • ‎português do Brasil • ‎русский • ‎ไทย • ‎中文 • ‎日本語 • ‎한국어
開発 タグ拡張機能 パーサー関数 フック 特別ページ 外装 マジックワード API Content models
MediaWiki extensions

パーサー関数とはMediaWiki 1.7以降追加された一種の拡張機能で、パーサーと緊密に連動します。「パーサー関数」という名称は誤解を招きがちですが、単純な関数の集合体Extension:ParserFunctions のことではありません (それらの説明はHelp:Extension:ParserFunctions を参照してください)。

説明

タグ拡張機能は未処理のテキストを取り込んでブラウザに HTML を返すのに対して、パーサー関数はページ上のその他の要素と「相互作用」ができます。たとえばパーサ関数の出力はテンプレート変数として利用したりリンクの作成に使うことができます。

パーサー関数の典型的な構文は以下の通りです:

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

詳細について、Parser::setFunctionHook ( $id, $callback, $flags = 0 )の説明はthe documentationを参照してください。その説明文書は次の内容を扱います。

コールバック関数の構文は次のとおりです。
function myParserFunction( &$parser, $arg1, $arg2, $arg3 ) { ... }
あるいは SFH_OBJECT_ARGS:
function myParserFunction( $parser, $frame, $args ) { ... }"

パーサー関数の作成は、タグフックを作成する場合よりも多少込み入っています。これは、関数名がマジックワードでなければならないためです; マジックワードは、別名および多言語対応をサポートする一種のキーワードです。

単純な例

パーサー関数を生成する拡張機能の例を以下に示します。

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 ) {

      // 関数フックを作成し、"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
magicWords引数は必須でありオプションではありません。省略するとパーサー関数はまったく機能しません。{{#example: hello | hi}} は拡張機能がインストールされていない状態として表示されます。

より長い関数

より複雑な関数を記述する場合には、フック関数を _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() を使用してキャッシュを無効にできます。 This has a significant negative impact on performance, so only use when necessary.

パーサー インターフェイス

出力の構文解析の制御

作成したパーサー関数が返すウィキテキストが完全に構文解析されるようにする (テンプレートの展開を含む) には、戻り値の noparse オプションに false を設定します:

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

noparse の既定値は、ある時点、バージョン 1.12 付近のどこかで、false から true に変更されたようです。

逆に、作成したパーサー関数が、ウィキテキストを返すのではなく、構文解析されないままの HTML を返すようにするには、以下のように指定します:

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

しかし、

This is {{#example:hello | hi | hey }} a test.

の記述は、以下のような出力を生成します:

This is

たとえば例文中のparam1 は hello、param2 は hi、param3 は hey です。

これは、パーサー関数の HTML 出力に、ハードコードされた "\n\n" 文字列が前置されることが原因です。この現象を回避するには、HTML コードが周りのテキストに対してインラインでレンダリングされるようにするため、以下のように記述します:

return $parser->insertStripItem( $output, $parser->mStripState );

命名

MW は既定でそれぞれのパーサー関数名の先頭にハッシュ記号 (「#」) を追加します。 追加させない (パーサー関数名に接頭辞「#」を付けない) ためには、以下で説明しているように、SFH_NO_HASH定数をオプションのflags引数のsetFunctionHookに挿入します。

もしハッシュ記号を接頭辞に使わない名称を選ぶ場合は、その関数名の後ろにコロンを付けて作ったページ名を参照呼出しできないことにご留意ください。特に、関数名は名前空間名と同名にしてはいけません。ウィキ間参照読み込みの[1]を有効にした場合には、関数名をウィキ間接頭辞と同名にしてはいけません。

setFunctionHook フック

パーサーに関連するインターフェースの詳細は、includes/Parser.phpに同梱した説明文書 setFunctionHook を参照してください。 以下はこれらのコメントを転写したものです (古い可能性あり) 。

function setFunctionHook( $id, $callback, $flags = 0 ) パラメーター:

  • string $id - マジックワード ID
  • mixed $callback - 使用するコールバック関数 (とオブジェクト)
  • integer $flags - (省略可能) 関数を「#」なしで呼び出すようにするには、SFH_NO_HASH 定数を設定します。

戻り値: この名前の元のコールバック関数 (ある場合)

たとえば{{#sum:1|2|3}}など関数の作成。コールバック関数の構文の書き方を示します。

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

コールバックの戻り値は関数が出力した文字列もしくはまたはテキストを含む配列要素0と、他の要素のフラグいくつかを示します。フラグの名前はキーで指定します。 有効なフラグは以下のとおりです。

found 
戻り値のテキストは有効で、テンプレートの処理を停止。これは既定で有効です。
nowiki 
戻り値に対するウィキマークアップは回避されるべき
noparse 
暗線ではない HTML タグは除去しないetc.
noargs 
Don't replace triple-brace arguments in the return value
isHTML 
戻り値の文字列は HTMLで、ウィキテキスト変換から保護する必要がある

名前付きパラメーター

パーサー関数はテンプレートもしくはタグ拡張機能と異なり、名前付きパラメーターをサポートしないものの、ときにはそれを回避する役に立ちます。利用者は引数を分けるために縦棒 ( | ) を使い慣れているため、パーサー関数のコンテキストでも同様の記述ができると便利です。これを実現する方法の簡単な例を示します。

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

関連項目