讓 Smarty 的 truncate 支援 utf-8
我用 PHP 搭配 Smarty template engine 時
習慣搭配 truncate 或 date_format 等 smarty 內建函數
方便日後設計人員可更改
這樣也可讓邏輯端的程式精簡些
有好一陣子沒用 Smarty 了
最近在翻閱之前的作品參考
突然看到用 utf-8 編碼格式的怎麼突然會有亂碼
先將 Smarty 版本更新到目前最新的 2.6.18
然後清掉 compile 的 cache 檔
情形還是一樣
在網路上搜尋後發現有不少教學文
大多都是自己加個 plugin
然後將呼叫 truncate 的函式改為 truncate_utf8 之類的
以下為這支 plugin:
// http://dev.splitbrain.org/view/darcs/dokuwiki/inc/utf8.php使用方法很簡單
/**
* UTF8 helper functions
*
* @license LGPL (http://www.gnu.org/copyleft/lesser.html)
* @author Andreas Gohr
*/
if(!defined('UTF8_MBSTRING')){
if(function_exists('mb_substr') && !defined('UTF8_NOMBSTRING')){
define('UTF8_MBSTRING',1);
}else{
define('UTF8_MBSTRING',0);
}
}
if(UTF8_MBSTRING){ mb_internal_encoding('UTF-8'); }
function utf8_strlen($string){
return strlen(utf8_decode($string));
}
function utf8_substr($str, $offset, $length = null) {
if(UTF8_MBSTRING){
if( $length === null ){
return mb_substr($str, $offset);
}else{
return mb_substr($str, $offset, $length);
}
}
$str = (string)$str;
$offset = (int)$offset;
if (!is_null($length)) $length = (int)$length;
if ($length === 0) return '';
if ($offset < 0 && $length < 0 && $length < $offset) return '';
$offset_pattern = '';
$length_pattern = '';
if ($offset < 0) {
$strlen = strlen(utf8_decode($str));
$offset = $strlen + $offset;
if ($offset < 0) $offset = 0;
}
if ($offset > 0) {
$Ox = (int)($offset/65535);
$Oy = $offset%65535;
if ($Ox) $offset_pattern = '(?:.{65535}){'.$Ox.'}';
$offset_pattern = '^(?:'.$offset_pattern.'.{'.$Oy.'})';
} else {
$offset_pattern = '^';
}
if (is_null($length)) {
$length_pattern = '(.*)$';
} else {
if (!isset($strlen)) $strlen = strlen(utf8_decode($str));
if ($offset > $strlen) return '';
if ($length > 0) {
$length = min($strlen-$offset, $length);
$Lx = (int)($length/65535);
$Ly = $length%65535;
if ($Lx) $length_pattern = '(?:.{65535}){'.$Lx.'}';
$length_pattern = '('.$length_pattern.'.{'.$Ly.'})';
} else if ($length < 0) {
if ($length < ($offset - $strlen)) return '';
$Lx = (int)((-$length)/65535);
$Ly = (-$length)%65535;
if ($Lx) $length_pattern = '(?:.{65535}){'.$Lx.'}';
$length_pattern = '(.*)(?:'.$length_pattern.'.{'.$Ly.'})$';
}
}
if (!preg_match('#'.$offset_pattern.$length_pattern.'#us',$str,$match)) return '';
return $match[1];
}
function smarty_modifier_truncate_utf8($string, $length = 80, $etc = '...', $break_words = false, $middle = false)
{
if ($length == 0)
{
return '';
}
if(utf8_strlen($string) > $length)
{
$length -= utf8_strlen($etc);
if(! $break_words && ! $middle)
{
$string = preg_replace('/\s+?(\S+)?$/us', '', utf8_substr($string, 0, $length+1));
}
if(! $middle)
{
return utf8_substr($string, 0, $length) . $etc;
}
else
{
return utf8_substr($string, 0, $length / 2) . $etc . utf8_substr($string, -$length / 2);
}
}
else
{
return $string;
}
}
?>
將上面的 code 另存新檔為 modifier.truncate_utf8.php
放至 Smarty-x.x.x/libs/plugins 下
由於 plugins 下已經存在 Smarty 內建的 plugins
如果你怕下次更新 Smarty 會忽略到的話
可自訂一個 plugins 的資料夾如 Smarty-x.x.x/libs/my_plugins
可在程式中加入
$smarty->plugins_dir[] = 'Smarty-x.x.x/libs/my_plugins';
即可
參考來源:
让“Smarty truncate modifier plugin”支持UTF-8
Comments