PukiWikiのPlug-inの仕様

English version : PukiWiki/Plugin/en



概要

プラグインディレクトリについて

PukiWiki のページをHTML 形式へコンバートする時と、プラグイン機能からの値を受け取った時に処理を行うプラグインを設置することができます。
デフォルトでは plugin です。

プラグイン名

英字または数字またはアンダースコア文字

ファイル名

<プラグイン名>.inc.php

ページ内でのプラグインの呼び出し

#プラグイン名
#プラグイン名(arg1,arg2...)
  • 行頭にスペースは含めることはできない
  • 引数内に括弧()を使用することができる。ただし ) 単体は不可
  • 引数を指定しなくても呼び出せる

実際には プラグインディレクトリ/<プラグイン名>.inc.php 内の関数 「plugin_<プラグイン名>_convert()」 が呼び出されます

&プラグイン名(引数リスト);
&プラグイン名(引数リスト){[文字列]};
  • 文中で呼び出すことができる

実際には プラグインディレクトリ/<プラグイン名>.inc.php 内の関数 「plugin_<プラグイン名>_inline()」 が呼び出されます

URL指定でのプラグインの呼び出し

pukiwiki.php?plugin=プラグイン名

実際には プラグインディレクトリ/<プラグイン名>.inc.php 内の関数 「plugin_<プラグイン名>_action()」 が呼び出されます

関数

function plugin_<プラグイン名>_convert()

  • wiki ソースからHTMLへのコンバート時に、行頭へ「#プラグイン名」形式が書かれていると呼び出しを試みます
    • プラグインが対応していない(関数が存在しない)場合、エラーメッセージが返されます。
      • ただし、本体以外から呼び出された場合は、その呼び出し元に依存します。
  • HTMLへのコンバート時に呼び出されます
  • 引数は func_get_args() で配列へ格納できます([0]~[n])
    • 複数行引数を使ったかどうかの確認は、n 番目(最後)の配列に改行("\r")が含まれているかで判断する必要があります。
  • func_num_args() によって、渡された引数の数を求めることができます
  • 返値がそのままHTML ソースとして使用されるので、クロスサイトスクリプティングなどのセキュリティホールを作らないよう、注意が必要です。
  • 返値をFALSE とすると、代わりにエラーメッセージを表示します。
    • ただし、本体以外から呼び出された場合は、その呼び出し元に依存します。

function plugin_<プラグイン名>_inline()

  • wiki ソースからHTMLへのコンバート時に、「&プラグイン名;」形式が書かれていると呼び出しを試みます
    • 1.4 系で追加
    • プラグインが対応していない(関数が存在しない)場合、エラーメッセージが返されます。
      • ただし、本体以外から呼び出された場合は、その呼び出し元に依存します。
  • 引数は func_get_args() で配列へ格納できます([0]~[n])
  • func_num_args() によって、渡された引数の数を求めることができます
    • 但し、
      &hoge(引数リスト);
      形式と
      &hoge(引数リスト){[文字列]};
      形式の互換のため、function plugin_プラグイン名_inline()では、前者は[文字列]部分が省略されている、という扱いになり、func_get_args() で格納した配列の最後が空文字列('')になり、引数の数も()内に記述した引数の数+1になります
    • 文字列はPukiWiki 書式であるとして、HTML 形式へと変換済みの状態でプラグインへと渡されます。ただし、ユーザ定義ルールやWikiName などの設定によっては、同じ文字列であっても得られる値が変化するので、取り扱いには注意が必要です。
  • 返値がそのままHTML ソースとして使用されるので、クロスサイトスクリプティングなどのセキュリティホールを作らないよう、注意が必要です。
  • 返値をFALSE とすると、代わりにエラーメッセージを表示します。
    • ただし、本体以外から呼び出された場合は、その呼び出し元に依存します。

function plugin_<プラグイン名>_action()

  • GET・POSTメソッドでpluginを指定されたときに呼び出しを試みます。
    • プラグインが対応していない(関数が存在しない)場合は、エラーメッセージが返されます。
      • ただし、本体以外から呼び出された場合は、その呼び出し元に依存します。
  • 返値は array('msg' => 'title', 'body' => 'contents')
    • キー'body' の要素にはスキンのbody 部分に表示させたいコンテンツを指定します。
      • 省略した場合には、$vars['refer'] で指定されているページを表示します。
      • ただし、ページを表示する前にアクセス制御を確認しないので、注意が必要です。
    • キー'msg' の要素には表示させたいタイトルを指定します。
      • キー'body' を指定した場合は省略できません。
      • キー'msg' の要素に$1 がある場合は、$1 を$vars['refer'] で指定されているページ名に置き換えします。(1.4 系でrefer を省略した場合、$defaultpage が使われます)
        ちなみに、cmd でプラグインを呼び出した場合は、refer の代わりにpage が置き換えに使われます。
  • die() またはexit() を実行することにより、スキンを適用させない事も可能です。
    • pcomment プラグインなどの様にheader() で別ページに飛ばしたり、attach プラグインやrss プラグインなどの様にファイルをダウンロードさせたり、したい時に便利です。
    • この場合に限り、全てのheader を出力した後にecho() やそれに類する関数を利用する事ができます。(これ以外で利用すると、「PHP エラー: headers already sent」に引っかかります)
  • 返値がそのままHTML ソースとして使用されるので、クロスサイトスクリプティングなどのセキュリティホールを作らないよう、注意が必要です。

