Manual:Tag extensions/ja

個別のプロジェクトにおいてシンプルな文字列の処理、本格的な情報の取得といった付加的な機能を持つ組み込みのwikiマークアップを拡張することが便利だと思うことはよくあります. タグ拡張機能によって新しいカスタムタグを作ることができます. 例えば、シンプルな新しい寄付フォームをページに挿入する&lt;donation /&gt;タグを導入するタグ拡張機能を使うことを考えます. パーサー関数とフックを持つ拡張機能はMediaWikiの機能を変更もしくは強化するためにもっとも効果的な手段です. 他のMediaWikiユーザーによって作成された既存の拡張機能に関しては、拡張機能の一覧表をご覧ください. 拡張機能を作成する前に誰かが既に作成していないかどうか常に一覧表を確認すべきです.

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

例
この例では、&lt;sample&gt;タグに対するコールバック関数を登録します. 次のようにユーザーはこのタグをページに追加できます:, パーサーはefSampleRender関数に以下の3つの引数を指定して呼び出します:

For a more elaborate example, see Tag extension example
 * $input : &lt;sample&gt;と&lt;/sample&gt;タグの間、もしくはnull、タグが"閉じている"場合では、&lt;sample /&gt;となります
 * $args : タグの引数で、HTMLのタグ属性のように入力されます; これは属性名でインデックス化された連想配列です
 * $parser : 親パーサーです; もっと高度な拡張機能が、文脈上のTitleを取得、wikiテキストを解析、中括弧を拡張、リンク関係や依存関係を登録などする際にこれを使用します.
 * $frame : The parent frame (a PPFrame object). This is used together with $parser to provide the parser with more complete information on the context in which the extension was called.

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

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

MediaWikiで利用可能なタグ拡張機能は非常に豊富です. その中のいくつかはこのサイトに登録されており; 他のものはウェブ検索を通して見つけることが出来ます. While a number of these are quite specialised for their use case, there are a great deal of well-loved and well-used extensions providing varying degrees of functionality.

規約
一つの拡張機能を単独のファイルで構成できますが、それぞれの拡張機能に対して、extensionsディレクトリの中に サブディレクトリを作成してその中に以下の3つのファイルを設置することをお勧めします:


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

セットアップファイルによって1つの要素が 配列に追加されます. この配列はどのファイルがロードされるのかを指定します:

For more general instructions, see Manual:Developing_extensions/ja.

拡張機能を公開する

 * 1) Extension:という名前の新しいページを作成します. そのページではどのようにインストールするのか、それを使っている様子を表すスクリーンショットなどの情報を掲載します. これらの情報の掲載を支援するためにTemplate:Extensionという便利なテンプレートがあります. 詳細についてはテンプレートページをご覧ください. ページの本体にできるだけ多くの情報を追加し、talkページに書き込まれるユーザの質問への回答を定期的に行った方がよいでしょう. また、Category:Extensionsカテゴリにあなたのページが表示されているかどうかを確認してください.
 * 2) 拡張機能コードの範囲内で新しくManual:Hooks/jaを作成する拡張機能に関してはExtension hook registryページに登録をお願いします. 新しく特別ページを作成する拡張機能に関してはExtension hook registryページで登録をお願いします.
 * 3) mediawiki-lメーリングリストに通知する.

See also publishing your extension.

セキュリティ関連
上記の例において、入力値を返す前に、htmlspecialchars</tt>を利用して入力値をエスケープしていることにおきづきになると思います. 任意のHTMLインジェクションを回避するためにすべてのユーザー入力をechoしてクライアントに返す前にこの方法で取り扱うことは大切です. HTMLインジェクションはクロスサイトスクリプティング(XSS)の脆弱性を導く可能性があるからです.

タイミングと拡張機能
拡張機能に対してコードを変更する場合、拡張機能を利用するすべてのページが、理論的には、即座に新しいコードの結果を反映します. 技術的には、拡張機能を含むページがレンダーされるたびにコードが実行されることを意味します.

