LOGIN ID Password Auto Login Register Now! Lost Password?
XUGJ Wiki

はじめに anchor.png

Smarty を使う上で知っておくと便利な小ネタ集です。
ここにあるものはとても便利ですが、でも、ここを読む前に、Smarty - コンパイリング PHP テンプレートエンジンを一読されることを強くおすすめします。

Page Top

コンテンツ一覧 anchor.png

ページ内コンテンツ
Page Top

基本的な文法 anchor.png

Page Top

変数 anchor.png

基本的に <{$vars}> のように表記。<{ }> で囲むとsmarty変数処理になる。 PHP定数であれば、<{$smarty.const.MY_CONST_VAL}> のように参照も可能。

Page Top

条件分岐 if/elseif/else文 anchor.png

変数の値によって処理を変えたい時に利用。

<{if $country eq "JPN"}>
	Japan
<{elseif $country eq "USA"}>
	United States of Ameria
<{else}>
	Welcome
<{/if}>

eqは==と同じ。neは!=と同じ。他は>や<=など。

Page Top

ループ処理(section) anchor.png

以下の場合だと$linksにassignされた配列で連続処理するので、section内では $link.xxx で参照が可能。

     <{section name=i loop=$links}>
       <{include file="db:main_link.html" link=$links[i]}>
     <{/section}>

なお、include fileで別のテンプレート呼び出しも可能。

Page Top

ループ処理(foreatch) anchor.png

sectionとほぼ同様。sectionよりもこちらを推奨。

<{foreach item=subcat from=$subcategories}>
<{$subcat.title}>
<{/foreach}>
Page Top

現在のページ・モジュールを知る方法 anchor.png

主にテーマ(theme.html)で利用します。

Page Top

トップページかどうか? anchor.png