function plugin_<プラグイン名>_init()

  • 初期化関数。プラグインが呼び出されるとまず最初に実行されます。プラグイン実行毎ではなく、最初の呼び出し時にだけ実行されます。
  • 1.4,4 以降では、返値にFALSE を指定可能です。この場合、エラーメッセージを表示させて終了します。
    • 本体以外から呼び出された場合は、その呼び出し元に依存します。

$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関数により[[]]を %%取り除ける%% 取り除かれている)
  • BugTrack2/213 グローバル変数 $scriptは参照せず、get_script_uri() を使用することを推奨
  • 意図的にGETメソッド、またはPOSTメソッドを禁止するのでなければ、$vars を利用してください。
    • 特に、他からも参照されるpage やrefer の値を書き換える必要のある場合は、$get や、$post だけでなく、$vars も書き換える必要があります。(PukiWiki のシステムが$vars['page'] 、$vars['refer'] と参照しているため)

GET, POST メソッドの入出力パラメータ名に関する制限

'cmd', 'plugin'
プラグイン名を渡すために、予約されています。また、どちらか一方しか利用できません。フォームを使ってプラグインを呼び出す場合や、URL から直接呼び出す場合に使われます。
'page'
'cmd' でプラグイン名を渡す場合のページ名。閲覧時などでページ名を得る場合に、使用することになる。
'refer'
'plugin' でプラグイン名を渡す場合のページ名。1.4 系なら、他のパラメータ名でも可。(ただし、タイトルに関する処理に注意)
'msg', 'pass'
外部からメッセージ・文章やパスワードを受け取るために、予約されています。比較的新しいバージョンのPukiWiki では、GETメソッドでこれらのパラメータが送られてきた場合に、アクセスを拒否します。
'encode_hint'
フォーム利用時に、文字化け防止用文字を自動付加するために予約されています。
'word'
本文中の特定の単語を色分けするために、予約されています。検索結果を表示する時などで使われています。$search_word_color の設定によっては色分け処理が省略されます。
'p'
keitai.skin.php で本文をを分割する時に、利用されています。携帯向け利用を考慮するのなら、このパラメータを使わないようにしてください。
'digest'
更新の衝突を検知するためのmd5 ハッシュを格納するために、利用されています。他の目的でこのパラメータを使うのは、避けたほうが無難です。(特に、他のプラグインにデータを引き継ぐ場合)
  • これ以外のパラメータ名は基本的に自由に使えます。しかし、他のプラグインを呼び出したりする場合は、同じ名前のパラメータが違う目的で使われている事によるトラブルを防ぐために、調整をする必要があります。

内部で予約しているグローバル変数など

代表的なものをいくつか。この他にも、pukiwiki.ini.php などの設定ファイルで使われている変数があります。

