2008年2月16日土曜日
2008年1月17日木曜日
【modifier】テンプレート上のSmarty変数をPHP関数で扱う
ITpro
【PHP TIPS】 68. Smartyのmodifierを使いこなそう
Smartyでは 、assignされた変数に処理を与えるmodifier という機能がある。
PHP関数をパイプ「|」でつなげて記述して使用します。
$smarty->assign('name', 'atsushi');
上記のコードをPHPファイル内に記述して変数をアサインする。 テンプレート内で文字を大文字にするstrtoupper()関数で処理するにはに
{$name|strtoupper}
//結果:ATSUSHI
modifierに配列を渡す場合は、関数名の前に「@」をつける。
$name_list = array(
'0' => 'atsushi',
'1' => 'yoshiki',
'2' => 'miwa',
'3' => 'hiroshi',
'4' => 'saito'
);
$smarty->assign('name_list', $name_list);
{$name_list|@count}
//結果:5
modifierには「:」をつけることで引数を渡すこともできる。
{$name|substr:'1':'3'}
//結果:tsu
modifierでは、パイプの前の変数とコロンの後に指定した値が、並べた順番にそのまま関数に渡される。
例えば、{$name|str_replace:'shi':'ko'}だとstr_replace($name, 'shi', 'ko')渡していることになる。
str_replace('shi', 'ko', $name); のように渡したい場合は次のようになる。
{'shi'|str_replace:'ko':$name}
//結果:atsuko
{'/a|i|s/'|preg_replace:'!':$name}
//結果:!t!u!h!
参考
- ITpro 総合トップ
- http://itpro.nikkeibp.co.jp/index.html
2007年12月28日金曜日
php+smartyで動いているPC用のサイトをテンプレートだけ変えて携帯サイトに変換する方法をご紹介。
1.ユーザーエージェントやIPなどで携帯からのアクセスか、パソコンからのアクセスかを判別する。
2.携帯からのアクセスだった場合はsmartyのテンプレート関連ディレクトリを携帯用のテンプレートを入れたディレクトリに切り替え。
>※携帯用のテンプレートはPC版と同じ文字コードにしておいてください。
3.$smarty->displayしてるとこでPCからのアクセスだった場合はそのままdisplayで表示させる。
携帯からのアクセスだった場合は$smarty->fetchで表示結果を変数に取得し、mb_convert_encodingを使って文字コードをSJISに変換して変数の内容をecho()で書き出し。みるくぜりー| php+smartyで手抜きケータイサイトをつくる。
詳しいところはリンク先を参照。
PEARを使った携帯・PCのアクセス判別や、テンプレート・ディレクトリの切り替えに関するソースを省いた必要な部分が以下。
それらがあったほうが便利で楽だが、PEAR使えないサーバもあるので。
class Smarty_Ex extends Smarty{
function display($template, $cache_id = null, $compile_id = null)
{
//携帯なので結果をいったん変数に
$output=parent::fetch($template);
//半角カナにしてパケ代をとりあえず節約。
$output=mb_convert_kana($output,"k","UTF-8");
//SJISに変換しましょう。
$output=mb_convert_encoding($output,"SJIS","UTF-8");
echo $output;
}
}
上のクラスはsmartyオブジェクトを継承してるので、使うときは変わらず。以下の通り。
上のクラスでは、キャリアの判別とディレクトリ切り替えをしてないので、実際使うときはPCと携帯のそれぞれで別のテンプレート・ファイルを呼び出すようにする必要がある。
$smarty=new Smarty_Ex();//smartyオブジェクト作成
$smarty->assign('var',$var);
$smarty->display("index.tpl");
2007年11月8日木曜日
【assign】テンプレートでの変数の定義
テンプレートファイル内で変数を定義するには{assign}関数をつかう。
{assign var="var" value="`$val1 + $val2`"}
使うときは他の変数と同様に{$var}
varが変数名でvalueが値。
"`"で囲むと文字列ではなく計算式として扱う。
【foreach】テンプレート内での繰り返し・ループ
配列のSmarty変数をループさせるにはforeachがある。
{foreach from=$data item="value" key="key" name="loop"}
{if $smarty.foreach.loop.first}
最初:{$key}:{$value}
{elseif $smarty.foreach.loop.last}
最後:{$key}:{$value}
{else}
{$smarty.foreach.loop.iteration}:{$key}:{$value}
{/if}
{foreachelse}
データがありません
{/foreach}
itemとfromの指定は必須。
配列のキーを使うにはkeyの指定が必要。
以下のSmarty予約変数を使うにはnameの指定が必要。
$smarty.foreach.loop.first … 最初の要素かどうか $smarty.foreach.loop.last … 最後の要素かどうか $smarty.foreach.loop.iteration … 現在のインデクス(何回目のループかカウント)
2007年10月9日火曜日
foreachとsectionの比較
Smartyforeachとsectionではどちらを使った方が良いか
プログラミングにおいて、同じような処理をする関数ではどちらが処理速度が速いのか、というのは議論になるところと思います。
PHPではecho()とprint()だったり、ループではdo()とwhile()とfor()だったり。
当たり前ですが、処理が単純で引数などがない方が速い様に思います。確か条件分岐があるだけでもプログラムの処理は一気に遅くなるというのをC言語で計測した覚えが有ります。
Smartyでのループ処理のforeachとsectionでは、属性が多く細かな設定が可能なsectionよりforeachの方が好ましいようです。
リンク先では、Smartyテンプレートエンジンがテンプレートファイルを解析して作られるキャッシュファイルを比較してます。実際に表示されるのはキャッシュのPHPファイルでしょうから、ソースが増えれば遅くなるでしょう。
は{foreach from=$custid item=curr_id} id: {$curr_id}
{/foreach}に。このあたりから微妙なニュアンスが漂います。<?php $_from = $this->_tpl_vars['custid']; if (!is_array($_from) && !is_object($_from)) { settype($_from, 'array'); }if (count($_from)): foreach ($_from as $this->_tpl_vars['curr_id']): ?> id: <?php echo $this->_tpl_vars['curr_id']; ?> <br> <?php endforeach; endif; unset($_from); ?>
おっかないのがsection。どっちもループだよねぇ、程度に思ってたのですが………甘いも甘いも大甘。が、なんと…{section name=customer loop=$custid} id: {$custid[customer]}<br> {/section}<?php unset($this->_sections['customer']); $this->_sections['customer']['name'] = 'customer'; $this->_sections['customer']['loop'] = is_array($_loop=$this->_tpl_vars['custid']) ? count($_loop) : max(0, (int)$_loop); unset($_loop); $this->_sections['customer']['show'] = true; $this->_sections['customer']['max'] = $this->_sections['customer']['loop']; $this->_sections['customer']['step'] = 1; $this->_sections['customer']['start'] = $this->_sections['customer']['step'] > 0 ? 0 : $this->_sections['customer']['loop']-1; if ($this->_sections['customer']['show']) { $this->_sections['customer']['total'] = $this->_sections['customer']['loop']; if ($this->_sections['customer']['total'] == 0) $this->_sections['customer']['show'] = false; } else $this->_sections['customer']['total'] = 0; if ($this->_sections['customer']['show']): for ($this->_sections['customer']['index'] = $this->_sections['customer']['start'], $this->_sections['customer']['iteration'] = 1; $this->_sections['customer']['iteration'] <= $this->_sections['customer']['total']; $this->_sections['customer']['index'] += $this->_sections['customer']['step'], $this->_sections['customer']['iteration']++): $this->_sections['customer']['rownum'] = $this->_sections['customer']['iteration']; $this->_sections['customer']['index_prev'] = $this->_sections['customer']['index'] - $this->_sections['customer']['step']; $this->_sections['customer']['index_next'] = $this->_sections['customer']['index'] + $this->_sections['customer']['step']; $this->_sections['customer']['first'] = ($this->_sections['customer']['iteration'] == 1); $this->_sections['customer']['last'] = ($this->_sections['customer']['iteration'] == $this->_sections['customer']['total']); ?> id: <?php echo $this->_tpl_vars['custid'][$this->_sections['customer']['index'; ?> <br> <?php endfor; endif; ?>がるの健忘録
細かい設定などが必要ないときはforeachを使った方が良さそうです。
参考
2007年8月3日金曜日
時刻のselect要素が作成できる - {html_select_time}関数
{html_select_time prefix="" field_array="time" time=$smarty.now display_seconds=false minute_interval="30"}
実行例:
prefixは各要素名の接頭辞。デフォルトがTime_なので(各セレクト名はTime_Hour、Time_Minute、Time_Second)付けない様にNULL。
field_arrayを指定する事で、時間要素が連想配列で$_POSTに渡される(例だと$_POST["time"]=Array(["Hour"],["Minute"],["Second"]))。
"秒"と"分"の選択メニューは1~30(秒/分)刻み。
true/falseは"(クウォート)で括ったり大文字で記述する(TRUE/FALSE)とうまくいかない様です。
属性(<html_select_date>との共通)
- prefix
- name属性に負荷する接頭辞[デフォルト:Date_、Tme_]
- time
- デフォルトセットの日付(YYYY-MM-DD形式かUNIXタイムスタンプで指定)[デフォルト:現在の日付・時刻]
- field_array
- 入力値を連想配列としてPHPに渡す
- all_extra
- 全ての<select>タグの属性指定
属性(<html_select_time>の固有)
- display_hours
- 時のプルダウン表示[true/false](デフォルト:true)
- display_minutes
- 分のプルダウン表示[true/false](デフォルト:true)
- display_seconds
- 秒のプルダウン表示[true/false](デフォルト:true)
- display_meridian
- AM/PMの表示[true/false](デフォルト:true)
- use_24_hours
- 24時間表示[true/false](デフォルト:true)
- minute_interval
- 分のプルダウンメニューの間隔[1~30](デフォルト:1分)
- second_interval
- 秒のプルダウンメニューの間隔[1~30](デフォルト:1秒)
- hour_extra
- 時の<select>タグの属性
- minute_extra
- 分の<select>タグの属性
- second_extra
- 秒の<select>タグの属性
- meridian_extra
- AM/PMの<select>タグの属性