<{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モジュールには対応できないようです。 また、 カスタムブロックで{xoopsform}関連をphpコードで書いて表示すると、トップページでも{legacy_module}に legacy の値が入ります。

XCLでも上記の例の$xoops_requesturiを使用した判定をするかですが /html/の部分がサイトにより異なるので、配布テーマとかには使えません。
XCLの場合、SCRIPT_FILENAMEをLegacy_Controllerも出来るだけセットしてくれるようなので、
案としては、同じ判定を

<{if $smarty.server.SCRIPT_FILENAME|basename == "index.php" and $smarty.server.SCRIPT_FILENAME|dirname|basename == $smarty.const.XOOPS_ROOT_PATH|basename}>

とすれば、サイト深さにかかわらず判定出来そうですが、どうでしょうね。

Page Top

ルートコントローラかどうか? anchor.png

トップページだけでなく、/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が付いてしまう物があります。

Page Top

特定のページかどうか? anchor.png

<{if $xoops_requesturi == '/modules/(modulename)/index.php'}>

など。
クエリストリングスを含むときは、&記号を&amp;にすることを忘れずに。

Page Top

ある特定のモジュールだけの処理 anchor.png

<{if $xoops_modulename == "pico"}>
<{/if}>

XCLでは$xoops_modulenameが機能しないので

<{if $legacy_module == "pico"}>
<{/if}>

とする。

Page Top

閲覧者が誰であるかを知る方法 anchor.png

テーマでもテンプレートでも利用される、ほぼ必須のテクニックです。

Page Top

管理者かどうか? anchor.png

<{if $xoops_isadmin}>
  (管理者だけに表示する部分)
<{/if}>
Page Top

ログインしている時のみ表示 anchor.png

<{if $xoops_isuser}>
  (ログインユーザだけに表示する部分)
<{/if}>
Page Top

ログインユーザ以外にユーザ情報を見せない(応用1) anchor.png

テンプレート system_userinfo.html (XCL2.1であれば user_userinfo.html) のカスタマイズ(altsysでの編集を推奨)

<{if $xoops_isuser}>
  (元の内容)
<{else}>
  <p>個人情報保護のため、ログインユーザ以外は閲覧できません</p>
<{/if}>

なぜかルートコントローラuserinfo.phpをHackする、なんて方法ばかりが出回っているが、断然こっちの方が優れている。

Page Top

一般ユーザ(管理者でもゲストでもないユーザ)のみ表示 anchor.png

<{if $xoops_isuser and $xoops_isadmin == false}>
  (一般ユーザだけに表示する部分)
<{/if}>

使いどころは不明 :-D

Page Top

ゲストにのみ表示 anchor.png

<{if ! $xoops_isuser}>
  (ゲストだけに表示する部分)
<{/if}>
Page Top

特定のユーザにのみ表示 anchor.png

<{if $xoops_uname == humptyDumpty}>
  (ユーザ名humptyDumptyだけに表示する部分)
<{/if}>
Page Top

特定のグループにのみ表示 anchor.png

所属グループはアサインされていないので、テーマの先頭等で自力でアサインしておく必要がある。

<{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初期状態では、「登録ユーザ」に該当する。

Page Top

ユーザIDから得られる様々な情報 anchor.png

<{1|xoops_user:'uname'}>

この場合は、ユーザID が 1 のユーザの uname を表示できます。
この他に

<{1|xoops_user:'name'}>

<{if 1|xoops_user:'user_viewemail' == 1 || $xoops_isadmin == true }>
  <{mailto address=1|xoops_user:'email' encode="javascript"}>
<{/if}>

<{1|xoops_user:'url'}>
<{1|xoops_user:'user_sig'}>

  PMボタン

      <{if $xoops_isuser == true }>
           <a href="<{$xoops_url}>/modules/message/index.php?action=new&amp;to_userid=1">
           <img src="<{$smarty.const.XOOPS_URL}>/images/icons/pm.gif" alt="<{1|xoops_user:'uname'}>さんにプライベートメッセージを送る。" title="<{1|xoops_user:'uname'}>さんにプライベートメッセージを送る。" /></a>
     <{/if}>

ただし、このxoops_user modifierプラグインを使えるのは、XCL2.1.XCL2.2のみです。X2では利用できません。XCL2.1,XCL2.2依存のプラグインであるため、単純にファイルをX2にコピーしても動きません。

これと同様の機能を持つSmartyプラグインとして、modifier.xoops_userinfo.php などがありますが、それらはX2でも動作します。  

Page Top

XCL2.2ではプロファイルデータも取得出来ます anchor.png

<{1|xoops_user:$key}>

と思ったら、エラーになりますね(XCL2.2ではバグで動かないです)

Page Top

ユーザーアバターの表示 anchor.png

ユーザID が 1 のユーザーの場合

Page Top

XCL2,1では anchor.png

<img title="Avatar" alt="Avatar" src="<1|xoops_user_avatarize}>">
Page Top

XCl2,2では、第1引数:uid ,第2引数:true=HTMLタグ付き ,第3引数:アバターをクリックしたときのリンク先url anchor.png

 function smarty_modifier_xoops_user_avatarize($uid, $tag=false, $url=null)

  • 第1引数:uidのみ指定
    <img src="<1|xoops_user_avatarize}>" title="Avatar" alt="Avatar" >
  • 第2引数:true=HTMLタグ付きの出力
    <{1|xoops_user_avatarize:true}>
    これの出力は次の様なものになります
    <img src="アバターのurl" width="幅" height="高さ" alt="ユーザー名" >
    ただし、アバターが未登録のとき幅,高さが0になる?(バグなのでは)
    
  • 第2引数:true 第3引数:アバターをクリックしたときのリンク先urlの例
    <{1|xoops_user_avatarize:true:"`$xoops_url`/userinfo.php?uid=1"}>
Page Top

Cycle 関数によるカスタマイズ Tips anchor.png

この関数は繰り返し処理するために使用します。主にtheme.html内で使用します。
使用できる属性名には name values print advance delimiter assign がありますが、XOOPS で使用するのは values です。
<{cycle values="a,b,c"}>の様に記述します。この場合は a b c a b c ... と循環されます。

Page Top

theme.html 内で記述し style.css で利用する anchor.png

例えば、 theme.html 内にある左ブロックタイトル部と、左ブロックコンテンツ部を囲っている<div>タグの class へ記述します。
そのクラスを style.css 内でそれぞれ指定。 背景色を赤、青、緑の繰り返しで表示させます。

Page Top

theme.html 記述例 anchor.png

<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>
Page Top

style.css 記述例 anchor.png

#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;
}
Page Top

特定モジュール用テクニック anchor.png

他のモジュールには利用できない点に要注意。

Page Top

TinyD モジュールの id (コンテンツ番号)を取得 anchor.png

<{if $xoops_modulename == "tinyd0"}>
	<{if $id == 5}>
	5
	<{elseif $id == 2}>
	2
	<{else}>
	other
	<{/if}>
<{/if}>

※ TinyD でしか利用できません

Page Top

pico のテンプレートで親カテゴリごとに処理を分ける anchor.png

<{if 'hoge'|in_array:$category.paths_raw}>
hoge カテゴリにぶら下がるページを表示しているときの処理
<{/if}>

※ pico でしか利用できません

Page Top

数値の表記 anchor.png

Page Top

カンマ区切りで表示する方法 anchor.png

<{$value|number_format}>
Page Top

カンマ区切りで、小数2位まで表示する方法 anchor.png

<{$value|number_format:2}>
Page Top

日付の表記 anchor.png

Page Top

「○年○月○日」と表示する方法1 anchor.png

date_format(日付のフォーマットを変える)という modifier をつかいます。

<{$story.posttime|date_format:"%Y年%m月%d日"}>

小ネタですが,音声環境ではスラッシュ区切りの日付が把握しにくくなっています。たとえば2006/9/1だと「いちぶんのきゅう,にせんろく」と読んだりします。ので,日本語環境だったら,なるべく年月日表記にしたほうがよいです。横文字環境であれば(横文字の場合によって,表記仕方自体ちがう場合もありますが)ハイフンでつなげるといいとおもいます。

さらに余談になりますが、date_formatは、すでにフォーマット済の年月日形式を、いったんUNIXタイムスタンプ形式に戻してから別のフォーマットに変更する修正子です。つまり、最初から年月日でしかアサインされていなければ、そこから時分秒を取り出すのは不可能です。

ある程度設計の新しいモジュールであれば、フォーマット済の年月日形式だけでなく、UNIXタイムスタンプ形式でもアサインしてくれているので、それを利用するのがベストです。
例えばこのような形になります。

<{"Y年n月j日"|date:$content.created_time}>
Page Top

「○年○月○日」と表示する方法2 anchor.png

xugj_dateというsmartyプラグインを追加する、という手もあります。

xugj_date

これを使う場合、上の例は以下のように表記できます。

<{$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}>

など。

Page Top

新着に new 表示をする anchor.png

Smartyプラグインxugj_dateを使いましょう。

xugj_date

xugj_dateを XOOPS_ROOT_PATH/class/smarty/plugins/ にコピーした上で、以下のように記述します。

<{$story.posttime|xugj_date:""}>

この場合、Newマークだけが表示されます。

Page Top

文字列処理 anchor.png

Page Top

メールアドレス収集bot対策 anchor.png

テンプレート 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"}> に問い合わせを送る
Page Top

大文字にする(index⇒INDEX) anchor.png

<meta name="robots" content="<{$xoops_meta_robots|upper}>" />
Page Top

文字列の置き換え anchor.png

例:西暦四桁とハイフン(xxxx-)を消す。

<{$topic.time|regex_replace:"/^\d{4}-/":""}>

(参考)もうちょっと軽いやり方

<{$topic.time|substr:5}>

例2:ボタンの名前を"表示"に変える。

<{$commentsnav|replace:"送信":"表示"}>
Page Top

テキストボックスに改行を入力 anchor.png

例:入力画面で[:return:]等と入力後、該当する変数に

<{$title|replace:"[:return:]":"<br />"}>

どうしてもテキストボックスで改行したいときがあれば…

Page Top

日本語文字列を丸めたい(mb_truncate) anchor.png

通常の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

Page Top

その他特殊テクニック anchor.png

Page Top

表示されないコメントアウト anchor.png

<{*
  
*}>

とすることで <{* *}> 内はHTML上へ実際に反映されることはありません。通常の<!-- --> は見た目は表示されませんが、HTML上へは反映されます。

Page Top

部分的にsmartyデバグモード anchor.png

このテンプレートで使われているSmarty変数を知りたい! という時は、テンプレートの最初の行に

<{debug}>

と書くと、そのページで利用されている全ての編集がポップアップ・ウィンドウで表示されます。 ※ローカル推奨

Page Top

配列変数が何を持っているのか知りたい anchor.png

変数$photoが

<{$photo.title}>

とかで使われていると、$photo変数の他のキーも知りたくなる場合。

<{$photo|var_dump}>

で$photo.descriptionとか$photo.createdがあれば、一覧で出ます。無ければあきらめて。;)