実際には、ページキャッシングのおかげで、これはあまり当てはまりません. ページキャッシングはMediaWikiソフトウェア、ブラウザ、もしくは中間のプロクシ、ファイヤーウォールによって行われます.

MediaWikiのパーサーキャッシュを回避して、新しいバージョンのページが生成されることを保証するためには、ブラウザのアドレスバーに表示されている記事のURLの一番後ろに"?action=purge"を追加してEnterキーを押してページを再読込します. これによってページとそれを参照するすべてのテンプレートはすべてのキャッシュデータを無視して再生成されます. メインページ自身が修正されない場合はパージアクションが必要ですが、レンダーされなけばならない方法法は変更されます(拡張機能が修正された、もしくは修正されたテンプレートを参照しました).

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

拡張機能を利用してキャッシングを無効にする方法は?
MediaWiki 1.5以降では、パーサーは3番目のパラメーターとして拡張機能に渡されます. このパーサは次のようなキャッシュを無効にするために使われます:

Regenerating the page when another page is edited
Maybe you don't want to disable caching entirely, you just want the page to be regenerated whenever another page is edited, similar to the way that template transclusions are handled. This can be done using the parser object that is passed to your hook function. The following method was lifted from CoreParserFunctions.php and appears to work for this purpose.

Fine grained adjustment of caching behavior
You can use fine grained caching for your extension by using cache keys to differentiate between different versions of your extension output. While rendering you have can add cache keys for every feature by adding an addExtraKey method to your hook function, e.g.:

To use the cached version of your page later on you have to implement the hook PageRenderingHash e.g:

バージョン1.16以降
Parser hook functions are passed a reference to the parser object and a frame object; these should be used to parse wikitext.

Parser::recursiveTagParse</tt> has been around since version 1.8. Its advantages include simplicity (it takes just one argument and returns a string) and the fact that it parses extension tags in $text</tt>, so you can nest extension tags.

The second parameter to recursiveTagParse, $frame</tt>, is an optional argument introduced in MW 1.16 alpha (r55682).
 * If $frame</tt> is provided (using the value of $frame</tt> passed to your extension), then any template parameters in $text</tt> will be expanded. In other words, content such as   </tt> will be recognized and converted into the appropriate value.
 * If $frame</tt> is not provided (e.g., $parser->recursiveTagParse( $text )</tt>), or if $frame</tt> is set to false, then template parameters will not be expanded;  </tt> will not be altered.  Although this unlikely to be the desired behavior, this was the only option available before MW 1.16.

However, one step of parsing that is still skipped for tags, even when using recursiveTagParse, is Parser::preSaveTransform. preSaveTransform is the first step of parsing, responsible for making permanent changes to the about-to-be saved wikitext, such as: The original call to preSaveTransform intentionally skips such conversions within all extension tags. If you need pre save transform to be done, you should consider using a parser function instead. All tag extensions can also be called as a parser function using  which will have pre save transform applied.
 * Converting signatures (, ~ ,  )
 * Expanding link labels, also known as the pipe-trick (e.g., changing Help:Contents into Contents ). Without this step, shorthand links such as Help:Contents are considered to be invalid, and are left in their wikitext form when parsed.
 * Expanding templates.

バージョン1.8から1.15
The only difference before 1.16 is that the $frame argument was not available for Parser::recursiveTagParse</tt>.

If the resulting inability to recognize template variables is a problem, see Extensions and Templates and bug 2257 for more information and workarounds.

バージョン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' -- すべての他の拡張機能です.

関連項目

 * Help:Magic words/ja - List of special tag/variables like,  , ...
 * Manual:Extensions/ja
 * Extensions FAQ/ja
 * Category:Extensions/ja
 * Extension Matrix
 * Manual:$wgExtensionFunctions/ja
 * Project:Extension requests