Зачем это нужно?

При разработке интернет-магазина на 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">&#36;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">&#36;n</span> <span class="token operator">%</span> <span class="token number">10</span> <span class="token operator">&&</span> <span class="token variable">&#36;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">&#36;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">&#36;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">&#36;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">&#36;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>

Как это работает:

  1. intval($n / 10) % 10 != 1 — исключает числа 11-19 (например, 11 товаров, 13 товаров), где всегда используется третья форма.
  2. $n % 10 — определяет последнюю цифру числа:
    • Если 1 — выбирает words[0] (1 товар),
    • Если 2-4 — выбирает words[1] (2 товара),
    • В остальных случаях — words[2] (5 товаров).

Пример использования

<span class="token smarty language-smarty"><span class="token delimiter punctuation">{</span><span class="token variable">&#36;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">&#36;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">&#36;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">&#36;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. Неправильный порядок слов в массиве
    Обязательный формат: [форма для 1, форма для 2-4, форма для 5+].
  2. Передача нечисловых значений
    Убедитесь, что n — целое число (используйте intval($n) при необходимости).

Итог
Функция plural решает проблему склонения слов в Webasyst всего за несколько строк кода. Её легко интегрировать в любую тему дизайна и отображение слов всегда будет правильным, даже при динамическом изменении чисел.