Tips 動的にテンプレートを変えるプラグイン

SJIS TIPSの流れから引き続き、関連のTIPSです。
といっても、テンプレートを変更するプラグインでTemplateSwitcherっていうプラグインがあるんですが・・・基本はこれと同じなわけです。
条件をUAによって振り分けれれば、SJISプラグインと合わせることによりページング処理を除いて携帯対応ってことになりますね。
今回使用するイベントは、OnLoadWebDocumentっていうイベントです。
このイベントが発生したときには、実は$modx->documentContentという変数には使用するテンプレートが展開されて入ってきてます。
このあとに、中身をパースしてドキュメントの中身を指示に従って入れ込んだり、スニペットを呼び出したと実際のページ作成の処理に入っていきます。
なので、このイベントでテンプレートの中身を入れ替える必要がでてくるわけです。

以下のコードは、以前携帯対応をしたときの抜粋&若干の手直しバージョンです。
携帯か?の判断文はありませんが、判断を入れれば、携帯のときのみにテンプレートを入れ替えるということが可能になります。
単純な携帯判定であれば、

if (preg_match("#docomo|softbank|vodafone|kddi#i",$_SERVER["HTTP_USER_AGENT"])
{
   ここにテンプレート切り替えロジックを入れる

みたいな感じになるでしょうか?
PearのNet_UserAgent_Mobileを利用して、判定ロジックはそちらに委ねるのもよいかと思います。
0.9.6でもこの部分の内部ロジックに変更はなかったので、多分いけるはずですが、実際に利用していた時期は0.9.2.1の頃です。

  1. switch ($e->event)
  2. {
  3. case "OnLoadWebDocument":
  4.         if($modx->documentObject['template'])
  5.         {
  6.                 $sql = "SELECT templatename FROM ".$modx->getFullTableName("site_templates")." WHERE ".$modx->getFullTableName("site_templates").".id = '".$modx->documentObject['template']."';";
  7.                 $result = $modx->dbQuery($sql);
  8.                 $row = $modx->fetchRow($result);
  9.                 $templates = $row['templatename'];
  10.                 if (!strstr($templates,"M@"))
  11.                 {       
  12.                         $templates = "M@".$templates;
  13.                         $sql = "SELECT id FROM ".$this->getFullTableName("site_templates")." WHERE ".$this->getFullTableName("site_templates").".templatename = '".$templates."';";
  14.                         $result = $this->dbQuery($sql);
  15.                         $row = $this->fetchRow($result);
  16.                         $new_id = $row['id'];
  17.                         $sql = "SELECT * FROM ".$modx->getFullTableName("site_templates")." WHERE ".$modx->getFullTableName("site_templates").".id = '".$new_id."';";
  18.                         $result = $modx->dbQuery($sql);
  19.                         $rowCount = $modx->recordCount($result);
  20.                         iif($rowCount==1) {
  21.                                 $row = $modx->fetchRow($result);
  22.                                 $modx->documentContent = $row['content'];
  23.                         }
  24.                 }
  25.         }
  26.         break;
  27. }

上記の処理では、テンプレートID番号からテンプレート名を取得し、M@(キーワード)がないテンプレート名の場合は、そのテンプレート名の先頭にM@を付けたテンプレート名をデータベースから探し出し、その内容をDocumentContentに格納します。
ちなみに、$modx->documentObject['template']にテンプレートのID番号が入ってきます。
(_blankの指定の場合は、0/nullです)
該当テンプレートが見つからないか、複数見つかった場合(ありえないとは思うけど)は、テンプレートを変更せずにそのままオリジナルテンプレートで動作します。
ここら辺は、しっかりとルール通りに設置運用しておけば問題ないはずということで手を抜いています。

携帯3キャリアごとにテンプレートを分ける場合には、それぞれテンプレート名の区別する文字コードを付加して、対応テンプレートを求めればよいでしょう。(ココでは、ロジックを簡潔にする為に携帯かそうでないかしかやっていませんが)
同じように、MacかWinで別のものっていう場合も同様に可能かと思います。

もちろん、プラグインで変更ではなくてスニペットでという方法も考えられます。
実際試してはいませんが、テンプレートに判定スニペットを作ってそれを呼び出すだけ・・・・。
実際のテンプレートの内容の部分はチャンクをテンプレートとして使う一般的なやり方です。

[!UA?pc=aaaa&mobile=bbb!]

みたいな感じのスニペットで、UserAgentを判別して、PCなら変数pcのチャンクを返して、携帯なら変数mobileのチャンクを返すという方法です。

多分、いけるはずです。
この方がシンプルかも知れませんねぇ。

ところで、このテンプレートを動的に切り替えるプラグイン及びスニペットではドキュメントのキャッシュを有効にしてはいけません。
当然のことながら、UAごとに中身が変わっちゃうわけなので・・・・。

あとはページングですけど、これはPagenationプラグインも合体させればいけるんじゃないかなぁと思います。

絵文字とかについては・・・・いつか、トライしてみますが・・・コンバートするしかないなかぁ プラグインで。
アクセスキーについては、そのままPC用でも入れて置けばよいとは思いますが・・・。
ってなことで、不明な点、おかしいぞ というところがありましたらご連絡くださいまし。

プッシュ通知を