Foren / National / Russian / Зоопарк с окончаниями

ErsteVorherige12345NächsteLetzte

Ratibor
#16 9. Februar 2009, 05:05
Надо наконец-то поставить точку с этим безобразием,
добавил в functions.php эту функцию.

Окончательный вариант выглядит так:

// Функция предназначена для вывода численных результатов с учетом
// склонения слов, например: "1 ответ", "2 ответа", "13 ответов" и т.д.
//
// $digit — целое число 
// можно вместе с форматированием, например "<b>6</b>"
// 
// $expr — массив, например: array("ответ", "ответа", "ответов").
// можно указывать только первые 2 элемента, например для склонения английских слов
// (в таком случае первый элемент - единственное число, второй - множественное)
// 
// $onlyword - если true, то выводит только слово, без числа
// необязательный параметр

function declension($digit,$expr,$onlyword=false)
{
    if(is_array($expr))
    {
            if(empty($expr[2])) $expr[2]=$expr[1];
            $i=preg_replace('/[^0-9]+/s','',$digit)%100; //intval не всегда корректно работает
            if($onlyword) $digit='';
            if($i>=5 && $i<=20) $res=$digit.' '.$expr[2];
            else
            {
                    $i%=10;
                    if($i==1) $res=$digit.' '.$expr[0];
                    elseif($i>=2 && $i<=4) $res=$digit.' '.$expr[1];
                    else $res=$digit.' '.$expr[2];
            }
    }
    else
    {
    $res = $digit.' '.$expr;
    }
 
        return trim($res);
}


Использование (на примере плагина search):

Пример русского ланг файла:
$L['plu_match'] = array('совпадение','совпадения','совпадений');
Примечание: нужно вписывать 3 значения: первое равно 1, второе рабно 2, третье равно 5. (1 совпадение, 2 совпадения, 5 совпадений)

Пример английского ланг файла:
$L['plu_match'] = array('match','matches');
Примечание: нужно вписывать 2 значения: первое единственное число, второе множественное.

В самом плагине было:
$plugin_body .= "<h4>".$L['Pages']." : ".$L['plu_found']." ".$items." ".$L['plu_match']."</h4>";
заменить на:
$plugin_body .= "<h4>".$L['Pages']." : ".$L['plu_found']." ".declension($items,$L['plu_match'])."</h4>";
Не задавай глупых вопросов, не услышишь вранья.
dervan
#17 9. Februar 2009, 05:43
Можно саму функцищу declension() поместить в lang-файл. А в common.php после вставки lang-файла сделать проверку - если функцища declension() не определена, то определять пустышку, которая не меняет окончания (это для тех языков, для которых не нужна такая функцища).
Ratibor
#18 9. Februar 2009, 05:46
# dervan : (это для тех языков, для которых не нужна такая функцища).
Смотри саму функцию :-)
Если какому то языку не нужна эта функция, то просто не нужно трогать лангфайл,
т.е. все остается как раньше:
$L['plu_match'] = "match(es)";
Не задавай глупых вопросов, не услышишь вранья.
dervan
#19 9. Februar 2009, 05:57
Ага, я смотрел. :) Но ещё можно предположить, что ветка if(is_array($expr)) для каких-то языков не будет работать, и придётся эту централизованную функцищу время от времени доделывать-переделывать. А если она в lang-файле, тогда с этим проще: для вот этого языка реализовали, а для другого языка - это уже другая песня.
Ratibor
#20 9. Februar 2009, 06:06
# dervan : Ага, я смотрел. :) Но ещё можно предположить, что ветка if(is_array($expr)) для каких-то языков не будет работать,
Видно не смотрел :-)
Функция ни как не связана с языком.
Если в ланг файле есть array, она используется, если нет, то на нет и суда нет.
Сейчас для русского и английского языков можно использовать склонения,
а также для языков использующих эти же правила, для других языков ничего не изменилось.

# dervan : и придётся эту централизованную функцищу время от времени доделывать-переделывать.
А мы вообще тут чем занимаемся ?
Если ктото доработает эту функцию для других языков у которых есть четкие правила склонения и эти правила не вписываются в русско-английский вариант, хорошо, не доработают, так и останется в других язаках все по ставрому, т.е. одно слово на все склонения.

