*1 : 2007/5/13時点でSmartyの最新版は2.6.18なんだけど2-6-7というのは何を意味してるのか不明.Ver.2.6マニュアルの第7版?
<?
// include_pathをSmartyインストールディレクトリに通しておく必要がある
include("Smarty.class.php");
// Smartyは,生成したオブジェクトを通して操作する
$objSmarty = new Smarty();
// テンプレートディレクトリとキャッシュディレクトリは,デフォルトでこの値になってる.
$objSmarty->template_dir = "./templates";
$objSmarty->compile_dir = "./templates_c";
// assign(テンプレート内の変数名, 割り当てる値); でテンプレート内の変数に値を割り当てる
$objSmarty->assign('body_message', 'テスト');
// 当然ながら変数も使える
$bodyMessage = "変数テスト";
$objSmarty->assign('var_body_message', $bodyMessage);
// 表示する
$objSmarty->display("example.tpl");
// fetchとは,「取ってくる」という意味.
// 棒を投げて犬に取ってこさせるような時に言うみたい.
// つまりは,処理結果を取ってくる.そんなイメージ.
// テンプレート内の変数にassignしたデータを割り当てた文字列,
// つまりdisplayした時に表示されるHTMLデータを取得する.
$htmlDocument = $objSmarty->fetch("example.tpl");
?>
example.tpl
<html>
<head><title>example</title></head>
<body>
{* テンプレート内でSmartyの機能を使う時は,中括弧で囲みます *}
{$body_message}<br />
{$var_body_message}
</body>
</html>
表示<html> <head><title>example</title></head> <body> テスト<br /> 変数テスト </body> </html>
{* テスト *}
| 表記*2 | |
|---|---|
| $foo | 配列やオブジェクトではない単純な変数を表示 |
| $foo[4] | ゼロから始まる配列の5番目の要素を表示 |
| $foo.bar | PHPで言う所の$foo['bar'].配列$foo*3をassignする |
| $foo.$bar | PHPで言う所の$foo[$bar]配列*4のキーを変数で表記 |
| $foo->bar | オブジェクト$fooのプロパティbarを表示 |
| $foo->bar() | オブジェクト$fooのメソッドbar()を実行した結果を表示 |
| $smarty.config.foo | 設定ファイル*5の変数fooを表示 |
| #foo# | $smarty.config.fooの簡易表記 |
| $foo[bar] | {section}{/section}内でのみ有効.詳細は繰り返しについて説明する所で |
*2 : 全て{ }で囲んで使うことを前提に書いてます
*3 : 連想配列と言いたいけど……
*4 : 連想配列
*5 : Smartyの?
*6 : そのパラメータに変数も使える
include("Smarty.class.php");
$objSmarty = new Smarty();
$variables = array();
$variables["first"] = "いっこめ";
$variables["second"] = "にこめ";
$variables["third"] = "さんこめ";
$objSmarty->assign($variables);
$objSmarty->display("example.tpl");
example.tpl
{$first}{$second}{$third}
表示いっこめにこめさんこめ
include("Smarty.class.php");
$objSmarty = new Smarty();
$bar = new foo();
// get_object_varsは,オブジェクトの持つpublicなプロパティの
// プロパティ名をキー,その値を値とする連想配列を取得する
$variables = get_object_vars($bar);
$objSmarty->assign($variables);
$objSmarty->display("example.tpl");
class foo {
public $first;
public $second;
public $third;
public function __construct() {
$this->first = "いっこめ";
$this->second = "にこめ";
$this->third = "さんこめ";
}
}
詳しい説明はこことかで*7.*7 : オブジェクトをassignして{$object->member}でアクセスする形にしてもいいと後で思った.
| 属性名 | 型 | 概要 |
|---|---|---|
| start | integer | ループ開始番号. 0より小さい値を指定すると末尾から順番に頭に向かって数値が減っていく. 例えば-1なら最後尾.-2なら最後尾から2番目. startとstepを-1にすると末尾から頭に向かうループになる*9. |
| step | integer | ループごとにループカウンタがどれだけ増減するか |
| max | integer | ループ回数の最大値.ループ回数はloopで決定するが, それを配列の要素数などで動的な値にした時のリミッターになる. |
| show | boolean | セクション自体を表示するか否か |
<?
include("Smarty.class.php");
$objSmarty = new Smarty();
$arraySource = Array("a","b","c","d");
$loopMax = 3;
$objSmarty->assign('arraySource', $arraySource);
$objSmarty->assign('loopMax', $loopMax);
$objSmarty->display("example.tpl");
?>
example.tpl
// ループ回数を定数で指定
constant:
{section name=idx loop=2}
{$arraySource[idx]}
{/section}
// ループ回数を変数で指定
variable:
{section name=idx loop=$loopMax}
{$arraySource[idx]}
{/section}
// 配列の要素数分ループ
array:
{section name=idx loop=$arraySource}
{$arraySource[idx]}
{/section}
表示constant:ab variable:abc array :abcdおまけ foreach
{* PHP の foreach($myArray as $foo) に対応 *}
{foreach from=$myArray item=foo}
{$foo}
{/foreach}
| 項目 | 内容 |
|---|---|
| index | 現在のループのインデックス |
| index_prev | 前回のループでのインデックス(初回は-1) |
| index_next | 前回のループでのインデックス |
| iteration | 現在のループが反復された回数 回数なので1回目のループでは1 |
| rownum | iterationのエイリアス |
| first | 現在のループが1回目ならtrueになる |
| last | 現在のループが最後ならtrueになる |
| loop | セクションが最後に処理したループのインデックス セクションの外でも使えるのが特徴 |
| show | sectionの属性のshowと同じ |
| total | セクションがループした合計回数*10 |
$smarty.section.セクション名((nameで指定した文字列)).項目名
//例
<section name=sample>
{$smarty.section.sample.index}
</section>
<?
include("Smarty.class.php");
$objSmarty = new Smarty();
// 連想配列の配列
$masterArray = Array();
$masterArray[] = Array("name" => "apple" , "date" => "2007/08/21","comment" => "りんご");
$masterArray[] = Array("name" => "orange", "date" => "2006/08/21","comment" => "オレンジ");
$masterArray[] = Array("name" => "cherry", "date" => "2003/08/21","comment" => "チェリー");
// 見ての通り,別にテンプレートの変数名とPHPの変数名が一致する必要は無いです
$objSmarty->assign('arraySource', $masterArray);
$objSmarty->display("example.tpl");
?>
example.tpl
{section name=idx loop=$arraySource}
名前 :{$arraySource[idx].name}<br>
登録日 :{$arraySource[idx].date}<br>
コメント:{$arraySource[idx].comment}<br>
{/section}
名前 :apple<br> 登録日 :2007/08/21<br> コメント:りんご<br> 名前 :orange<br> 登録日 :2006/08/21<br> コメント:オレンジ<br> 名前 :cherry<br> 登録日 :2003/08/21<br> コメント:チェリー<br>
<?
include("Smarty.class.php");
$objSmarty = new Smarty();
$firstArray = Array("a","b","c","d");
$secondArray = Array("a","b","c","d");
$objSmarty->assign('firstArray', $firstArray);
$objSmarty->assign('secondArray', $secondArray);
$loopMax = 3;
// unsetして変数が無効になるとsectionelseが表示される
unset($loopMax);
// ここでassignしなかったらsectionelseが表示される
$objSmarty->assign('loopMax', $loopMax);
$objSmarty->display("example.tpl");
?>
example.tpl
{section name=idx loop=$loopMax}
first:{$arrayFirst[idx]}<br>
second:{$arraySecond[idx]}<br>
{sectionelse}
ループ回数が不明です
{/section}
表示ループ回数が不明です
*8 : 識別する名前であると気付いたのが遅かったのでここのサンプルはnameにidxとか適当な名前が入ってしまってます.
*9 : 注意すべきはこの時のloop属性.間違ってはいけないのはloopは,あくまでループ回数を指定しているわけでloopの値になるまでループするとかでは無い.なので末尾からのループだからloop=0にしなければいけないというのは間違い.
*10 : リファレンスによると参照した時点での累計ループ回数が入るはずですが,私が試した時にはループ回数が表示されました.別の環境で再現するかは確認してません.
演算子の両端には必ず空白が必要
{if $name == "apple"}
...
{elseif $name == "orange"}
...
{else}
...
{/if}
使える論理演算子はここを参照.== != > < >= <= === ! //否定 % //剰余 && (and) || (or)テーブルを作ったりする時に便利なのがこれ
| 演算子 | 意味 |
|---|---|
| is [not] div by | 割り切れる |
| is [not] even | 偶数である |
| is [not] even by | よくわからない*11 |
| is [not] odd | 奇数である |
| is [not] odd by | is [not] even byの奇数版 |
*11 : PHPに直すと($a is even by $b)は(($a / $b) % 2 == 0)らしい
{literal}
<script language="JavaScript">
<!--
function navigate(path){
window.navigate(path);
}
// -->
</script>
{/literal}
{* 相対値を指定するには,+や-を付ける *}
{html_select_date display_days=false display_months=false start_year='+0' end_year='+2' prefix='cmbDate'}
表示<select name="cmbDateYear"> <option label="2007" value="2007" selected="selected">2007</option> <option label="2008" value="2008">2008</option> <option label="2009" value="2009">2009</option> </select>
{html_select_date|indent:3:"\t" display_days=false display_months=false start_year='+0' end_year='+2' prefix='dateEnd'}年
この場合,html_select_dateの直後に|indent:3:"\t"を入れているのがポイント.
<?
include("Smarty.class.php");
$objSmarty = new Smarty();
// 値が未定義の変数$foo
$objSmarty->assign("foo", $foo);
$objSmarty->display("example.tpl");
?>
example.tpl
{$foo|default:'初期値'}
表示初期値
{$foo|escape:'html'}
{$foo|string_format:"%07s"}
$fooが31なら,表示されるのは0000031.
{section name=testSection loop=10}
{if isset($sampleArray[testSection])}
{* こちらにオブジェクトの要素に当たった時の処理を書く *}
{else}
{/if}
{/section}
issetを比較時に使えばOK.
{math equation="x + y" x=1 y=1}
出力)2例えば,テンプレート変数と定数のかけ算でピクセル数を設定したい場合の例を挙げます.
<div style="height: {math equation="x / 100 * y" x=$height y=50}px;">
テスト
</div>
この例は,次のように計算されます.$height / 100 * 50ちなみに,演算結果を整数部のみにしたい場合は,次のようにsptintf形式のformat属性を指定します.
<div style="height: {math equation="x / 100 * y" x=$height y=50 format=%d}px;">
テスト
</div>
{include file='テンプレートファイルパス' include先にアサインする変数名=アサインする変数の実体}
実際に使うと次のようになります.(ループ内でも使えることも示します)
parent begin
{section name=testLoop start=0 loop=3}
{include file='child.tpl' foo=$bar hoge=$fuga count=$smarty.section.testLoop.iteration}
{/section}
parent end
child.tpl
child{$count} begin
変数foo:{$foo}
変数hoge:{$hoge}
child{$count} end
PHP側は次のような形.
$mySmarty = new Smarty();
$mySmarty->assign('bar', '変数bar');
$mySmarty->assign('fuga', '変数fuga');
$mySmarty->display('parent.tpl');
これを実行すると次のように表示されます.parent begin child1 begin 変数foo:変数bar 変数hoge:変数fuga child1 end child2 begin 変数foo:変数bar 変数hoge:変数fuga child2 end child3 begin 変数foo:変数bar 変数hoge:変数fuga child3 end parent end
<input type="text" name="hoge" value="{$hogehoge|escape:'html'}">
<textarea name="fuga"{$fugafuga|escape:'html'}</textarea>
こんな感じでフォームに値を入れる時に例えば<を<に変換して表示しても,return htmlspecialchars($string, ENT_QUOTES, $char_set);これだけ.なので変なエスケープは,htmlspecialcharsが原因っぽいけど,そんなバグみたいなのあったっけ?それとも(\")が正しいのかな.と思いかけたけどそんな変換が正しいわけが無いと思う.
*12 : 空白が表示されるのかなと思ったらこの動作は助かります.
*13 : XSSがどうこう以前に埋め込んではいけない文字は,埋め込んではいけないのです.
*14 : <が<に変換されて送られてくる