この記事の概要
Nucleusのスキンにコンテナ・タグのような記述を可能にするユーティリティ・プラグインです。別途対応するプラグインからコンテナ機能を呼び出すためのベースになります(つまりプラグイン作者向けのプラグイン)。
以前試作したプラグインの汎用版です。
NP_Container_v0.3.zip 最新版をご利用ください
このプラグインは、スキンのパース前にコンテナ部分の記述を切り取る処理を行います。インストールしたら、なるべくプラグインリストの上の方に配置してください。
通常プラグインオプションで保持する表示系テンプレートをスキン側に移植するイメージです。
スキンに次のようにパーツを定義できます(begin ~ end 間にコメントを利用してパーツをそれぞれ定義するようになっています)。
<%Container(begin,TestContainer)%>
<!--PART name="header"-->
<dl>
<dt>
blog: <%blogsetting(name)%>
category: <%if(category)%><%category(name)%><%else%>未選択<%endif%>
</dt>
<!--/PART-->
<!--PART name="body"-->
<dd><%TestContainer(blah)%></dd>
<!--/PART-->
<!--PART name="footer"-->
</dl>
<!--/PART-->
<%Container(end)%>
<%TestContainer(max:3,echo:ループ表示だよ)%> <!-- 実際にパーツを利用するプラグイン -->
この例ではheader, body, footer パーツを定義しています。
1行目の<%Container(begin,TestContainer)%> の"TestContainer"の部分は、定義したパーツを利用するプラグイン名を入れます。
コンテナ機能を利用する側のサンプル、NP_TestContainer.phpのコードはこちら。 記述の都合上、PHPの開始・終了タグを省いています。PHPタグを付け足して使ってください。
/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
(see nucleus/documentation/index.html#license for more info)
*/
class NP_TestContainer extends NucleusPlugin {
function getName() { return 'TestContainer'; }
function getAuthor() { return 'yu'; }
function getURL() { return 'http://nucleus.datoka.jp/'; }
function getVersion() { return '0.1'; }
function getMinNucleusVersion() { return 330; }
function getDescription() {
return "Sample plugin using NP_Container";
}
function supportsFeature($what) {
switch($what){
case 'SqlTablePrefix':
return 1;
default:
return 0;
}
}
function doSkinVar($skinType) {
global $manager;
$params = func_get_args();
array_shift($params); // remove skintype parameter
foreach ($params as $param) {
list($type, $value) = explode(':', $param);
switch ($type) {
case 'max':
$this->max = (int)$value;
break;
case 'echo':
$this->echo = $value;
// only continue when the plugin is really installed
if (!$manager->pluginInstalled('NP_Container')) return false;
// get container object
$container =& $manager->getPlugin('NP_Container');
$parts =& $container->getParts( $this->getName() );
$parser =& $container->parser;
$this->cnt = 0;
$parser->parse($parts['header']);
while ($this->cnt++ < $this->max) $parser->parse($parts['body']);
$parser->parse($parts['footer']);
//$container->unsetParts( $this->getName() );
break;
case 'blah':
$echo = ($this->echo) ? $this->echo : 'blah';
echo "{$echo}({$this->cnt})";
break;
}
}
}
}
こんなかんじで doSkinVar() で コンテナ・データを呼び出しています。
スキン・パーサーを呼び出せるので、パーツにスキン変数を記述することも可能です。実際、最初のスキン記述サンプル(コンテナ定義のところ)では、bodyパーツ内に <%TestContainer(blah)%> を配置するなんてことをやってます。
出力結果の例:
<dl>
<dt>
blog: テスト
category: 未選択
</dt>
<dd>ループ表示だよ(1)</dd>
<dd>ループ表示だよ(2)</dd>
<dd>ループ表示だよ(3)</dd>
</dl>
yu:
http://niku.suku.name/item/543
パーツ定義に使ってるコメント形式はもうちょっと判定に融通を持たせていいかも。それこそコメントも書き足せるように。
コンテナをいくつかに分けて定義することができない・・・こりゃひどい。
setParts() の部分は
$this->parts[$plugname] = $data じゃなくて
$this->parts[$plugname] = array_merge($this->parts[$plugname], $data) てかんじかな
コンテナ名(=$plugname)の扱いは別に自由でいいよね?
ていうか利用する側のプラグイン名で縛る方法が思いつかなかった。
利用プラグイン側のプロパティとしてセットしちゃうことも考えたけど、実行順序を考えるとちょっと自信がない。
つか、そろそろフォーラムのほうに提案したほうがいいか