А плодить дубли одной и той же функции - это зло.
Не задавай глупых вопросов, не услышишь вранья.

Dieser Beitrag wurde von Ratibor (am 9. Februar 2009, 06:20, vor 15 Jahre) bearbeitet
dervan
#21 9. Februar 2009, 06:22
# Ratibor : Видно не смотрел :-)
Не веришь - не надо. :)

# Ratibor : Если ктото доработает эту функцию для других языков у которых есть четкие правила склонения и эти правила не вписываются в русско-английский вариант, хорошо, ...
Хорошо, но только если не будет сильного разрастания кода этой функцищи при её адаптации под другие языки.
Ratibor
#22 9. Februar 2009, 06:29
# dervan : Хорошо, но только если не будет сильного разрастания кода этой функцищи при её адаптации под другие языки.
А ты думаешь ктото будет ее дорабатывать под другие языки ? :-)
Посмотри на дату первого поста, даже при готовой функции никто не чесался пол года :-)
Разве что теперь других жаба задавит, у русских и англоговорящих все склоняется правильно, а у них нет :)

P.S. Кто еще знает какие языки с четкими правилами склонения, не подходящие к данным правилам ? А также языки подходящие к данным правилам ?
Не задавай глупых вопросов, не услышишь вранья.
esclkm
#23 9. Februar 2009, 06:37
буду предателем, но согласен с дерваном ! я не уверен что в турецком теже правила склонения! да и в немецкрм тоже там свои заморочки, в общем наверное само то, чтобы эта функция имела свои пропростки как в ленг файлах, так и в файле функций. то есть правила склонения там, а это тут.или все только в ленг файле, но функция имеет стандартные входные и выходные параметры.
littledev.ru - мой маленький зарождающийся блог о котонти.
снижение стоимости программирования и снижение стоимости производства разные вещи. Первое можно скорее сравнить с раздачей работникам дешевых инструментов, чем со снижением зарплаты
dervan
#24 9. Februar 2009, 06:39
Исходил из предположения, что дорабатывать будут. А что будет в действительности - откуда мне знать?

esclkm, а я чур буду Сусаниным. :)

Dieser Beitrag wurde von dervan (am 9. Februar 2009, 06:41, vor 15 Jahre) bearbeitet
Dayver
#25 9. Februar 2009, 06:51
Неее, в ленг файлы по умолчанию сунуть функции считаю категорически не правильным
Просто нуно функцию дорабатотать так (функции пагинации Трастмастер апгрейдил именно так):
/**
 * Function is intended for output of numerical results with the registration
 * declinations of words, for example: "1 answer", "2 answers" etc.
 */

function declension($digit,$expr,$onlyword=false)
{

	if(function_exists('declension_custom'))
	{
		// For custom declension functions in plugins or leng file
		return declension_custom($digit,$expr,$onlyword=false);
	}

    if(is_array($expr))
    {
            if(empty($expr[2])) $expr[2]=$expr[1];
            $i=preg_replace('/[^0-9]+/s','',$digit)%100;
            if($onlyword) $digit='';
            if($i>=5 && $i<=20) $res=$digit.' '.$expr[2];
            else
            {
                    $i%=10;
                    if($i==1) $res=$digit.' '.$expr[0];
                    elseif($i>=2 && $i<=4) $res=$digit.' '.$expr[1];
                    else $res=$digit.' '.$expr[2];
            }
    }
    else
    {
    $res = $digit.' '.$expr;
    }
 
        return trim($res);
}

Отличие в этом
....
	if(function_exists('declension_custom'))
	{
		// For custom declension functions in plugins or leng file
		return declension_custom($digit,$expr,$onlyword=false);
	}
....

И тогда саму функцию перерабатывать не придется и всем будет хорошо
Pavlo Tkachenko aka Dayver
dervan
#26 9. Februar 2009, 07:06
# Dayver : Неее, в ленг файлы по умолчанию сунуть функции считаю категорически не правильным

