English version : PukiWiki/Plugin/en
PukiWiki のページをHTML 形式へコンバートする時と、プラグイン機能からの値を受け取った時に処理を行うプラグインを設置することができます。
デフォルトでは plugin です。
英字または数字またはアンダースコア文字
<プラグイン名>.inc.php
#プラグイン名 #プラグイン名(arg1,arg2...)
実際には プラグインディレクトリ/<プラグイン名>.inc.php 内の関数 「plugin_<プラグイン名>_convert()」 が呼び出されます
&プラグイン名(引数リスト); &プラグイン名(引数リスト){[文字列]};
実際には プラグインディレクトリ/<プラグイン名>.inc.php 内の関数 「plugin_<プラグイン名>_inline()」 が呼び出されます
pukiwiki.php?plugin=プラグイン名
実際には プラグインディレクトリ/<プラグイン名>.inc.php 内の関数 「plugin_<プラグイン名>_action()」 が呼び出されます
&hoge(引数リスト);形式と
&hoge(引数リスト){[文字列]};形式の互換のため、function plugin_プラグイン名_inline()では、前者は[文字列]部分が省略されている、という扱いになり、func_get_args() で格納した配列の最後が空文字列('')になり、引数の数も()内に記述した引数の数+1になります
$messages ハッシュ配列を設定し、set_plugin_messages($messages); に渡すのが通例のようです。例
function plugin_<プラグイン名>_init() { $messages['_<プラグイン名>_messages'] = array( 'msg_title' => '<p>メッセージ:%s</p>', 'err' => <p>エラー:%s</p>); set_plugin_messages($messages); }
この例では、$_<プラグイン名>_messages という名前の global 変数ができます。 値は $messages['_<プラグイン名>_messages'] で設定したものです。
plugin_<プラグイン名>_convert() などの関数中では
global $_<プラグイン名>_messages;
のように宣言して使用します。 $_<プラグイン名>_messages['msg_title'] のようにしてアクセスできることでしょう。
ja.lng, en.lng で設定するような値をダウンロードするユーザーの簡便性を考えてプラグイン中で設定しておく場合などに使用することでしょう。set_plugin_messages() を使用するとすでにその変数があった場合は上書きしません。つまり ja.lng, en.lng での設定のほうが優先されます。
ファイル内にecho() やvar_dump() など、出力を開始してしまう関数やコードを置かないでください。
「PHP エラー: headers already sent」が出る原因になります。(例外は、die() またはexit() を実行して、スクリプトを終了させる場合)
ユーザに設定させる初期値などについては、define で定義して下さい。
他の定義名とバッティングしないように、PLUGIN_<plugin-name>_<subject> という形式を推奨します。(BugTrack2/29#zd28eeb6)
コンバート時のGET・POSTの出力内容に必要なものは refer と plugin という値で、
refer : そのページの名前($vars['page'])
plugin : プラグイン名
とします。(1.4 系では、refer を省略する事が可能になりました)
以下の値を global でグローバル変数にすることによって値を取得できます。
$script : スクリプトのurl ※get_script_uri() の使用を推奨します $get : GETメソッドによるHTTPからの引数 ※$varsの使用を推奨します $post : POSTメソッドによるHTTPからの引数 ※$varsの使用を推奨します $vars : GET・POST両方のメソッドによるHTTPからの引数 $vars['page'] : 開いているページ名 (strip_bracket関数により[[]]を %%取り除ける%% 取り除かれている)
代表的なものをいくつか。この他にも、pukiwiki.ini.php などの設定ファイルで使われている変数があります。
これらの定義に応じて、プラグインの動作ポリシーを変更するようにしてください。(例: PKWK_READONLYが有効の場合は、コメント用のフォームを表示しない、投稿を受け付けない)
func_get_args()でプラグインに渡される引数はサニタイズされていませんので、引数の値を出力するプラグインでは、プラグインの中でサニタイズしてから出力しないとクロスサイトスクリプティング(XSS)の脆弱性が発生します。 引数の値をHTML・XHTMLのタグの属性値として出力する場合、プラグイン内で「>」や「&」、「"」などを実体参照に変換しておく必要があります。htmlspecialcharsを通すことで簡単に変換できますので、忘れずに処理しておきましょう。
ただし、インライン型プラグインの場合、{ }内の文字列はサニタイズ済みなので、
&plugin(foo){bar};
形式の bar を得るには、
$args = func_get_args(); $bar = array_pop($args); // サニタイズ済み。そのままHTMLに出力できる
のようにします。 barが省略された
&plugin(foo);
の場合でも、$barには空の文字列が入ります(上記参照)。
htmlspecialchars 関数を用いる際に3番目のパラメータまで全て明示して使用するか、PukiWiki 1.5以降で定義されている互換関数htmlsc を代替として利用するようにしてください。
PHP 5.5 以前のバージョンを使っている場合や、 default_charset の指定が入力とは違う文字セットになっている場合は、 適切な値を指定しておくことを強く推奨します。
とマニュアルにあるように、不一致による文字化けなどが原因となり正常に表示できないケースがあります。
PukiWiki1.4にはアクセス制御が組み込まれているため、プラグインからページを直接読み込んでいる場合はアクセス権のチェックをしないとセキュリティホールになります。 詳しくは PukiWiki/1.4/ちょっと便利に/任意のページごとの閲覧・編集制限 の プラグインの改造 を参照して下さい。
プラグインの中でJavaScriptなどを記述するために<script>タグを出力する場合、PukiWiki 1.4はXHTMLですので、<script>と</script>の間に直に「<」や「&」を記述することができません(HTML 4.01ではCDATAだが、XHTML 1.1ではCDATAではなく#PCDATA)。 XMLのCDATAセクション(<![CDATA[~]]>で囲む)を使用するか、scriptを外部ファイルにする必要があります。XMLに対応していないブラウザとの互換性を重視して、外部ファイルにするのが無難です。
1.4用のプラグインもしくはスキンで、amazonアソシエートによるamazonへのライブリンクを導入する場合、
※都合により、リンク指定でのhttp表記を省略しています
<iframe scrolling="no" frameborder=0 width=120 height=600 src="rcm-jp.amazon.co.jp/e/cm?t=hogehogesite-22&l=st1 &search=%E3%82%A4%E3%83%A9%E3%82%AF&mode=books-jp&p=11&o=9&f=ifr"> <table border="0" cellpadding="0" cellspacing="0" width="120" height="600"> <tr><td> <MAP NAME="boxmap11"> <AREA SHAPE="RECT" COORDS="4,584,115,600" HREF="rcm-jp.amazon.co.jp/e/cm/privacy-policy.html?o=9" alt="プライバシー ポリシー"> <AREA COORDS="0,0,10000,10000" HREF="www.amazon.co.jp/exec/obidos/ redirect?tag=hogehogesite-22&path=tg/browse/-/489986"> </MAP> <img src="rcm-images.amazon.com/images/G/09/extranet/ associates/amzn_recommends/xproduct-skyscrapper120x600.gif" width="120" height="600" border="0" usemap="#boxmap11"> </td></tr> </table> </iframe>
これをPukiWiki 1.4用に書き換えると次のようになります。
<?php if (ereg("MSIE (3|4|5|6)", HTTP_USER_AGENT) == FALSE) { ?> <object width="121" height="602" style="margin-left:auto;margin-right:auto;overflow:hidden" type="text/html" data="//rcm-jp.amazon.co.jp/e/cm?t=hogehogesite-22&l=st1 &search=%E3%82%A4%E3%83%A9%E3%82%AF&mode=books-jp&p=11&o=9&f=ifr"> <?php } else { ?> <object width="140" height="620" style="margin-left:auto;margin-right:auto;overflow:hidden" type="text/html" data="rcm-jp.amazon.co.jp/e/cm?t=hogehogesite-22&l=st1 &search=%E3%82%A4%E3%83%A9%E3%82%AF&mode=books-jp&p=11&o=9&f=ifr"> <?php } ?> <table border="0" cellpadding="0" cellspacing="0" summary="amazon"> <tr><td> <map id="boxmap11"> <area shape="rect" coords="4,584,115,600" href="rcm-jp.amazon.co.jp/e/cm/privacy-policy.html?o=9" alt="プライバシー ポリシー" /> <area coords="0,0,10000,10000" href="www.amazon.co.jp/exec/obidos/ redirect?tag=hogehogesite-22&path=tg/browse/-/489986" alt="" /> </map> <img src="rcm-images.amazon.com/images/G/09/extranet/ associates/amzn_recommends/xproduct-skyscrapper120x600.gif" width="120" height="600" style="border-style:none" usemap="boxmap11" alt="" /> </td></tr> </table> </object>
<iframe>を<object>に書き換えるとき、widthとheightの値を微調整する必要があるのと、style="overflow:hidden"を指定しておくのが無難です。IEの場合、style="overflow:hidden"が効かないバグがあるので、widthとheightの値を大きくしておく必要があります。
ここではIEとその他のブラウザで条件分けしていますが、CSSファイルをIE用とその他のブラウザで分けている場合は、<object>のwidth、heightをCSSファイルで指定しておけば上記のような条件分けは必要ありません。width、height、styleをCSSファイルで指定した場合は<object>は次のように指定できます。
<object type="text/html" data="rcm-jp.amazon.co.jp/e/cm?t=hogehogesite-22&l=st1 &search=%E3%82%A4%E3%83%A9%E3%82%AF&mode=books-jp&p=11&o=9&f=ifr">
1.3系用のamazonkey.inc.phpも上記の修正で簡単に1.4系で使用できます。
ただし、Internet Explorerの<object>にはバグがあり、<object>内のリンクをクリックした場合、フレームでもないのに<object>内でリンク先のページを表示してしまいます。W3C準拠のブラウザではこのような症状は発生しません。
独自プラグイン等での管理者パスワードのチェックはpkwk_login()を利用する事が推奨されています。(see PukiWiki/1.4/1.4.3以前からの移行, 開発日記/2004-07-18)
もともとPukiWiki 1.3.2からNetscape 4.xやIE4などには対応していない(切り捨てている)
(参照: PukiWiki/1.4/NewTable reimy さんの2002-09-17のコメントより)