Manual:Tag extensions/ja

それぞれのプロジェクトではシンプルな文字列の処理、本格的な情報の取得といった付加的な機能を持つ組み込みのwikiマークアップを拡張することは便利であることに気付きます. タグエクステンションは新しいカスタムタグを作成することを可能にします. 例えば、シンプルな新しい寄付フォームをページに挿入する&lt;donation /&gt;タグを導入するタグエクステンションを使用しようすることを考えてみます. Parser FunctionsとHooksを伴うエクステンションはMediaWikiの機能を変更もしくは強化するためにもっとも効果的な方法です. 他のMediaWikiによって作成されたエクステンションを見るためにはExtension Matrixをご覧下さい. エクステンションを作成する前に誰かが既に作成していないかどうか常にマトリックスを調査すべきです.

シンプルなタグエクステンションはコールバック(callback)関数で構成されます. コールバック関数はパーサにフック(hook)され、パーサが動作するときに、実際のHTMLをレンダーするために対応してコールバック関数を呼び出すことで特定のタグのすべてのインスタンスを見つけ置き換えます.

例
この例では、&lt;sample&gt;タグのためのコールバック関数を登録します. ユーザがこのタグを次のようにページを追加する場合です:

...input...

パーサはefSampleRenderを呼び出し、3つに引数に渡します:


 * $input : &lt;sample&gt;と&lt;/sample&gt;タグの間、もしくはnull、タグが閉じている場合では、すなわち&lt;sample /&gt;
 * $args : タグの引数で、HTMLタグ属性のようなものです; 属性名でインデックスされた連想配列です
 * $parser : 親パーサ; もっと高度なエクステンションが文脈上のタイトルを取得したり、wikiテキストを解析したり、リンク関連や依存性を登録したりするためにこれを使用します.

属性
他の例を見てみましょう:

この例は値と共にタグに渡された属性をダンプします. 新しいカスタムタグの柔軟な仕様を可能にすることはとても明確です. 例えば、&lt;emailform to="User" email="user@foo.com" /&gt;のようなものを使用して、ユーザがユーザページにコンタクトフォームを差し込むを可能にするタグエクステンションを定義するとします.

MediaWikiで利用可能なタグエクステンションの過剰な選択肢があり、このサイトにリストされているものもあり; 他のものはウェブ検索を通して見つけることが出来ます.

変換
一つのエクステンションを単独のファイルで構成できる一方で、それぞれのエクステンションのために個別のextensionsディレクトリの中に サブディレクトリを作成してその中に3つのファイルを設置することをお勧めします:


 * 小さなセットアップファイル、
 * 国際化ファイル、
 * コード本体を含むファイル、

配列に要素を追加するセットアップファイルで、どのファイルが読み込まれるのかを指定します:

$wgAutoloadClasses[extension_name] = dirname(__FILE__). '/extension_name.body.php';

エクステンションを公開する

 * 1) Extension:という名前の新しいページを作成します. そのページではどのようにインストールするのか、それを使っている様子のスクリーンショットなどの情報を掲載します. Template:Extensionと呼ばれるこの情報を保持する便利なテンプレートが作成されています. 詳細についてはテンプレートページをご覧下さい. ページのボディにできるだけ多くの情報を追加し、会話ページに書き込まれるユーザの質問への回答を定期的に行うことがよいことです. また、Category:Extensionsカテゴリにページが所属することを確認して下さい. ノート: meta.wikimedia.org上にエクステンションのページがありましたら管理者によって完全な履歴と一緒に移転されます - それまでの間は、metaで編集を続けることが出来ます
 * 2) エクステンションコードの範囲内で新しくManual:Hooksを作成するエクステンションはそれらをextension hook registry上に登録します. 新しく特別ページを新しく作成するエクステンションはextension special page registry上で同じことをします.
 * 3) mediawiki-lメーリングリストに通知する.

セキュリティ関係
上記の例では値を返す前にhtmlspecialchars</tt>を使用して入力をエスケープしていたことにお気づきになられたと思います. XSS脆弱性を避けるためにクライアントにechoして返す前にこの方法ですべてのユーザの入力を取り扱うための重要な方法です.

タイミングとエクステンション
エクステンションのためにコードを変更する場合、理論的には、エクステンションを使用するすべてのページが即座に新しいコードの結果に反映します. 技術的に言えば、エクステンションを含むページが表示されるたびに実行されます.

実際には、MediaWikiとブラウザ、もしくはプロクシ、ファイヤーウォールによるページキャッシュのおかげで、これはあまり当てはまりません.

MediaWikiのパーサキャッシュを回避して、生成されたページの新しいバージョンを保証するためには、編集をクリックしてブラウザのアドレスバーにあるURLの"action=edit"を"action=purge"に置き換えて新しいURLを入力します. ページとそれを参照するすべてのテンプレートはすべてのキャッシュデータを無視して再生成されます. パージアクションはメインページ自身が修正されていないが、表示される方法が変更された場合(エクステンションが修正され、もしくは参照されたテンプレートが修正される場合)に必要になります.

