Сниппет Declension для склонения слов
Предлагаю вашему вниманию небольшой сниппет для вывода склонения. Работает как фильтр вывода, использовать нужно примерно так:

Как видите, он применяется к любым тегам с числами, а в options нужно указать три формы слова (1 яблоко, 2 яблока и 10 яблок) для русского, или 2 (1 ticket, 2 tickets) для английского.
Для экспериментов можно повызывать сниппет с произвольными числами:
Как вы уже догадались, сниппет был написан для оформления баланса на хостинге, но я подумал, что вам он тоже пригодится.
Если кто-то оформит его в готовый пакет и выложит в репозиторий — не возражаю. Уже давно есть.
[[+balls]] [[+balls:declension=`балл,балла,баллов`]]
Как видите, он применяется к любым тегам с числами, а в options нужно указать три формы слова (1 яблоко, 2 яблока и 10 яблок) для русского, или 2 (1 ticket, 2 tickets) для английского.
Для экспериментов можно повызывать сниппет с произвольными числами:
15 [[*id:input=`15`:declension=`яблоко,яблока,яблок`]]Полный код под катом.<?php
/**
* Declension of words
* This algorithm taken from https://github.com/livestreet/livestreet/blob/eca10c0186c8174b774a2125d8af3760e1c34825/engine/modules/viewer/plugs/modifier.declension.php
*/
/** @var array $scriptProperties */
$number = $modx->getOption('input', $scriptProperties, 0);
$forms = $modx->getOption('options', $scriptProperties, '');
if (is_string($forms)) {
if ($forms[0] == '[') {
$forms = $modx->fromJSON($forms);
}
else {
$forms = explode(',', $forms);
}
}
if (!is_numeric($number)) {
return;
}
if (!is_array($forms) || empty($forms)) {
return 'Вы должны указать формы слов для склонения. Например [[*id:declension=`яблоко,яблока,яблок`]].';
}
if (count($forms) == 3) {
$mod100 = $number % 100;
switch ($number % 10) {
case 1:
if ($mod100 == 11) {
$text = $forms[2];
}
else {
$text = $forms[0];
}
break;
case 2:
case 3:
case 4:
if (($mod100 > 10) && ($mod100 < 20)) {
$text = $forms[2];
}
else {
$text = $forms[1];
}
break;
case 5:
case 6:
case 7:
case 8:
case 9:
case 0:
default:
$text = $forms[2];
}
}
elseif (count($forms) == 2) {
if ($number == 1) {
$text = $forms[0];
}
else {
$text = $forms[1];
}
}
else {
$text = 'Недостаточно форм слов для склонения';
}
return $text;Как вы уже догадались, сниппет был написан для оформления баланса на хостинге, но я подумал, что вам он тоже пригодится.
Комментарии: 30
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
ПашокFi1osof{$count|spell:«яблоко»:«яблока»:«яблок»}
Ну и лично я люблю, когда понятно, а не коротко. PHP всё равно оптимизирует исходники при выполнении.
Fi1osofМожно и в одну строку сжать — не проблема. От этого кому лучше будет?
Я вообще не понимаю экономии на строках. А есть еще люди, которые на скобках экономят, и на пробелах. Должно быть понятно, тем более, когда выкладываешь что-то для других.
Я к тому, что функция нужная, но не такая важная, чтобы из нее пакет делать. Алгоритм элементарный, такие задачки на информатике в школе проходить нужно и пишется он за пару минут. Это сейчас не укор твоим способностям, они неоспоримы.
АндрейНо поскольку для новых версий MODX его из репозитория не скачать, можно использовать обычный сниппет:
А дальше вызывать:
Почему я поднял этот вопрос:
потому что сейчас я решил «как обычно» не заморачиваясь скачать пакет «Units» из офф-репозитория, но его там не оказалось (не знаю, конфликт версий с MODX наверное). Дальше я вспомнил про этот сниппет и решил вбить его здесь на сообществе в поиск. Но подобрать подходящее слово у меня не получилось, и по «Units» тоже эта статья не нашлась. И пришлось мне кликать по пагинации раз 20 пока я не нашел эту статью (в закладках в профиле тоже куча статей и также долго пришлось её искать).
Я понимаю, что решение для кого-то несложное, но зачем каждый раз его велосипедить, если быстрее скачать и использовать?
Победило такое решение:
Ну и вызываем:
declension (decl) — склоняет слово, следующее за числом по правилам русского языка. Например: 1 яблоко, 2 яблока, 10 яблок.
и пример:
У меня для статей сделаны комментарии при помощи компонента Tickets, теперь к сути:
чанк обёртки комментариев содержит переменную {$total} — количество комментариев. Хочу добавить склонение, но оно не хочет работать, хм… вот чанк tpl_commentsWrapper
Может подскажете что не так делаю, ибо не склоняет переменную. Если подставлять цифры то склоняет, а переменную не хочет.
Так что сейчас у тебя нет этой переменной, он пустая, и количество комментариев выставляется через javascript.
Укажи &setTotal=`1` в вызове TicketsComments, и всё должно заработать.
Да и дело даже не в скорости, а в том, что при добавлении нового комментария их общее количество изменится, а склонение — нет.
Поэтому лучше или оставить как есть, без склонения, или делать его на js — и тогда total вообще не нужен.
Это после загрузки страницы javascript подставляет количество комментов. Открой исходник страницы и увидишь на месте переменной, что там пусто.