CSS Selector Generator | CSS のセレクタ一覧を一発で自動生成!

14

06月2007年

Smarty研究(2)マルチバイト文字に対応した truncate 修飾子を作る

kimoto 16:09 PM

  • はてなブックマークに登録
  • livedoorクリップに登録
  • Yahoo!ブックマークに登録
  • deliciousに追加

スマティスト(Smarty を使う人の意)のみなさま、こんにちは。
tanaka の Smarty 研究シリーズがいつまでたっても続いてくれないので勝手にやってみようと思います。

さて、北斗の拳には「息を吸うのも面倒で嫌だ」と言ったらケンシロウに息を吸えなくされてあえなく昇天してしまったゲイラさんというキャラクターがいますが、そいつに負けるとも劣らない程の面倒くさがりな僕こと kimoto です。
通常であれば、ライブラリを独自に拡張などは持ち前の面倒くさがり気質を発揮してやらないのですが、Smarty には「せっかく便利なので日本語が通らない!」とか「せっかく便利なのに IE では意味をなさない!」などのもったいない修飾子や関数が存在します。
そこで、そのあたり、独自に関数を作ったり拡張したりして使っている物を何回かにわたりご紹介していこうと思います。
まずは、文字列を扱う修正子から。

truncate 修正子

truncate は、文字列を指定の文字数までで切ってくれます。切った後につける文字列も指定できるので、
たとえば

$smarty->assign('string', 'abcdefghijklmnopqrstuvwxyz');

として

{$string|truncate:5:"..."}

などとすれば、文字列は 5 つめで切り捨てられ

abcde...

と表示されます。

しかしこの修飾子、文字列判定にはバイト数を使用しており、マルチバイト文字列で使用すると文字化けを起こしてしまう可能性があるのです。
なんだよちくしょー、と Smarty のプラグインディレクトリの中の「modifier.truncate.php」を開いてみたら、単に文字数取得に使われている関数が「strlen」、文字列切り出しの関数に「substr」を利用しているだけの事です。
となれば、ここをマルチバイト対応にすればよいのではないか?
てことで作った修飾子がこちらです。

function smarty_modifier_mb_truncate($string, $length = 80, $etc = '...') {
    if ($length == 0) {return '';}

    if (mb_strlen($string) > $length) {
        return mb_substr($string, 0, $length).$etc;
    } else {
        return $string;
    }
}

文字数を取得する部分には「mb_strlen」を、文字列切り出しには「mb_substr」を利用しています。
日本語には必要ないと思われる第4、第5引数はバッサリカットして見た目もスッキリ。
これを「modifier.mb_truncate.php」という名前で保存し、「smarty/libs/plugins」の中に放り込めば、テンプレート内で

{$string|mb_truncate:5:"..."}

このように使用できます。
ちなみに第4引数は単語で切らないようにする、という機能で、日本語では意味をなしません。
第5引数は…マニュアルにはありませんが、関数を見る限り 文字列を半分にして、真ん中に「...」などを入れる機能のようです。どういう使い方するんだろ。

ということで今回はおそらく結構自前で作ってる人が多そうな mb_truncate の修飾子をご紹介しました
次回はラジオボタンやチェックボックスのラベルのお話をしようと思ってます。

バシャログスタッフによるWebサイト制作サービス

トラックバック

このエントリーのトラックバックURL
http://c-brains.jp/cgi-bin/mt/###/1144
###はmt-tb.cgiに変更してください。

コメント

早速参考にさせていただきました。
ありがとうございます。
私の環境ではそのまま使えず、文字コードを第3引数で指定できるようにして使っています。

function smarty_modifier_mb_truncate($string, $length = 80, $etc = '...', $encoding = '') {
if ($length == 0) {return '';}

if (mb_strlen($string,$encoding) > $length) {
return mb_substr($string, 0, $length,$encoding).$etc;
} else {
return $string;
}
}

テンプレート側
{$datum.title|mb_truncate:24:'...':'utf8'}

bugspray さま

コメントありがとうございます。
確かに、環境によってはうまく動かないので、明示的に指定してあげる方が親切ですね!
補足、ありがとうございました。

コメントを投稿

ページの先頭へ

POPULAR TAGS
  • バシャログスタッフによるWebサイト制作サービス

ARCHIVE

特集

RECENT COMMENTS

ishida on CSS Nite in Ginza, Vol.49「バシャログ LIVE」 で紹介したDreamweaverの正規表現クエリーを公開します
>市川さん コメントありがとうございます。 前提条件の部分
ichikawa on 1.2.3で整えるPHP開発環境【STEP.1】 XAMPPをインストール
いつもバシャログ。をご覧いただきありがとうございます。 >
市川 on CSS Nite in Ginza, Vol.49「バシャログ LIVE」 で紹介したDreamweaverの正規表現クエリーを公開します
どういう前提での使用例なのか、わかりませんが、 タグを明示的
studio-8ch on 1.2.3で整えるPHP開発環境【STEP.1】 XAMPPをインストール
いつも記事を大変興味深く、拝見いたしております。 是非、A
sakai on [使える CSS テクニック] CSSで実現するプルダウンメニュー
>とらのすけさん コメントありがとうございます。 CSS