ページの新しいコピーを取得するために十分ではない場合、通常は上記のURLの末端に'&rand=somerandomtext'を追加することで中間状態のキャッシュを回避することが出来ます. 'somerandomtext'は毎回異なることを確認して下さい.

エクステンションを使用してキャッシングを無効にする方法は？
MediaWiki 1.5以降では、パーサは3番目のパラメータとしてエクステンションに渡されます. このパーサはキャッシュを無効にするために使用されます:

サイト上でのすべてのサーバサイドキャッシングを無効にするために、次のコードをLocalSettings.phpに追加して下さい:

特別ページ
キャッシュを解析しない出力を表示する時に、例えば特別ページ上などで

$text</tt>は解析されるwikitextです.

パーサフック
パーサフック関数はパーサオブジェクトに参照を渡され、これをwikitextを解析するために使用します.

Parser::recursiveTagParse</tt>はバージョン1.8以降で導入されました. 利点は簡潔で(一つの引数を取得し文字列を返します)$text</tt>にエクステンションタグを解析することです. エクステンションタグを入れ子にすることが出来ます. これらの利点を持たないアプローチは次の通りになります:

Parser::parseへの4番目と5番目のパラメータは$lineStart</tt>と$clearState</tt>です; これはパーサがどのように振る舞うのか指図します. $lineStart</tt>がtrueの場合、wikitextは新しい行として取り扱われます(ブロック、もしくはリスト表示などを取り扱うときに使用します). $clearState</tt>がtrueのとき、パーサが内部状態情報をクリアします; 多くの場合falseに設定されています.

上記の例ではParser::parse</tt>は生のHTMLではなくParserOutputオブジェクトを返します. 多くの場合動作しません(実行の順序、ネスティング、もしくは他のフックの混同)、パーサオブジェクトのクローンコピーを使用して下さい:

エクステンションとテンプレート
テンプレートパラメータはエクステンションタグ内部で使用される場合(例えば、 "はエクステンションに直接渡され、テンプレートが呼ばれたときに指定された正しい値に変換されません. パーサにあるテンプレートの前にエクステンションが解析されるからです. もっと詳細な情報と利用可能なパッチについてはbug 2257をご覧下さい.

この問題の次善策はテンプレート変数を拡張するいパーサ関数を作成しエクステンションコードを作成することです. テンプレートパラメータで を呼び出すためには、次のような新しいパーサ関数を作成します:

次のようなページ上で関数を呼び出します:

バージョン1.5以降
MediaWiki 1.5以降では、XMLスタイルのパラメータ(タグ属性)がサポートされています. パラメータは2番目のパラメータとしてフック機能に連想配列として渡されます. 文字列の値は既にデコードされたHTML文字エンティティを持つので、それらをHTMLに戻す場合、HTMLインジェクションのリスクを避けるために、 を使用することを忘れないで下さい.

バージョン1.5以前
MediaWiki 1.5はパラメータとエクステンションタグの間にパラメータを渡さなければなりません. すなわち、オプションのために特別な構文と、それらのためのフック入力テキストを分析しなければなりません. 可能な構文の一つは次の通りです:

@option1=foo @option2=bar

...content to be processed by the extension....

エクステンション機能に置いて、通常の処理を実行する前に@option1=foo</tt>のような行を探します. 他の構文を選択することももちろん自由です.

エクステンションのHTML出力の修正を避ける方法は？
パーサフックエクステンションを想定する現在のエクステンションコードはインラインの素材を産みだし、それらはステージをレンダリングする最後のブロックレベルで挿入されます(8997をご覧下さい).

これに取りかかる方法は実際の結果の代わりにマーカーを出力するエクステンションのパーサフック関数を作成し、そのマーカーをParserAfterTidyフックのために登楼されたハンドラ関数の実際の結果で置き換えることです.

代替的には、マーカーの出力の代わりに、武装されたフォーム(例えば、Base64でエンコードされたもの)に結果を出力することと、ParserAfterTidyハンドラでそれを武装解除(デコード)することも可能です.

Special:Version上でエクステンションが現れるようにするには？
エクステンションをMediaWikiのSpecial:Versionページで表示するためには、PHPコードの範囲内でエクステンションクレジットを割り当てなければなりません.

これをするために、フック行もしくは関数の定義の前に$wgExtensionCredits変数を最初の実行可能な行のコードとして追加します

エクステンションクレジットの例は次の通りです:

'validextensionclass'を次の一つで置き換えて下さい:
 * 'specialpage' -- MediaWikiの特別ページへの追加するために確保されます;
 * 'parserhook' -- エクステンションが修正され、補完、もしくはMediaWikiでパーサ関数に置き換える場合に使用されます;
 * 'variable' -- MediaWikiに複数の機能を追加するエクステンションです;
 * 'other' -- すべての他のエクステンションです.

関連項目

 * Manual:Extensions/ja
 * Extensions FAQ/ja
 * Manual:Extensions/ja
 * Category:Extensions
 * Extension Matrix
 * Manual:$wgExtensionFunctions
 * Comparison of parser function and XML-style parser extension - refers to DynamicPageList2, but is of general interest
 * Project:Extension requests