А такое по умолчанию и не предлагалось. По умолчанию предлагалось в common.php определять функцищу-заглушку declension() после вставки lang-файла, если в lang-файле не была определена declension() для этого языка. Т.е. примерно так:
require_once($mlang);
if (!function_exists('declension'))
{
	function declension($digit, $expr, $onlyword = false)
	{
		return "$digit $expr";
	}
}
Ratibor
#27 9. Februar 2009, 07:15
В общем сам себе отвечаю :-)

Языки не имеющие числительных склонений:
Japanese, Korean, Vietnamese, Turkish

Языки полностью подходящие к английским правилам:
Danish, Dutch, English, Faroese, German, Norwegian, Swedish, Estonian, Finnish, Greek, Hebrew, Italian, Portuguese, Spanish, Esperanto, Hungarian

а также вроде:
French, Brazilian Portuguese

Языки полностью подходящие к русским правилам:
Croatian, Serbian, Russian, Ukrainian


Вот остались какие языки, не входящие в эти правила(полностью или частично):

Latvian
Gaeilge (Irish)
Romanian
Lithuanian
Slovak, Czech
Polish
Slovenian


В общем вот:
http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms
http://translate.sourceforge.net/wiki/l10n/pluralforms
Не задавай глупых вопросов, не услышишь вранья.

Dieser Beitrag wurde von Ratibor (am 9. Februar 2009, 07:38, vor 15 Jahre) bearbeitet
Sergey
#28 9. Februar 2009, 07:22
Вы наверное будете смеяться, но такую функцию по назначению, я еще в LDU предлагал:
function numwords($mydigit,$lang,$word)
        {
        if (empty($word)) {return;}
        $ew=explode(",",$word);
        $mydigit=abs((int)$mydigit);
        switch($lang)
              {
         case "ru":
                  {
                  while($mydigit>20) {$mydigit=$mydigit%10;}
                  if($mydigit == 0) {return ($ew[0].$ew[1]);}
                  if($mydigit == 1) {return ($ew[0].$ew[2]);}
                  if($mydigit >= 2 && $mydigit <= 4 )  {return ($ew[0].$ew[3]);}
                  if($mydigit >= 5 && $mydigit <= 20 ) {return ($ew[0].$ew[4]);}
                  }
         case "uk":
                  {
                  if($mydigit == 0) {return ($ew[0].$ew[1]);}
                  if($mydigit == 1) {return ($ew[0].$ew[2]);}
                  if($mydigit >1)   {return ($ew[0].$ew[3]);}
                  }
         default:{}
               }
       return ($word);
       }
и соответствующие изменения в языковом файле например:
$L['File_s'] = "Файл,ов,,а,ов";
предложение не получило поддержки :-)
www.cotonti.mobi
esclkm
#29 9. Februar 2009, 08:52
дайвер мыслит болеее чм верно
littledev.ru - мой маленький зарождающийся блог о котонти.
снижение стоимости программирования и снижение стоимости производства разные вещи. Первое можно скорее сравнить с раздачей работникам дешевых инструментов, чем со снижением зарплаты
Ratibor
#30 9. Februar 2009, 15:19
# esclkm : дайвер мыслит болеее чм верно
Не совсем :-)
В данном случае нельзя делать эту функцию плугином,
вдруг ктото забудет его поставить ?

Проще зделать это встроенной функцией, тем более что все правила известны.

В общем вот все правила:
<?php

class Plural {

