Куда идем?

Каждый раз, когда я делаю очередной интернет-магазин на Virtuemart, то сталкиваюсь с одной и той же мелкой, но очень неприятной проблемой. Модуль мини-корзины Virtuemart не умеет правильно склонять слово «товар», когда их, товаров, добавлено несколько. В этом кейсе я расскажу о том, как обойти данную проблему без применения хаков.

Примечание

Данный способ не является правильным с точки зрения разработки, но он позволяет нам внести изменения таким образом, чтобы при обновлении Virtuemart они не были потеряны, т.е. без хаков.

Суть проблемы склонения слова «Товар»

У нас есть модуль мини-корзины:

1

Пока в корзине нет товаров или есть только один товар, то все отображается корректно:

2

Но как только товаров становится 2 и более, слово «товар» начинает склоняться неправильно:

3

Это не ошибка Virtuemart. Это особенность русского языка. В английском языке есть один «product» и много «products». Этим все ограничивается. В русском языке есть один «товар», два «товара», пять «товаров». Т.е. три варианта склонения. Понятно, что разработчики VM не учитывают особенности каждого языка. Исправим это для русского языка самостоятельно.

Проблема не имеет простого решения. Дело в том, что мини-корзина Virtuemart обновляется двумя разными способами:

  1. Через PHP при перезагрузке страницы
  2. Через AJAX, без перезагрузки страницы, при добавлении товара в корзину

Если в первом случае достаточно просто переопределить макет модуля мини-корзины в шаблон Joomla и внести в нем изменения, то во втором случае внесение изменений в JS-код обновления количества товаров в корзине будет хаком. В этом вся сложность, в этом вся проблема. Посмотрим, как можно ее решить.

Склонение слова «товар» в мини-корзине Virtuemart

Шаг 1. Переопределение языковых констант

Первое, что нам нужно сделать – разделить количество товаров и склоняемое слово «товар». По умолчанию они содержатся в двух языковых константах:

  • COM_VIRTUEMART_CART_ONE_PRODUCT
  • COM_VIRTUEMART_CART_X_PRODUCTS

для, соответственно, одного и нескольких товаров в английском языке.

Переходим в: «Расширения -> Менеджер языков -> Переопределение констант» и создаем два новых переопределения для указанных выше языковых констант. Подставляем их в поиск и заменяем:

  • «1 товар» на «1»
  • «%s товаров» на «%s»

4

Если все сделано правильно, на сайте, в мини-корзине, вместо «2 товаров» у вас будет отображаться просто «2»:

5

Теперь нам остается добавить слово «товар» в модуль и правильно просклонять его.

Шаг 2. Склонение слова «товар» средствами PHP

Переопределяем макет модуля мини-корзины в используемый шаблон Joomla. Для этого копируем файл:

modules/mod_virtuemart_cart/tmpl/default.php

в:

templates/ваш_шаблон/html/mod_virtuemart_cart/

и в скопированный файл добавляем следующие изменения:

В самом начале файла, после строчки:

 

defined('_JEXEC') or die('Restricted access');

 

и закомментированных копирайтов, добавляем:

 

<?php //Склоняем слово "товаров"         
function sklon($number, array $words) {
    $cases = array(2, 0, 1, 1, 1, 2);
    return $words[($number % 100 > 4 && $number % 100 < 20) ? 2 : $cases[min($number % 10, 5)]];
}
?>

 

Находим строчку:

 

<div class="total_products"><?php echo  $data->totalProductTxt ?></div>

 

и заменяем ее на:

 

<div class="total_products">
     <?php if ($data->totalProduct) {
              echo $data->totalProduct.' '.sklon($data->totalProduct, array('товар', 'товара', 'товаров'));
     } ?>
</div>

 

Если все сделано правильно, то на сайте, после добавления товара в корзину и обновления страницы(!) склонение будет показываться корректно:

6

