2011年09月10日
by fkit
コメントは受け付けていません。
Smarty3のtruncate修飾子がマルチバイト対応になりました。
Googleで「smarty truncate マルチバイト」で検索すると結構な数の「自前でマルチバイト対応のtruncate修飾子を作りました」ってサイトがヒットするので、みんなが待ち望んだ改善ですね。
でもね、ただちょっと、そのままだと微妙に使いづらいんですよ。
結論から言うと、3番目のパラメタ「切り捨てを単語の境界で行うか(FALSE)、厳密なキャラクタ数で行うか(TRUE)」に必ず「TRUE」をセットしないと結果がおかしくなる場合があります。
以下、実行例です。20文字で切り捨ててみます
[smartyの定義]
{$str='OS X Lionは Eメールにまったく新しい方法を採用しました。'}
{$str} //オリジナル<br>
{$str|truncate:20} //境界指定を省略<br>
{$str|truncate:20:'...':true} //境界をTRUE<br>
[実行結果]
Lionは Eメールにまったく新しい方法を採用しました。 //オリジナル
OS X Lionは... //境界指定を省略
OS X Lionは Eメールにま... //境界をTRUE
オリジナル文章の”Eメール”の前に半角のスペースが入ってます。
境界指定がfalseだとココで切り捨ててしまいます。
英語だと単語境界で切り捨てるのが便利なんでしょうが、日本語だと残念な事になります。
対応方法としては
a){$str|truncate:20:’…’:true}と面倒でも書く
b)Smarty/plugins/modifier.truncate.phpを修正してデフォルトをTRUEにする
c)自前のマルチバイト対応truncate修飾子を作る
ぐらいでしょうか?
a)は面倒くさいし、b)は後々問題になりそうだし。
そういう事で、私はC)の自前マルチバイトtruncate修飾子を作る事にしました。
結局、Smarty2と同じになっちゃいました。(笑)
こういう場合のために、Smartyのインスタンス生成時に
Smarty->Lang = 'Japan';
とかできればいいんですけどね。
一応、SYS238版のマルチバイトtruncate修飾子を載せておきます。
[modifier.s238_mb_truncate.php]
<php
/**
* 文字の切り捨て
* Type: modifier
* Name: s238_mb_truncate
* @param string $string 文字列
* @param integer $length 切り捨て長
* @param string $etc 付加文字
* @param string $encoding エンコーディング
* @return string
*/
function smarty_modifier_s238_mb_truncate($string, $length=80, $etc='...', $encoding='UTF-8'){
if($length == 0) return '';
if(mb_strlen($string, $encoding) > $length){
$length -= mb_strlen($etc, $encoding);
return mb_substr($string, 0, $length, $encoding).$etc;
}else{
return $string;
}
}