![]() |
![]() |
Smarty を使う上で知っておくと便利な小ネタ集です。
ここにあるものはとても便利ですが、でも、ここを読む前に、Smarty - コンパイリング PHP テンプレートエンジンを一読されることを強くおすすめします。
基本的に <{$vars}> のように表記。<{ }> で囲むとsmarty変数処理になる。 PHP定数であれば、<{$smarty.const.MY_CONST_VAL}> のように参照も可能。
変数の値によって処理を変えたい時に利用。
<{if $country eq "JPN"}>
Japan
<{elseif $country eq "USA"}>
United States of Ameria
<{else}>
Welcome
<{/if}>eqは==と同じ。neは!=と同じ。他は>や<=など。
以下の場合だと$linksにassignされた配列で連続処理するので、section内では $link.xxx で参照が可能。
<{section name=i loop=$links}>
<{include file="db:main_link.html" link=$links[i]}>
<{/section}>なお、include fileで別のテンプレート呼び出しも可能。
sectionとほぼ同様。sectionよりもこちらを推奨。
<{foreach item=subcat from=$subcategories}>
<{$subcat.title}>
<{/foreach}><{if $xoops_requesturi == '/index.php' or $xoops_requesturi == '/'}>user.php などを見ているときに判定からはずせます。
※XOOPSをドキュメントルート以外にインストールしている場合(たとえば /html/ など)は,
<{if $xoops_requesturi == '/html/index.php' or $xoops_requesturi == '/html/'}>とする。
また XCL だったら、
<{if ! $legacy_module}>とすると、トップページ判定に近いことができるようです。
ただし、InquirySPモジュールには対応できないようです。
トップページだけでなく、/user.php /userinfo.php /register.php なども含まれます。
<{if $xoops_dirname == false}>.....<{/if}> あるいは <{if !$xoops_dirname}>.....<{/if}>なお、XCL以降はルートコントローラでもXCL必須モジュールが機能を受け持つものがあるため、/user.phpにはuser、/notifications.phpにはlegacy、/viewpmsg.phpにはpmなどとdirnameが付いてしまう物があります。
<{if $xoops_requesturi == '/modules/(modulename)/index.php'}>など。
クエリストリングスを含むときは、&記号を&amp;にすることを忘れずに。
<{if $xoops_modulename == "pico"}>
<{/if}>XCLでは$xoops_modulenameが機能しないので
<{if $legacy_module == "pico"}>
<{/if}>とする。
テンプレート system_userinfo.html (XCL2.1であれば user_userinfo.html) のカスタマイズ(altsysでの編集を推奨)
<{if $xoops_isuser}>
(元の内容)
<{else}>
<p>個人情報保護のため、ログインユーザ以外は閲覧できません</p>
<{/if}>なぜかルートコントローラuserinfo.phpをHackする、なんて方法ばかりが出回っているが、断然こっちの方が優れている。
<{if $xoops_isuser and $xoops_isadmin == false}>
(一般ユーザだけに表示する部分)
<{/if}>使いどころは不明 
所属グループはアサインされていないので、テーマの先頭等で自力でアサインしておく必要がある。
<{php}>
$this->assign( 'xoops_user_groups' , is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getGroups() : array(XOOPS_GROUP_ANONYMOUS) ) ;
<{/php}>これをtheme.htmlの先頭付近に挿入した上で、以下のような判断が利用できる。
<{if in_array(2,$xoops_user_groups)}>
(「登録ユーザ」に所属するユーザだけに表示する部分)
<{/if}>もちろん、上の2が目的とするグループ番号であり、XOOPS初期状態では、「登録ユーザ」に該当する。
<{1|xoops_user:'uname'}>この場合は、ユーザID が 1 のユーザの uname を表示できます。
ただし、このxoops_user modifierプラグインを使えるのは、XCL2.1のみです。X2では利用できません。XCL2.1依存のプラグインであるため、単純にファイルをX2にコピーしても動きません。
これと同様の機能を持つSmartyプラグインとして、modifier.xoops_userinfo.php などがありますが、それらはX2でも動作します。
この関数は繰り返し処理するために使用します。主にtheme.html内で使用します。
使用できる属性名には name values print advance delimiter assign がありますが、XOOPS で使用するのは values です。
<{cycle values="a,b,c"}>の様に記述します。この場合は a b c a b c ... と循環されます。
例えば、 theme.html 内にある左ブロックタイトル部と、左ブロックコンテンツ部を囲っている<div>タグの class へ記述します。
そのクラスを style.css 内でそれぞれ指定。 背景色を赤、青、緑の繰り返しで表示させます。
<td id="leftcolumn">
<{foreach item=block from=$xoops_lblocks}>
<div class="blockTitle_<{cycle values="a,b,c"}>"><{$block.title}></div>
<div class="blockContent_<{cycle values="a,b,c"}>"><{$block.content}></div>
<{/foreach}>
</td>#leftcolumn .blockTitle_a,
#leftcolumn .blockTitle_b,
#leftcolumn .blockTitle_c {
padding:3px 5px;
color:#000000;
font-weight:bold;
}
#leftcolumn .blockTitle_a {
background: #f00;
}
#leftcolumn .blockTitle_b {
background: #00f;
}
#leftcolumn .blockTitle_c {
background: #0f0;
}
#leftcolumn .blockContent_a,
#leftcolumn .blockContent_b,
#leftcolumn .blockContent_c {
padding:5px;
}
#leftcolumn .blockContent_a {
background: #fcc;
}
#leftcolumn .blockContent_b {
background: #ccf;
}
#leftcolumn .blockContent_c {
background: #cfc;
}<{if $xoops_modulename == "tinyd0"}>
<{if $id == 5}>
5
<{elseif $id == 2}>
2
<{else}>
other
<{/if}>
<{/if}>※ TinyD でしか利用できません
<{if 'hoge'|in_array:$category.paths_raw}>
hoge カテゴリにぶら下がるページを表示しているときの処理
<{/if}>※ pico でしか利用できません
date_format(日付のフォーマットを変える)という modifier をつかいます。
<{$story.posttime|date_format:"%Y年%m月%d日"}>小ネタですが,音声環境ではスラッシュ区切りの日付が把握しにくくなっています。たとえば2006/9/1だと「いちぶんのきゅう,にせんろく」と読んだりします。ので,日本語環境だったら,なるべく年月日表記にしたほうがよいです。横文字環境であれば(横文字の場合によって,表記仕方自体ちがう場合もありますが)ハイフンでつなげるといいとおもいます。
さらに余談になりますが、date_formatは、すでにフォーマット済の年月日形式を、いったんUNIXタイムスタンプ形式に戻してから別のフォーマットに変更する修正子です。つまり、最初から年月日でしかアサインされていなければ、そこから時分秒を取り出すのは不可能です。
ある程度設計の新しいモジュールであれば、フォーマット済の年月日形式だけでなく、UNIXタイムスタンプ形式でもアサインしてくれているので、それを利用するのがベストです。
例えばこのような形になります。
<{"Y年n月j日"|date:$content.created_time}>xugj_dateというsmartyプラグインを追加する、という手もあります。
これを使う場合、上の例は以下のように表記できます。
<{$story.posttime|xugj_date:"Y年m月d日"}>xugj_dateであれば、01月の0を消すことも可能で、以下のように表記します。
<{$story.posttime|xugj_date:"Y年n月j日"}>デフォルトだとNewマークが出ますので、それを避けるのであれば、以下のようにしてください。
<{$story.posttime|xugj_date:"Y年n月j日":"":""}>タイムスタンプ形式を利用する場合でもxugj_dateがそのまま利用できます。
<{$content.created_time|xugj_date:"n月j日 H時i分":"最新":"新着":false}>など。
Smartyプラグインxugj_dateを使いましょう。
xugj_dateを XOOPS_ROOT_PATH/class/smarty/plugins/ にコピーした上で、以下のように記述します。
<{$story.posttime|xugj_date:""}>この場合、Newマークだけが表示されます。
テンプレート system_userinfo.html (XCL2.1であれば user_userinfo.html)
<td class="odd"><{$user_email}></td>この部分を見つけて、
<td class="odd"><{$user_email|replace:"@":" at "}></td>と書き換える。
(もうちょっと凝ったパターンの方が良いかも)
以下の
javascriptでわかりづらくする方法もある
smartyのマニュアルより
<{mailto address=$EmailAddress encode="javascript" subject="Hello"}> に問い合わせを送る例:西暦四桁とハイフン(xxxx-)を消す。
<{$topic.time|regex_replace:"/^\d{4}-/":""}>(参考)もうちょっと軽いやり方
<{$topic.time|substr:5}>例2:ボタンの名前を"表示"に変える。
<{$commentsnav|replace:"送信":"表示"}>例:入力画面で[:return:]等と入力後、該当する変数に
<{$title|replace:"[:return:]":"<br />"}>どうしてもテキストボックスで改行したいときがあれば…
通常のtruncateでは英数字でカウントするため、2バイト文字列の場合は途中で切れてしまう場合がありますので、2バイト文字列対応のsmarty plugin「mb_truncate」を利用する方法です。
以下の内容を class/smarty/plugins/modifier.mb_truncate.php として保存します。
<?php
/*
* Smarty plugin
* -------------------------------------------------------------
* Type: modifier
* Name: mb_truncate
* Purpose: Truncate a string to a certain length if necessary,
* optionally splitting in the middle of a word, and
* appending the $etc string.
* -------------------------------------------------------------
*/
function smarty_modifier_mb_truncate($string, $length = 80, $etc = '...', $break_words = false)
{
if ($length == 0)
return '';
if (strlen($string) > $length) {
$length -= strlen($etc);
if (!$break_words)
$string = preg_replace('/\s+?(\S+)?$/', '', mb_strcut($string, 0, $length+1));
return mb_strcut($string, 0, $length).$etc;
} else
return $string;
}
?>
例えばd3pipesの rssprint_block_sync.html であれば
<a href="<{$entry.link|escape}>"><{$entry_headline4disp}></a>の丸めたい部分($entry_headline4disp)に
<a href="<{$entry.link|escape}>"><{$entry_headline4disp|mb_truncate:60}></a>とすれば、60 文字以上ある場合には文字列を丸めて表示します。
参考)xoopscube.jp 旧フォーラム「MyAlbumのcat_listの説明文に関して。」
http://xoopscube.jp/modules/newbb/viewtopic.php?topic_id=4440&forum=17&post_id=23846
<{*
*}>とすることで <{* *}> 内はHTML上へ実際に反映されることはありません。通常の<!-- --> は見た目は表示されませんが、HTML上へは反映されます。
このテンプレートで使われているSmarty変数を知りたい! という時は、テンプレートの最初の行に
<{debug}>と書くと、そのページで利用されている全ての編集がポップアップ・ウィンドウで表示されます。 ※ローカル推奨
変数$photoが
<{$photo.title}>とかで使われていると、$photo変数の他のキーも知りたくなる場合。
<{$photo|var_dump}>で$photo.descriptionとか$photo.createdがあれば、一覧で出ます。無ければあきらめて。;)
…というのは、実はあまり良くないやり方。modifierプラグインの特殊ルール*1のおかげで、肝心の配列インデックスが表示されない。
つまり、ここでの最善の解はこうなる。
<{""|var_dump:$photo}><{$photo|@var_dump}>
<{$photo|@debug_print_var}>というのが解ですね……と重箱の隅をつつくようなことを書きます^^;- suin