今回は「第2部 スニペットの作成」で作ったスニペットを呼び出すプラグインを作ります。「第3部 ページの作成」で表示できたから終わりなんじゃない?と思われるかもしれませんが、どっこいそうではありません。「第2部 スニペットの作成」の「3.1 仮実装」では、スニペットが単体で正しく動くことを確認しましたが、どこから、どういう条件で呼び出されるかが決まっていませんでした。ここでは常に最新のMediaRSSが表示されるようにキャッシュのクリアタイミングでスニペットが呼び出されるようにします。
「スニペットを作った経験はあるけどプラグインはない」というMODxユーザーは比較的多いと思います。でも、スニペットもプラグインも同じPHPプログラム。プラグインの仕組みとイベントの種類(タイミング)さえ理解してしまえば身近な仕組みとして利用できので是非チャレンジしてみてください。
なお、プラグインの仕組みが理解しづらいため、本稿ではなにかにつけてうんちくから入ることお許しを。
1.プラグインとは(スニペットとの違い)
1.1 スニペットのおさらい
まず、スニペットの特性を簡単に整理します。スニペットはプログラム用語的には関数・ファンクション(function)・サブルーチン(subroutine)に相当するもので、スニペット名が関数名(エントリーポイント)、呼び出し時の¶m=`value`で表現される複数指定可能な情報が引数(パラメータ)、return文で返す情報が復帰値(リターンバリュー)に相当します。関数名は必須ですが、引数と復帰値は省略できます(この場合は”サブルーチン”などと呼ぶこともあります)。当たり前のことですが、スニペットは作っただけでは何も起こらず、他の場所から意図的に呼び出すこと([[snippet]] / [!snippet!] / MODxAPIのrunSnippetなど)ではじめて機能します。これらのことと比較する形でプラグインという機能を解説してみます。
1.2 プラグインの特徴(呼ばれ方)
プラグインを言い換えるなら、”割り込み処理”または”イベント処理(イベントハンドラ)”という言葉が一番近いように思います。”割り込み処理”は、MODxのコアプログラムの一連の処理にユーザーが作った処理を割り込ませる能動的なアクションです。一方”イベント処理”は、MODxのコアプログラムの一連の処理の特定な場所(タイミング)を”イベント”と定義し、そのタイミングでユーザーが作った処理がコアから呼ばれる受動的なアクションになります。イベントそのものまたはイベントに処理を登録することを”フック”などと表現することもあります。ここで言うフックとは”物を引っ掛けるための道具”やその動作を指します。要は引っ掛けたり、ぶらさげたり、とめておいたりってこと。”イベントドリブン”、”イベント駆動”、”イベントドリブンなプログラム”などと表現することもあります。
1.3 プラグインの引数
スニペットは呼び出し元の事情に応じた値を引数に指定することで処理結果をコントロールできますが、プラグインはそのようなことはできません。なぜなら、プラグインはその仕組上、コアのあるポイント(イベント)からしか呼ばれないからです。プラグインには単一のイベントだけを処理するものと複数のイベントを処理するものがあります。プラグイン(イベントハンドラ)にはイベントの種類や詳細な情報を含むイベント情報が渡され、イベントの振り分けなどに利用されます。管理画面のプラグイン編集画面の設定タブには、”パラメータ”と”値”が対になった引数に似た情報が存在します。これはプラグイン使用者の環境や好みで変わる可能性のある情報をコードの外に追い出すことを目的とした一種のカスタマイズ情報で、呼び出し元と関係するものではありません。
1.4 プラグインの復帰
スニペットは呼び出し元にreturn文で値を返しますが、プラグインは基本的には値を返しません。なぜなら、コアは呼び出す先は分かっていも返される値の型や意味が予測できないからです。ただ例外的に、イベント情報には出力用変数が用意されており、そこに値を入れて返すことがあります。インストーラに同梱されるForgot Manager Loginプラグインなどが良い例です。これは、プラグインが値を返すのではなく、呼び出し元(コア)に処理を依頼したり情報を保存するためのもので、復帰値とは大きく意味が異なります。
1.5 プラグインの実行順
プラグインはイベントにフックすることで動くプログラムです。1つのイベントには複数のプラグインがぶらさがることがあります。例えば、ある既存のプラグインの処理結果が気に入らない場合、プラグインを新規に作成し、既存プラグインの後で実行できれば、既存プラグインを改造することなく挙動を変化させることができます。このような場合に使うのが、プラグイン管理の頭にある「イベント発生時のプラグインの実行順を編集」です。
プラグインの仕組みをざっと見たところで、さて制作に・・・といきたいところですが、「なぜプラグインからスニペットを呼ぶようにしたのか」が明確になっていません。ということで、もうひと頑張り。。。
2.プラグインからスニペットを呼ぶようにした理由
細かいことを気にしなければ、ぶっちゃけテンプレートやリソース、MaxiGalleryからスニペットを呼べば済む話なんです。本シリーズの最初に申し上げた「弄って理解する」が最大の理由だったりしますが、こだわりを2,3申し上げますと・・・
2.1 サーバーへの負荷対策
テンプレートやリソースから非キャッシュでスニペットをコールしてMediaRSSを作った場合、閲覧者からページがリクエストされるたびにMediaRSSを作ることになるので言語道断。ということで、動的にMediaRSSを生成するプランはボツ。
2.2 閲覧者への負荷対策
テンプレートやリソースからキャッシュでスニペットをコールしてMediaRSSを作った場合、キャッシュクリア後の最初の閲覧者に負荷がかかる。ということで、この時点でテンプレートやリソースから呼ぶプランはボツ。
2.3 既存のプログラムをなるべく改造したくない
MaxiGalleryが管理する最新の画像を配信するのだから、MaxiGalleryで画像を追加・変更・削除したタイミングでスニペットを呼んでMediaRSSを作り直すのが理にかなってる。でも、できればMaxiGalleryは改造したくない。ということでMaxiGalleryの改造プランもボツ。
等々流れて、「んじゃ、MediaRSSを保存する場所はcacheの下だし、キャッシュクリアイベントで作るか」となりました。その後アホなことにMaxiGalleryによる画像の追加・変更・削除ではキャッシュがクリアされないことが分かりマニュアルで消すことに・・・(そりゃそうだよ)。ということで、2.3のこだわりはどこへやら、MaxiGalleryを改造してキャッシュをクリアするようにしました。
自分A: そんなことなら2.3の方がマシなんじゃない?(キャッシュが消えて結局サーバーと閲覧者に迷惑が・・・)
自分B: いいんです。右往左往が目的ですから。これぞMODx習得の極意なり。
3.プラグインの実装
折角スニペットに引数を付けて、出力内容を呼び出し元から変えることができるようにしたので、2種類のMediaRSSを作ることにしました。1つのプラグインでスニペットを2度コールすればおしまいですが、プラグインのパラメータをシンプルに使いたいので、プラグインを2つ作ります。
3.1 mrss.rssを作るプラグイン
プラグインを新規に作成し、以下の設定で保存します。最新20件の画像をフィードし、サムネイルクリック時はリサイズ画像が表示されます。このMediaRSSは、サイト右上のフィードと「画像を画面一杯に表示」で利用されます。
| プラグイン名 | : | MaxiGalleryMediaRss |
| 説明 | : | キャッシュアップデート時にフィード用mrss.rssを作成 |
| プラグインコード | : | 下参照 |
| プラグイン設定 | : | 下参照 |
| システムイベント | : | OnCacheUpdate |
プラグインコード)
Title: MediaRss for MaxiGallery
Category: Plugin
Author: quickart
Author URI: http://www.quickart.jp/
License: GNU General Public License(http://www.gnu.org/licenses/gpl.html)
Version: 1.0.0
Last Update: 2009-12-24
==============================================================================*/
$e = &$modx->event;
switch ($e->name) {
case "OnCacheUpdate":
$modx->runSnippet('MaxiGalleryMediaRss', array(
'rsspath'=>$rsspath,
'mgtable'=>$mgtable,
'mgfolder'=>$mgfolder,
'mgthumbpre'=>$mgthumbpre,
'mgbigpre'=>$mgbigpre,
'mgusebig'=>$mgusebig,
'logopath'=>$logopath,
'copyright'=>$copyright,
'includeDocs'=>$includeDocs,
'excludeDocs'=>$excludeDocs,
'limit'=>$limit
)) ;
break;
}
プラグイン設定) ※includeDocsはMaxiGallery用リソースを指定のこと
3.2 photos.rssを作るプラグイン
3.1で作ったプラグインを複製し、以下の設定で保存します。最新60件の画像を表示し、サムネイルクリック時は大画像が表示されます。このMediaRSSは埋め込みページで利用されます。
| プラグイン名 | : | MaxiGalleryMediaRssforCooliris |
| 説明 | : | キャッシュアップデート時にCoolIris用photos.rssを作成 |
| プラグインコード | : | (変更の必要なし) |
| プラグイン設定 | : | 下参照 |
| システムイベント | : | OnCacheUpdate(変更の必要なし) |
プラグイン設定) ※includeDocsはMaxiGallery用リソースを指定のこと
4.テスト
- MaxiGalleryで画像を操作(追加・更新・削除
- 管理画面でキャッシュをクリア
- assets/cache/rss/mrss.rssとassets/cache/rss/photos.rssの日付と内容を確認
- 「画像を画面一杯に表示」でCoolIrisに最新画像が表示されることを確認
- 埋め込みページでCoolIrisに最新画像が表示されることを確認
5.まとめ
正直なところを書いたつもりですが、終盤グダグダでお見苦しい点が多々あったと思います。本シリーズの最初に申し上げた「MODx(オープンソース)の醍醐味」みたいなものが少しでも伝わることを祈りつつ、このシリーズを終えたいと思います。なお、文書内の誤りは自己レビューで随時修正するようにしてますが、多くの問題が残ってると思います。おかしな点はご指摘いただけるとありがたいです。
さて、次は何を書くか・・・って、実は決まってたりして ^^;
では御機嫌よう




















samaさん、先ほどコメントありがとうございます。
ModxもCMSも初めてでインストールであたふたした状態です・・・(笑)
このブログ、お気に入りに入れて今後勉強させてもらいます。
宜しくお願いします~・・・
ヒロトンさん、コメありがとうございます。
自分はどちらかというと、CMS/CMFの応用に興味があるので「MODx(CMS)をどう使うか」/「MODx(CMF)で何ができるか」ということを、なるべく分かりやすく書いていきたいと思っています。
このブログは公開から日も浅く、ネタも希薄で、手探りの状態で運営してます。ですから、ネット上の皆さんのブログが先生なんです。この辺も含め、皆さんとセッションしていけたらいいなーと思ってます。
今後とも宜しくお願いします。