В 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>{% if banner.image_sm %}<source media="(max-width: 768px)" srcset="{{ banner.image_sm }}">{% endif %}<img src="{{ banner.image }}" alt="{{ banner.title }}" class="img-responsive" /></picture>
Как вариант, прикрепляю файл с кодом (slideshow.twig.zip), который получился у меня. Убрал лишний div, так же здесь id указан для общего контейнера ".slideshow", а не ".swiper-container" и кнопки навигации указаны через id модуля. В стандартном варианте, если на странице выведено несколько слайдшоу, кнопками верхнего можно листать и все что ниже.
Немного изменил код шаблона, забыл добавить проверку на наличие этого самого изображения
По прежнему ничего не произошло, на фронте не передается вообще изображение.
пустое получается.
Добрый день, не сработал метод, в админке все указываю, на фронте не выводится фото.
Модуль тот же? Если правки внесены в catalog/controller и шаблон, то или кэш, или шаблон другой используется. Скачайте, посмотрите на всякий случай пример шаблона
Скачал по примеру, шаблон стоковый.
Все заработало в контроллер забыл прописать 'image_sm' => 'image/'.$result['image_sm'],
Спасибо!!!
Супер! :)