Но, еще раз хочу отметить, склонение корректно будет показываться только после перезагрузки страницы (когда отрабатывает PHP), но не после добавления товара в корзину (когда работает JavaScript).

Шаг 3. Склонение слова «товар» средствами JavaScript

Теперь пришло время добавить поддержку склонений средствами JavaScript (далее JS).

Конечно, правильно было бы добавить такую поддержку в JS-код, формирующий обновление данных модуля мини-корзины, но это приведет нас к хаку VM, а потому нам придется пойти на некоторую хитрость.

В наш переопределенный файл из шага 2 после первого добавленного куска кода:

<?php //Склоняем слово "товаров"         
function sklon($number, array $words) {
    $cases = array(2, 0, 1, 1, 1, 2);
    return $words[($number % 100 > 4 && $number % 100 < 20) ? 2 : $cases[min($number % 10, 5)]];
}
?>

Добавляем:

 

<?php
//Добавляем скрипт склонения после AJAX-обновления корзины
$document = JFactory::getDocument();
$cart_js=" 
function sklon(num, expressions) {
    var result;
    count = num % 100;
    if (count >= 5 && count <= 20) {
        result = expressions['2'];
    } else {
        count = count % 10;
        if (count == 1) {
            result = expressions['0'];
        } else if (count >= 2 && count <= 4) {
            result = expressions['1'];
        } else {
            result = expressions['2'];
        }
    }
    return result;
}


jQuery(document).ready(function() {
            jQuery('.addtocart-button').click(function() {
                        jQuery(document).ajaxStop(function() {
                                   var pr_count = parseInt(jQuery('#vmCartModule .total_products').text());
                                   jQuery('#vmCartModule .total_products').text(pr_count+' '+sklon(pr_count, ['товар','товара','товаров']));
                        });
            });
});
";        
 
$document->addScriptDeclaration($cart_js);
?>

 

Здесь мы создали JS-функцию склонения, а затем, при клике по кнопку добавления в корзину, выполняем ее и подменяем наше слово в мини-корзине правильным.

Здесь следует обратить внимание на событие ajaxStop. Оно выполняется после того, как были выполнены все AJAX-запросы. Т.е. склонение и подмена происходит уже после того, как сам Virtuemart обновит корзину через AJAX.

Мне не нравится этот код! Он ужасен! Программисты, слышите, ужасен! Но он работает. Быстро, просто, четко, и, главное, без хаков.

Хочу обратить внимание, что для корректной работы, у всех кнопок добавления в корзину на сайте должен быть CSS-класс «addtocart-button». По умолчанию, в стандартном шаблоне VM, он есть, но если вы используете нестандартный шаблон, проверьте его наличие, либо исправьте этот класс в коде, приведенном выше, на тот, что имеют ваши кнопки добавления в корзину.

В результате, если код вставлен правильно, склонение слова «товар» на сайте должно быть полностью работоспособным.

Склонение слова «товар» в мини-корзине Virtuemart. Быстрый способ

Ниже, по ссылке, вы можете скачать уже готовый измененный макет мини-корзины. Просто скопируйте его в ваш шаблон Joomla, как описывается на шаге 2 и выполните шаг 1. Результат будет аналогичным.

Скачать измененный макет

Если у вас что-то не получается сделать самостоятельно, вы всегда можете задать вопрос на форуме или обратиться ко мне за платной помощью.

Об авторе
Wedal
(Виталий). Веб-разработчик полного цикла (Full Stack). Создатель и автор сайта Wedal.ru.
Основной профиль – создание сайтов и расширений на CMS Joomla.
Добавить комментарий

Комментарии  
0
Добрый день!

Помогите пожалуйста, я никак не могу вывести в категории ее изображения, в списке категорий оно выводиться, а шаблоне самой категории нет. Там есть такой код:
0
Антон, изображение категории в макете категории можно вывести с помощью такого кода:

Код:

<?php echo $this->category->images[0]->displayMediaThumb("",false); ?>