Зачем это нужно?
При разработке интернет-магазина на Webasyst часто требуется динамическое склонение слов в зависимости от количества товаров (например: «1 товар», «2 товара», «5 товаров»).
Ручная проверка условий для каждого случая усложняет разработку. Решение — функция Smarty, которая автоматически выбирает нужную форму слова. В статье разберем её реализацию и применение.
Готовая функция для склонения слов
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token keyword">function</span> plural <span class="token attr-name">n</span><span class="token operator">=</span><span class="token number">0</span> <span class="token attr-name">words</span><span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">"один"</span><span class="token punctuation">,</span> <span class="token string">"два"</span><span class="token punctuation">,</span> <span class="token string">"пять"</span><span class="token punctuation">]</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token keyword">if</span> <span class="token function">intval</span><span class="token punctuation">(</span><span class="token variable">$n</span> <span class="token operator">/</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">%</span> <span class="token number">10</span> <span class="token operator">!=</span> <span class="token number">1</span> <span class="token operator">&&</span> <span class="token number">1</span> <span class="token operator"><=</span> <span class="token variable">$n</span> <span class="token operator">%</span> <span class="token number">10</span> <span class="token operator">&&</span> <span class="token variable">$n</span> <span class="token operator">%</span> <span class="token number">10</span> <span class="token operator"><=</span> <span class="token number">4</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token keyword">if</span> <span class="token variable">$n</span> <span class="token operator">%</span> <span class="token number">10</span> <span class="token operator">==</span> <span class="token number">1</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token variable">$words</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token keyword">else</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token variable">$words</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{/</span><span class="token keyword">if</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token keyword">else</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token variable">$words</span><span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{/</span><span class="token keyword">if</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{/</span><span class="token keyword">function</span><span class="token delimiter punctuation">}</span></span>
Как это работает:
intval($n / 10) % 10 != 1— исключает числа 11-19 (например, 11 товаров, 13 товаров), где всегда используется третья форма.$n % 10— определяет последнюю цифру числа:- Если 1 — выбирает
words[0](1 товар), - Если 2-4 — выбирает
words[1](2 товара), - В остальных случаях —
words[2](5 товаров).
- Если 1 — выбирает
Пример использования
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token variable">$reviews_count</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token keyword">call</span> plural <span class="token attr-name">n</span><span class="token operator">=</span><span class="token variable">$reviews_count</span> <span class="token attr-name">words</span><span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">"отзыв"</span><span class="token punctuation">,</span> <span class="token string">"отзыва"</span><span class="token punctuation">,</span> <span class="token string">"отзывов"</span><span class="token punctuation">]</span><span class="token delimiter punctuation">}</span></span>
Вариант с системной функцией перевода Webasyst (_wp()):
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token variable">$products_count</span><span class="token delimiter punctuation">}</span></span>
<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token keyword">call</span> plural <span class="token attr-name">n</span><span class="token operator">=</span><span class="token variable">$products_count</span> <span class="token attr-name">words</span><span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">"{_wp("</span>товар<span class="token string">")}"</span><span class="token punctuation">,</span> <span class="token string">"{_wp("</span>товара<span class="token string">")}"</span><span class="token punctuation">,</span> <span class="token string">"{_wp("</span>товаров<span class="token string">")}"</span><span class="token punctuation">]</span><span class="token delimiter punctuation">}</span></span>
Результаты:
- Если
$products_count = 1: «Найден 1 товар», - Если
$products_count = 3: «Найдено 3 товара», - Если
$products_count = 7: «Найдено 7 товаров».
Замените массив words на нужные варианты. Например, для слова «отзыв»:
Преимущества подхода
- Универсальность — можно использовать для любых слов: «пользователь», «заказ», «сообщение».
- Чистый код — логика склонения инкапсулирована в одну функцию.
- Текст правильно выглядит — исключает случаи неверного склоненеия слов. Например: 3 товаров, осталось 2 упаковка и т.д.
Частые ошибки
- Неправильный порядок слов в массиве
Обязательный формат:[форма для 1, форма для 2-4, форма для 5+]. - Передача нечисловых значений
Убедитесь, чтоn— целое число (используйтеintval($n)при необходимости).
Итог
Функция plural решает проблему склонения слов в Webasyst всего за несколько строк кода. Её легко интегрировать в любую тему дизайна и отображение слов всегда будет правильным, даже при динамическом изменении чисел.