$script
スクリプトへのurl
※get_script_uri() の使用を推奨します
$get, $post, $vars
GETメソッド、POSTメソッド、GET・POST両方のメソッド、によるHTTPからの引数
$head_tags
head タグ内に出力したい内容を、収めておく配列。1.4 以降対応(BugTrack/309
ただし、スキンが対応(<?php echo $head_tag ?>)していないと、出力されない。
$javascript
<meta http-equiv="Content-Script-Type" content="text/javascript" /> を出力するためのフラグ。1.4.5 以降対応。(BugTrack/578
ただし、PKWK_ALLOW_JAVASCRIPT 定数によってjavascript を受け入れるポリシーになっている事と、スキンが出力に対応している必要がある。
$pkwk_dtd($html_transitional)
出力するファイルの種類の宣言(DTD)を指定するフラグ。1.4.5 以降対応。(BugTrack/768
以前(1.4~1.4.4)は$html_transitiona というフラグで、有効にするとXHTML 1.0 Transitional になるというものでした。
スキンが対応していない(固定出力している)場合には、意味がありません。
$digest
convert_html() をする時に、$vars['page'] のページソースのmd5ハッシュ値が格納されます。
対象としたいページとは別のものが入っている事があるため、自力で得たほうが無難です。
$do_update_diff_table
更新の衝突時に表示される、差分テーブルを格納するために予約。

PukiWiki本体の重要な定義など

これらの定義に応じて、プラグインの動作ポリシーを変更するようにしてください。(例: PKWK_READONLYが有効の場合は、コメント用のフォームを表示しない、投稿を受け付けない)

PKWK_READONLY
変更を不可とする閲覧専用モードにするための設定。1.4.5 以降対応。(BugTrack/744
同時に各種認証(管理者パス、ユーザー認証)が無効(正解でも拒否する状態)になるので、プラグイン設計時に注意する事。
PKWK_SAFE_MODE
もはや利用されていない機能、常時有効にする必要がない機能、その他安全ではないと思われる機能など、公開Web環境では使わない方がよい機能を、まとめて無効にするための設定。1.4.5 以降対応。(BugTrack/787
PKWK_OPTIMISE
きちんと動作確認を済ませたのであれば必要のない処理(ダブルチェックやデバッグ用メッセージなど)、有用ではあるがスパムやボットなどに大量にアクセス(実行)されるとパフォーマンスに影響がでる動作の重い機能、などを、まとめて無効にするための設定。1.4.5 以降対応。(開発日記/2004-12-02
PKWK_ALLOW_JAVASCRIPT
PukiWikiがJavaScriptを受け付けるかの設定。1.4.5 以降対応。(BugTrack/578
無効の場合は、JavaScriptを用いずに出力する事。(設定を無視して、metaタグやJavaScriptを出力しない事)
PKWK_QUERY_STRING_MAX
PukiWikiが受け付けるQUERY_STRING(URIの?以降)の長さを制限するための設定。1.4.5 以降対応。(開発日記/2005-01-02
長いアドレスを生成する場合には、受付拒否されないようにチェックが必要。
SOURCE_ENCODING
PukiWikiスクリプトのソースで使われている文字エンコーディング。ページ名や各データがソースのエンコーディングに依存しているので、エンコーディング変換を行う際に使用されます。普通は、mbstring モジュールがサポートしているエンコーディング名を使用しているはずです。

クロスサイトスクリプティング(XSS)

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 関数についての注意

htmlspecialchars 関数を用いる際に3番目のパラメータまで全て明示して使用するか、PukiWiki 1.5以降で定義されている互換関数htmlsc を代替として利用するようにしてください。

PHP 5.5 以前のバージョンを使っている場合や、 default_charset の指定が入力とは違う文字セットになっている場合は、 適切な値を指定しておくことを強く推奨します。 

とマニュアルにあるように、不一致による文字化けなどが原因となり正常に表示できないケースがあります。

1.4系プラグイン作成時の注意

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系プラグイン作成時の注意(part2)

1.4用のプラグインもしくはスキンで、amazonアソシエートによるamazonへのライブリンクを導入する場合、

  1. <iframe>を<object>に置き換える必要があります。src="..."をdata="..."に書き換え、type="text/html"を指定します。
  2. 属性値の中の&を&amp;に書き換える必要があります。属性値を必ず引用符で囲む必要があります。タグ名や属性名は小文字にする必要があります。
  3. <map>タグのname属性をid属性に変更する必要があります。
  4. <area>タグ、<img>タグなどを<area ... /><img ... />のように閉じタグ付きに書き換える必要があります。
  5. <img>タグ、<area>タグにalt属性を追加する必要があります。<img>タグのborder属性をstyle="border-width"に書き換える必要があります。
  6. クライアントサイドイメージマップを指定する<img>のusemap属性は、HTML4.01ではURIを与えていましたが、XHTML 1.1ではイメージマップを定義している<map>のid属性の値を指定するよう変更されています。したがって、<img>タグのusemap属性の属性値が#で始まっている場合は#を削除する必要があります。

※都合により、リンク指定でのhttp表記を省略しています

  • amazonアソシエーションで表示されたサンプル
     <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&amp;l=st1
     &amp;search=%E3%82%A4%E3%83%A9%E3%82%AF&amp;mode=books-jp&amp;p=11&amp;o=9&amp;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&amp;l=st1
     &amp;search=%E3%82%A4%E3%83%A9%E3%82%AF&amp;mode=books-jp&amp;p=11&amp;o=9&amp;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&amp;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&amp;l=st1
     &amp;search=%E3%82%A4%E3%83%A9%E3%82%AF&amp;mode=books-jp&amp;p=11&amp;o=9&amp;f=ifr">

    1.3系用のamazonkey.inc.phpも上記の修正で簡単に1.4系で使用できます。

    ただし、Internet Explorerの<object>にはバグがあり、<object>内のリンクをクリックした場合、フレームでもないのに<object>内でリンク先のページを表示してしまいます。W3C準拠のブラウザではこのような症状は発生しません。

1.4系(1.4.4rc1~)プラグイン作成時の注意(part3)

独自プラグイン等での管理者パスワードのチェックはpkwk_login()を利用する事が推奨されています。(see PukiWiki/1.4/1.4.3以前からの移行, 開発日記/2004-07-18)

pukiwiki 用の javascript を作成する際に考慮すべきブラウザは...

もともとPukiWiki 1.3.2からNetscape 4.xやIE4などには対応していない(切り捨てている)

(参照: PukiWiki/1.4/NewTable reimy さんの2002-09-17のコメントより)

関連


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-11-23 (日) 20:08:31
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u2. HTML convert time: 0.355 sec.

OSDN