    /**
     * Returns the plural version to use for each language
     *
     * @param $plural  Plural to check the version for
     * @param $locale  Locale to search the rule for
     * @return string  Evaluation method for the pluralform
     */
    public static function getPlural($plural, $locale) {

        switch($locale) {
            case 'bo':
            case 'dz':
            case 'id':
            case 'ja':
            case 'jv':
            case 'ka':
            case 'km':
            case 'kn':
            case 'ko':
            case 'ms':
            case 'th':
            case 'tr':
            case 'vi':
                return 0;
                break;

            case 'af':
            case 'az':
            case 'bn':
            case 'bg':
            case 'ca':
            case 'da':
            case 'de':
            case 'el':
            case 'en':
            case 'eo':
            case 'es':
            case 'et':
            case 'eu':
            case 'fa':
            case 'fi':
            case 'fo':
            case 'fur':
            case 'fy':
            case 'gl':
            case 'gu':
            case 'ha':
            case 'he':
            case 'hu':
            case 'is':
            case 'it':
            case 'ku':
            case 'lb':
            case 'ml':
            case 'mn':
            case 'mr':
            case 'nah':
            case 'nb':
            case 'ne':
            case 'nl':
            case 'nn':
            case 'no':
            case 'om':
            case 'or':
            case 'pa':
            case 'pap':
            case 'ps':
            case 'pt':
            case 'so':
            case 'sq':
            case 'sv':
            case 'sw':
            case 'ta':
            case 'te':
            case 'tk':
            case 'ur':
            case 'zh':
            case 'zu':
                return ($plural == 1) ? 1 : 0;

            case 'am':
            case 'bh':
            case 'fil':
            case 'fr':
            case 'gun':
            case 'hi':
            case 'ln':
            case 'mg':
            case 'nso':
            case 'xbr':
            case 'ti':
            case 'wa':
                return (($plural == 0) || ($plural == 1)) ? 1 : 0;

            case 'be':
            case 'bs':
            case 'hr':
            case 'ru':
            case 'sr':
            case 'uk':
                return (($plural % 10 == 1) && ($plural % 100 != 11)) ? 1 : (($plural % 10 >= 2) && ($plural % 10 <= 4) && (($plural % 100 < 10) || ($plural % 100 >= 20))) ? 2 : 0;

            case 'cs':
            case 'sk':
                return ($plural == 1) ? 1 : (($plural >= 2) && ($plural <= 4)) ? 2 : 0;

            case 'ga':
                return ($plural == 1) ? 1 : ($plural == 2) ? 2 : 0;

            case 'lt':
                return (($plural % 10 == 1) && ($plural % 100 != 11)) ? 1 : (($plural % 10 >= 2) && (($plural % 100 < 10) || ($plural % 100 >= 20))) ? 2 : 0;

            case 'sl':
                return ($plural % 100 == 1) ? 1 : ($plural % 100 == 2) ? 2 : (($plural % 100 == 3) || ($plural % 100 == 4)) ? 3 : 0;

            case 'mk':
                return ($plural % 10 == 1) ? 1 : 0;

            case 'mt':
                return ($plural == 1) ? 1 : (($plural == 0) || (($plural % 100 > 1) && ($plural % 100 < 11))) ? 2 : (($plural % 100 > 10) && ($plural % 100 < 20)) ? 3 : 0;

            case 'lv':
                return ($plural == 0) ? 1 : (($plural % 10 == 1) && ($plural % 100 != 11)) ? 2 : 0;

            case 'pl':
                return ($plural == 1) ? 1 : (($plural % 10 >= 2) && ($plural % 10 <= 4) && (($plural % 100 < 10) || ($plural % 100 > 29))) ? 2 : 0;

            case 'cy':
                return ($plural == 1) ? 1 : ($plural == 2) ? 2 : (($plural == 8) || ($plural == 11)) ? 3 : 0;

            case 'ro':
                return ($plural == 1) ? 1 : (($plural == 0) || (($plural % 100 > 0) && ($plural % 100 < 20))) ? 2 : 0;

            case 'ar':
                return ($plural == 0) ? 1 : ($plural == 1) ? 2 : ($plural == 2) ? 3 : (($plural >= 3) && ($plural <= 10)) ? 4 : (($plural >= 11) && ($plural <= 99)) ? 5 : 0;

            default:
                return null;
        }
    }
}

Теперь остается дописать функцию обработки и все счастливы и довольны.
Не задавай глупых вопросов, не услышишь вранья.

Dieser Beitrag wurde von Ratibor (am 9. Februar 2009, 16:19, vor 15 Jahre) bearbeitet

ErsteVorherige12345NächsteLetzte