…というのは、実はあまり良くないやり方。modifierプラグインの特殊ルール*1のおかげで、肝心の配列インデックスが表示されない。
つまり、ここでの最善の解はこうなる。

<{""|var_dump:$photo}>
<{$photo|@var_dump}>
<{$photo|@debug_print_var}>

というのが解ですね……と重箱の隅をつつくようなことを書きます^^;- suin

Page Top

smarty変数の内容による処理分け anchor.png

たとえば system_block_siteinfo.html (XCL2.1では legacy_block_siteinfo.html) などで、アバター画像のファイル名として blank.gif が渡されているときは、この部分を表示しない……というような場合。

<{if ! strstr($user.avatar,"blank.gif")}>
  <img src="<{$user.avatar}>" alt="" width="32" />
<{/if}>

*1 配列をmodifierに渡すとforeach展開されて値だけがmodifierに渡されてしまう

トップ   凍結 差分 バックアップ 複製 名前変更 リロード印刷に適した表示   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom Powered by xpWiki
Counter: 62522, today: 1, yesterday: 2
初版日時: 2007-01-27 (土) 00:17:05
最終更新: 2014-01-13 (月) 22:06:02 (JST) (1103d) by jidaikobo
Back to Page Top
MainMenu
Manuals
Search
XOOPS Official & Dev.
XOOPS Communities