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

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

スマティスト(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 の修飾子をご紹介しました
次回はラジオボタンやチェックボックスのラベルのお話をしようと思ってます。

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