Комплексное обновление и разработка интернет-магазина доставки цветов
В конце января 2025 года был завершен инженерный проект по обновлению и полному рефакторингу платформы интернет-магазина по доставке цветов и подарков. Ресурс был переведен с устаревшей кодовой базы Joomla 3.x на актуальную архитектуру Joomla 5.2.0 с оптимизацией под серверное окружение PHP 8.1. Проект включал в себя не только трансфер базы данных (ETL), но и написание с нуля фронтенд-интерфейса, глубокую модернизацию E-commerce ядра JoomShopping, внедрение сложных алгоритмических JavaScript-решений без использования тяжелых фреймворков и строгую SEO-калибровку (устранение дублей, настройка канонических ссылок).

1. Архитектура миграции и серверная инфраструктура
Переход с третьей версии Joomla на пятую требует кардинальной перестройки принципов работы с базой данных и API системы. В процессе миграции были решены следующие фундаментальные задачи:
- Адаптация под PHP 8.1: Кодовая база шаблона и всех задействованных расширений прошла строгий аудит. Были устранены устаревшие (deprecated) функции, исправлены предупреждения строгой типизации, а вызовы классов переведены на использование пространств имен (Namespaces) в соответствии со стандартами PSR-12.
- Обновление базы данных JoomShopping: Выполнен перенос структуры таблиц товаров (
#__jshopping_products), категорий, заказов и клиентов. Индексы баз данных были перестроены для повышения скорости выполнения SQL-запросов. - Маршрутизация (URL Routing): Ключевым бизнес-требованием являлось сохранение 100% старых URL-адресов для удержания поисковых позиций. Была сохранена структура ID категорий и товаров. Механизм SEF-ссылок настроен таким образом, чтобы адреса вида
/katalog/klassicheskie-bukety/buket-iz-15-rozпродолжали работать без необходимости настройки массива 301-редиректов.
2. Модернизация E-commerce ядра (JoomShopping)
Магазин доставки цветов имеет специфическую бизнес-логику: необходимость привязки сопутствующих товаров, динамическая подгрузка ассортимента и сложная система маркировки. Для этого базовая комплектация JoomShopping была расширена специализированными аддонами и кастомным кодом.
2.1. Интеграция премиум-аддонов JoomShopping
Для реализации требуемого маркетингового функционала были интегрированы и доработаны на уровне кода следующие расширения от Webdesigner-profi:
- Product Multilabel: Внедрен алгоритм присвоения нескольких меток (шильдиков) одному товару. Теперь к букетам могут одновременно применяться метки «Скидка», «Хит продаж» или «Новинка». Потребовалась правка файлов шаблона вывода товара (
list_products/product.php) для корректного позиционирования абсолютных блоков.product_label_pos_leftповерх изображений. - Set of Product: Настроен функционал автоматического предложения бесплатной открытки к каждому букету. Это потребовало ручной привязки ID подарочной открытки к массиву товарных позиций и доработки логики добавления в корзину (исключение учета стоимости подарочного сета).
- AJAX Product Pagination: Для снижения нагрузки на сервер (TTFB) и базу данных при рендеринге объемных категорий (например, «Букеты из роз»), классическая пагинация заменена на асинхронную подгрузку. Внедрена кнопка «Загрузить ещё» (
#load-more-btn). Скрипт анализирует ширину экрана (window.innerWidth) и динамически определяет шаг подгрузки (по 12 товаров для десктопа и мобильных устройств), инкрементируя значение атрибутаdata-loaded.
2.2. Модификация процесса оформления заказа (Checkout)
Согласно требованиям законодательства РФ (ФЗ-152), в процесс чекаута интегрированы юридические механизмы согласия. Выполнено системное переопределение (Override) файла /components/com_jshopping/templates/base/checkout/adress.php. На 826-й строке внедрен блок с чекбоксом, подтверждающим ознакомление с «Заявлением о конфиденциальности». Текстовки переменных вынесены в языковые файлы и управляются через административную панель (Joomshopping > Настройки > Статический текст).
3. Глубокая SEO-калибровка и управление каноническими ссылками
Специфика каталога JoomShopping заключается в генерации дублей страниц при доступе к одному товару через разные категории или фильтры. Для жесткого контроля индексации проведена фундаментальная настройка:
- Нативная канонизация: Активированы базовые функции
JoomShopping Product canonicalиJoomShopping category canonical. - Custom Canonical CK: Установлен и настроен системный плагин для принудительного переопределения канонических ссылок.
- Очистка SEF: Во избежание циклических редиректов удален базовый домен из системных настроек SEF Joomla.
- Мануальная разметка: Для статических материалов Joomla, не относящихся к магазину (например,
/kontakty), канонические ссылки прописаны вручную во вкладке "Метаданные". Автоматическая генерация канонических ссылок на уровне пунктов меню (Menu Items) отключена для предотвращения конфликтов с роутером JoomShopping. - Исключения, такие как главная страница
/katalog(не являющаяся физической категорией JoomShopping) и/sitemap, оставлены без жестких канонических тегов для сохранения ранее сформированного графа индексации в Яндекс.Вебмастере.
4. Фронтенд-разработка: Helix Ultimate и Typography
Визуальный интерфейс спроектирован на базе фреймворка Helix Ultimate и сетки Bootstrap 5.3.3. Разработана сложная типографическая иерархия с использованием библиотеки Google Fonts:
- Базовый текст (Body):
'Roboto Serif', sans-serif(16px для десктопов, плавно уменьшающийся до 13px на мобильных через CSS Media Queries). - Заголовки H1-H2:
'PT Serif', sans-serifдля придания премиального, классического вида. - Навигация (Mega Menu):
'Oswald', sans-serif(16px, font-weight: 300). - Акцентные элементы H6:
'Exo 2', sans-serif.
Цветовая палитра строится на использовании CSS-переменных, где акцентным выступает фирменный малиновый оттенок (#ff4057), контрастирующий с темным (#323232) подвалом и белоснежными контентными блоками.
5. Интеллектуальные JavaScript-компоненты (Vanilla JS)
Для обеспечения максимальной производительности интерфейса (без загрузки тяжелых библиотек вроде jQuery UI или Slick Carousel) все интерактивные блоки написаны на чистом JavaScript (ES6+).
5.1. Динамический генератор тегов (DOM Parser)
Один из самых сложных алгоритмов внедрен в секцию #sevHomeTagsDesktop («Популярные направления»). Скрипт динамически парсит структуру Mega Menu в шапке сайта, извлекает ссылки и формирует из них сетку SEO-тегов на главной странице.
- Функция
getHeaderRoots()собирает все ссылки из.sp-megamenu-wrapper. - Функция
findCatalogContainer()анализирует вес ссылок и находит основной контейнер каталога. - Алгоритм очищает ссылки от мусорных узлов (SVG-иконки, каретки), нормализует текст (
normalizeText), удаляет дубликаты по URL и исключает системные разделы (например, "По цене"). - На основе полученных данных скрипт "на лету" (через
document.createElement) строит DOM-узлы с заголовками групп и тегами. - Внедрен
MutationObserver, который следит за изменениями DOM. Если меню загружается асинхронно или изменяется, скрипт автоматически перестраивает сетку тегов. Для длинных списков внедрена логика кнопки «Показать ещё» (показывает по 5 дополнительных тегов).
5.2. Комплексные слайдеры (Hero Section)
Главный баннер реализован в двух изолированных версиях: #sevDesktopSlider и #sevMobileSlider. Логика управления написана на Vanilla JS и изолирована внутри IIFE (Immediately Invoked Function Expression) для предотвращения конфликта областей видимости.
- Мультимедиа: Поддержка видео-фона (
<video autoplay muted loop playsinline>) и статических изображений. - Автовоспроизведение и Прогресс-бар: Настроена задержка в 9000мс. Анимация прогресс-бара синхронизирована с таймером через CSS Keyframes (
@keyframes svdProgress). - События и Сенсорное управление: Обработка событий
touchstartиtouchend. Скрипт вычисляет дельту свайпа (touchEndX - touchStartX) и перелистывает слайд при преодолении порога в 50px. - Доступность (A11y): Управление с клавиатуры (
ArrowLeft/ArrowRight), корректные ARIA-атрибуты, приостановка автовоспроизведения при сворачивании вкладки браузера (visibilitychange).
5.3. Интерактивная карусель "Недавно смотрели / Новинки"
Блок горизонтальной прокрутки товаров реализован с поддержкой нативного Drag-and-Drop (захват и перетаскивание мышью).
slider.addEventListener('mousemove', (e) => {
if (!isDragging) return;
e.preventDefault();
const x = e.pageX - slider.offsetLeft;
const walk = (x - startX) * 1.5; // Мультипликатор скорости 1.5
slider.scrollLeft = scrollLeft - walk;
});
Помимо мыши, реализованы кнопки дискретного скроллинга, вычисляющие ширину контейнера (slider.offsetWidth) для точного позиционирования следующего блока карточек.
6. Мобильная адаптация и App-like интерфейс
Пользовательский опыт на мобильных устройствах максимально приближен к нативным приложениям.
6.1. Фиксированная полоса доставки (Sticky Delivery Bar)
Реализован информационный блок #sevHeaderDelivery, информирующий о круглосуточной доставке. На мобильных устройствах он фиксируется (position: fixed) ровно под шапкой (top: 50px). Для предотвращения перекрытия контента внедрен элемент .sev-header-delivery-space. Написан сложный JavaScript-обработчик с использованием MutationObserver, который отслеживает открытие бокового меню (Off-Canvas) и плавно скрывает полоску (transform: translateY(-10px)), чтобы она не ломала z-index навигации.
6.2. AJAX Мини-корзина (SJ Minicart Pro)
Внедрен модуль mod_sj_minicart_pro. Логика корзины полностью асинхронна.
- Кнопки плюс/минус и изменение количества (input keyup) отправляют AJAX-запрос к контроллеру VirtueMart/JoomShopping с задержкой 500мс (техника Debounce) для предотвращения DDOS-эффекта на сервер.
- Интегрировано поле для ввода купона с мгновенной проверкой (задача
setcoupon) и возвратом JSON-ответа об успешном применении или ошибке. - Визуальная часть корзины использует плагин
mCustomScrollbarдля эстетичной прокрутки.
7. Интеграции, Безопасность и Юридическая обвязка
7.1. Модуль Cookie Consent (n3tcookieconsent)
Внедрен системный плагин для соответствия требованиям GDPR и Роскомнадзора. Дизайн попапа кастомизирован через CSS-переменные (--cc-bg, --cc-btn-primary-bg: rgba(219, 83, 83, 1)). Текстовые константы плагина переведены и переопределены напрямую в INI-файлах языковых пакетов:
/administrator/language/ru-RU/ru-RU.plg_system_n3tcookieconsent.ini (строка 371)
7.2. Беспарольная аутентификация (WebAuthn)
Форма входа в систему (mod_login) оснащена кнопкой plg_system_webauthn_login_button, интегрирующей API FIDO2. Пользователи могут входить в личный кабинет с использованием биометрических датчиков устройства, что исключает возможность брутфорса и перехвата паролей.
7.3. Интерактивные формы (QuickForm3 и Умный поиск)
На сайте развернута многоуровневая система коммуникации:
- Smart Search: Модальное окно поиска открывается по клику, не перегружая DOM-дерево при первоначальной загрузке.
- Smart Forms: Интегрированы модули "Обратный звонок", требующие чекбокса согласия с политикой конфиденциальности.
- Аналитика: Подключены коды Яндекс.Метрики (
yaCounter46855263), Top.Mail.Ru, скрипт защиты от скликивания (botfaqtor.ru) и виджет онлайн-консультанта Битрикс24 (loader_2_3n2zyj.js).
Использованные технологии
| Технология / Инструмент | Версия | Роль в архитектуре проекта |
|---|---|---|
| Joomla! CMS | 5.2.0 | Ядро платформы, управление контентом, ACL, WebAuthn. |
| PHP | 8.1 | Серверное окружение, строгая типизация. |
| JoomShopping | 5.x | E-commerce база, товары, категории, чекаут. |
| JoomShopping Addons | Latest | Multilabel (метки), Set of Product (подарки), Ajax Pagination. |
| Helix Ultimate | 2.0+ | Фронтенд-фреймворк, Bootstrap 5.3.3, Layout Builder. |
| Vanilla JS | ES6 | Обработчики событий, Drag-and-Drop, MutationObserver, DOM Parser. |
| n3tcookieconsent | Latest | Управление файлами Cookie и согласиями пользователей. |
Заключение
Обновление интернет-магазина цветов с Joomla 3 на Joomla 5.2 является примером технологического скачка. Архитектура сайта была переработана с нуля, избавившись от наследия старых версий. Внедрение асинхронных загрузок (AJAX), отложенной загрузки изображений, кастомных JS-скриптов и передового функционала JoomShopping позволило создать высококонверсионный, быстрый и безопасный B2C-портал. Строгое сохранение старых URL и тонкая настройка канонических ссылок обеспечили сохранность органического трафика. Если вашему E-commerce проекту требуется обновление до Joomla 5 или индивидуальная доработка JoomShopping, ознакомьтесь с ответами на частые технические вопросы.
Развернуть полный вид интернет-магазина доставки цветов на Джумле 5

Примечание: текущее состояние и внешний вид действующего сайта могут отличаться от представленных в данном кейсе, так как после завершения и сдачи проекта заказчик мог внести самостоятельные изменения.
Вопросы и ответы по данному сайту
Как именно реализована генерация SEO-тегов из меню?
Скрипт использует document.querySelectorAll для сбора всех ссылок внутри .sp-megamenu-wrapper. Затем он анализирует pathname и search каждой ссылки с помощью объекта URL(). Дубликаты, якорные ссылки (#) и ссылки javascript: отфильтровываются. Далее алгоритм вычисляет уровень вложенности ссылки в DOM-дереве (через parentElement) и группирует их под родительскими заголовками. Итоговый HTML формируется через document.createElement и вставляется в секцию #sevHomeTagsDesktop.
Как работает функция "Бесплатная открытка" (Set of Product) на уровне базы данных?
Аддон Set of Product создает связующую таблицу в базе данных JoomShopping, сопоставляя product_id основного товара (букета) с product_id дочернего товара (открытки). При добавлении букета в корзину (через контроллер Cart), плагин перехватывает событие и автоматически добавляет дочерний товар с нулевой стоимостью, предотвращая возможность его самостоятельного удаления покупателем без удаления основного товара.
В чем преимущество использования MutationObserver для мобильного меню?
Мобильное меню (Off-Canvas) в Helix Ultimate может открываться как при клике на иконку "бургер", так и при свайпе. Использование обычного addEventListener('click') не всегда перехватывает свайпы или программные вызовы. MutationObserver отслеживает изменение атрибутов class и style у тега <body> и самого меню. Как только класс offcanvas-active появляется, скрипт гарантированно скрывает фиксированную полоску доставки.
Как устроена AJAX пагинация товаров в JoomShopping?
При клике на кнопку "Загрузить ещё", JavaScript отправляет фоновый GET-запрос к контроллеру категории с параметром limitstart, увеличенным на заданный шаг (например, +12). Сервер возвращает HTML-фрагмент со следующими товарами. Скрипт извлекает из ответа карточки товаров (.product-item) и "приклеивает" (append) их в конец контейнера #products-container, не перезагружая шапку и футер сайта.
Что за параметр `is-email="1" first="aW5mbw==" last="c2V2Y3ZldG9rLnJ1"` в коде?
Это работа плагина joomla-hidden-mail. Данный плагин защищает email-адреса от сбора (парсинга) спам-ботами. Реальный адрес разбивается на части (логин и домен), кодируется алгоритмом Base64 (aW5mbw==) и помещается в кастомный тег <joomla-hidden-mail>. При загрузке страницы в браузере, клиентский JavaScript (joomla-hidden-mail.min.js) декодирует Base64 и собирает кликабельную ссылку mailto:, которая невидима для ботов, читающих исходный HTML-код.