Smarty Установить окончание слова по числу
Мне часто требуется просклонять слово по числам:
0 слонов, 1 слон, 2 слона
Или слово страницы, очень часто требуется.
На смарти (но переделать в php проще простого) добавила функцию.
<?php
/**
* Преобразование слов в зависимоси от числа
* Например: преобразование слова комментарий
* 0 комментариев, 1 комментарий, 2 комментария
*
* По наблюдениям всегда различны лишь 3 окончания ($n0, $n1, $n2).
* Для верного вывода стот только проанализировать число ($num) как сроку, его окончание из 2х символов
* 0 => $n0
* 1 != 11 => $n1
* 1 == 11 => $n0
* 2-4 != 12..14 => $n2
* 2-4 == 12..14 => $n0
* 5 => $n0
*
* @created 11.08.11
*
* @author olgatcpip
* @contact olgatcpip@ya.ru
*/
function smarty_function_wordnum($params, $template)
{
$num = 0; //число слова
$root = ''; //корень слова
$n0 = $n1= $n2 = ''; //окончания
foreach($params as $_key => $_val)
{
switch ($_key)
{
case 'num':
$num = (int)$_val;
break;
case 'root':
$root = $_val;
break;
case 'n0':
$n0 = $_val;
break;
case 'n1':
$n1 = $_val;
break;
case 'n2':
$n2 = $_val;
break;
default:
return 'Error smarty_function_doc_tree: empty params!';
}
}
if(!isset($root))
{
Return 'Error: smarty_function_wordnum: root params required!';
}
$numend = substr($num,-1);
$word = '';
switch($numend)
{
case '0':
$word = $root.$n0;
break;
case '1':
if(substr($num,-2)!='11')
$word = $root.$n1;
else
$word = $root.$n0;
break;
case '2':
case '3':
case '4':
if(substr($num,-2) == '1'.(int)$numend)
$word = $root.$n0;
else
$word = $root.$n2;
break;
default:
$word = $root.$n0;
}
return $word;
}
?>
0 слонов, 1 слон, 2 слона
Или слово страницы, очень часто требуется.
На смарти (но переделать в php проще простого) добавила функцию.
<?php
/**
* Преобразование слов в зависимоси от числа
* Например: преобразование слова комментарий
* 0 комментариев, 1 комментарий, 2 комментария
*
* По наблюдениям всегда различны лишь 3 окончания ($n0, $n1, $n2).
* Для верного вывода стот только проанализировать число ($num) как сроку, его окончание из 2х символов
* 0 => $n0
* 1 != 11 => $n1
* 1 == 11 => $n0
* 2-4 != 12..14 => $n2
* 2-4 == 12..14 => $n0
* 5 => $n0
*
* @created 11.08.11
*
* @author olgatcpip
* @contact olgatcpip@ya.ru
*/
function smarty_function_wordnum($params, $template)
{
$num = 0; //число слова
$root = ''; //корень слова
$n0 = $n1= $n2 = ''; //окончания
foreach($params as $_key => $_val)
{
switch ($_key)
{
case 'num':
$num = (int)$_val;
break;
case 'root':
$root = $_val;
break;
case 'n0':
$n0 = $_val;
break;
case 'n1':
$n1 = $_val;
break;
case 'n2':
$n2 = $_val;
break;
default:
return 'Error smarty_function_doc_tree: empty params!';
}
}
if(!isset($root))
{
Return 'Error: smarty_function_wordnum: root params required!';
}
$numend = substr($num,-1);
$word = '';
switch($numend)
{
case '0':
$word = $root.$n0;
break;
case '1':
if(substr($num,-2)!='11')
$word = $root.$n1;
else
$word = $root.$n0;
break;
case '2':
case '3':
case '4':
if(substr($num,-2) == '1'.(int)$numend)
$word = $root.$n0;
else
$word = $root.$n2;
break;
default:
$word = $root.$n0;
}
return $word;
}
?>
Пример выполнения
0 >>>> {wordnum num=0 root="страниц" n0="" n1="а" n2="ы"}<br/>
1 >>>> {wordnum num=1 root="страниц" n0="" n1="а" n2="ы"}<br/>
2 >>>> {wordnum num=2 root="страниц" n0="" n1="а" n2="ы"}<br/>
5 >>>> {wordnum num=5 root="страниц" n0="" n1="а" n2="ы"}<br/>
10 >>>> {wordnum num=10 root="страниц" n0="" n1="а" n2="ы"}<br/>
11 >>>> {wordnum num=11 root="страниц" n0="" n1="а" n2="ы"}<br/>
12 >>>> {wordnum num=12 root="страниц" n0="" n1="а" n2="ы"}<br/>
20 >>>> {wordnum num=20 root="страниц" n0="" n1="а" n2="ы"}<br/>
21 >>>> {wordnum num=21 root="страниц" n0="" n1="а" n2="ы"}<br/>
23 >>>> {wordnum num=23 root="страниц" n0="" n1="а" n2="ы"}<br/>
25 >>>> {wordnum num=25 root="страниц" n0="" n1="а" n2="ы"}<br/>
125 >>>> {wordnum num=125 root="страниц" n0="" n1="а" n2="ы"}<br/>
101 >>>> {wordnum num=101 root="страниц" n0="" n1="а" n2="ы"}<br/>
111 >>>> {wordnum num=111 root="страниц" n0="" n1="а" n2="ы"}<br/>
Результат будет таким
0 >>>> страниц
1 >>>> страница
2 >>>> страницы
5 >>>> страниц
10 >>>> страниц
11 >>>> страниц
12 >>>> страниц
20 >>>> страниц
21 >>>> страница
23 >>>> страницы
25 >>>> страниц
125 >>>> страниц
101 >>>> страница
111 >>>> страниц
1 >>>> страница
2 >>>> страницы
5 >>>> страниц
10 >>>> страниц
11 >>>> страниц
12 >>>> страниц
20 >>>> страниц
21 >>>> страница
23 >>>> страницы
25 >>>> страниц
125 >>>> страниц
101 >>>> страница
111 >>>> страниц
ЕСЛИ ОБНАРУЖИТЕ ОШИБКУ, ПРОШУ СООБЩИТЬ.
Как-то сложно оно у вас
ОтветитьУдалить/**
* For the formation of endings of words.
*
* @param int $value number.
* @param string $word0 word in the singular.
* @param string $word1 word in the plural (2, 3).
* @param string $word2 word in the plural.
* @param string $separator separator, default ' '.
* @return string formed words
* @access private.
*/
private function morph($value, $word0, $word1, $word2, $separator = ' ')
{
if (preg_match('/1\d$/', $value))
{
return $value . $separator . $word2;
} elseif (preg_match('/1$/', $value))
{
return $value . $separator . $word0;
} elseif (preg_match('/(2|3|4)$/', $value))
{
return $value . $separator . $word1;
} else
{
return $value . $separator . $word2;
}
}
Надо потестить. Как правило регулярки в php5 медленнее работают чем такие (как у меня) извращения.
ОтветитьУдалитьНо ваш вариант куда короче и приятней выглядит. :)
спасибо большое коллега! все работает чики-пуки ))))
ОтветитьУдалить