В Opencart есть модули для вывода слайдшоу, баннеров, но вывести можно только один вариант изображения. Здесь инструкция, как "модернизировать" эти модули и вывести в них разные варианты изображения для различных устройств.
В качестве источника изображений эти модули используют "Баннеры" (Дизайн -> Баннеры).
Лучшим вариантом считаю заранее подготовить изображения под разные устройства, для каждого баннера указать несколько вариантов (по умолчанию только один). Далее, уже в модулях, использовать тег picture для вывода разных вариантов в зависимости от разрешения, например широкое изображение для ПК, узкое для мобильных.
В примере (для Opencart 3) будет добавлен один дополнительный вариант изображения. Изображения будут добавляться в "Дизайн -> Баннеры", поэтому начать нужно с этого компонента.
Первый шаг - добавить поле (в phpMyAdmin) "image_sm" в таблицу "banner_image". У меня это "oc_banner_image", использую префикс по умолчанию, может быть другой.
Для удобства вот запрос на добавление поля:
ALTER TABLE `oc_banner_image` ADD `image_sm` VARCHAR(255) NOT NULL DEFAULT '' AFTER `image`;
Далее изменения в модели, контроллере и шаблоне "баннеров" (ниже есть архив с измененными файлами)
1. Модель. /admin/model/design/banner.php
Здесь в двух местах (в функциях addBanner и editBanner) нужно найти:
$this->db->query("INSERT INTO " . DB_PREFIX . "banner_image SET banner_id = '" . (int)$banner_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($banner_image['title']) . "', link = '" . $this->db->escape($banner_image['link']) . "', image = '" . $this->db->escape($banner_image['image']) . "', sort_order = '" . (int)$banner_image['sort_order'] . "'");
Эти строки в двух функциях одинаковы, но может быть отличие в одном лишнем пробеле. Меняем на:
$this->db->query("INSERT INTO " . DB_PREFIX . "banner_image SET banner_id = '" . (int)$banner_id . "', language_id = '" . (int)$language_id . "', title = '" . $this->db->escape($banner_image['title']) . "', link = '" . $this->db->escape($banner_image['link']) . "', image = '" . $this->db->escape($banner_image['image']) . "', image_sm = '" . $this->db->escape($banner_image['image_sm']) . "', sort_order = '" . (int)$banner_image['sort_order'] . "'");
Было добавлено:
, image_sm = '" . $this->db->escape($banner_image['image_sm']) . "'
Еще одно изменение здесь. Нужно найти:
'image' => $banner_image['image'],
И после этого добавить:
'image_sm' => $banner_image['image_sm'],
2. Контроллер. /admin/controller/design/banner.php
Здесь изменения небольшие и коснуться только функции getForm. Здесь нужно найти:
$data['banner_images'][$key][] = array(
Перед этой строкой есть проверка существования изображения с объявлением переменных $image и $thumb. Эту конструкцию нужно продублировать с небольшим изменением. Получится так:
if (is_file(DIR_IMAGE . $banner_image['image_sm'])) {
$image_sm = $banner_image['image_sm'];
$thumb_sm = $banner_image['image_sm'];
} else {
$image_sm = '';
$thumb_sm = 'no_image.png';
}
Далее внутри массива banner_images, после:
'thumb' => $this->model_tool_image->resize($thumb, 100, 100),
Добавим:
'image_sm' => $image_sm,
'thumb_sm' => $this->model_tool_image->resize($thumb_sm, 100, 100),
3. Шаблон. /admin/view/template/design/banner_form.twig
Здесь правки в трех местах, нужно найти и продублировать все что касается изображения. Находим:
<td class="text-center">{{ entry_image }}</td>
Сразу после нужно добавить:
<td class="text-center">{{ entry_image }} mobile</td>
Находим:
<td class="text-center"><a href="" id="thumb-image{{ image_row }}" data-toggle="image" class="img-thumbnail"><img src="{{ banner_image.thumb }}" alt="" title="" data-placeholder="{{ placeholder }}" /></a>
<input type="hidden" name="banner_image[{{ language.language_id }}][{{ image_row }}][image]" value="{{ banner_image.image }}" id="input-image{{ image_row }}" /></td>
После:
<td class="text-center"><a href="" id="thumb-imagesm{{ image_row }}" data-toggle="image" class="img-thumbnail"><img src="{{ banner_image.thumb_sm }}" alt="" title="" data-placeholder="{{ placeholder }}" /></a>
<input type="hidden" name="banner_image[{{ language.language_id }}][{{ image_row }}][image_sm]" value="{{ banner_image.image_sm }}" id="input-imagesm{{ image_row }}" /></td>
Находим:
html += ' <td class="text-center"><a href="" id="thumb-image' + image_row + '" data-toggle="image" class="img-thumbnail"><img src="{{ placeholder }}" alt="" title="" data-placeholder="{{ placeholder }}" /></a><input type="hidden" name="banner_image[' + language_id + '][' + image_row + '][image]" value="" id="input-image' + image_row + '" /></td>';
После:
html += ' <td class="text-center"><a href="" id="thumb-imagesm' + image_row + '" data-toggle="image" class="img-thumbnail"><img src="{{ placeholder }}" alt="" title="" data-placeholder="{{ placeholder }}" /></a><input type="hidden" name="banner_image[' + language_id + '][' + image_row + '][image_sm]" value="" id="input-imagesm' + image_row + '" /></td>';
В результате получится так:
Вот файлы, правки в которые вносились выше: Скачать
Теперь можно приступать к изменениям в каталоге. Для примера будут правки в модуле слайдшоу.
Для начала контроллер - /catalog/controller/extension/module/slideshow.php
Здесь находим:
'image' => $this->model_tool_image->resize($result['image'], $setting['width'], $setting['height'])
Выше добавим:
'image_sm' => 'image/'.$result['image_sm'],
Можно и ниже, главное про запятую не забыть. Вывел изображение без масштабирования, поэтому и не делал правок в админке модуля. Желательно сразу подготовить изображение с нужным разрешением и его указывать. Для изображения под ПК я также обычно убираю масштабирование.
Вообще можно сделать в самом модуле несколько полей с вводом размеров картинки под разные разрешения, но обычно это избыточно. К тому же, не каждый хостинг может оптимизировать изображения, т.е. на выходе можно получить мелкое изображение с большим размером файла, чем если подгонять и оптимизировать до загрузки.
Теперь шаблон модуля. Файл /catalog/view/theme/default/template/extension/module/slideshow.twig
Находим (в двух местах, внутри ссылки и без):
<img src="{{ banner.image }}" alt="{{ banner.title }}" class="img-responsive" />
Здесь изображение выведено классическим способом, тегом img. Для адаптивности можно использовать тег picture с указанием различных вариантов зображения и обязательным img внутри, где будет выведено изображение для основного разрешения. Меняем (дважды) на:
<picture><source media="(max-width: 768px)" srcset="{{ banner.image_sm }}"><img src="{{ banner.image }}" alt="{{ banner.title }}" class="img-responsive" /></picture>
Как вариант, прикрепляю файл с кодом (slideshow.twig.zip), который получился у меня. Убрал лишний div, так же здесь id указан для общего контейнера ".slideshow", а не ".swiper-container" и кнопки навигации указаны через id модуля. В стандартном варианте, если на странице выведено несколько слайдшоу, кнопками верхнего можно листать и все что ниже.