Hello Friends, in this blog, we will learn how can we add custom content or media to Configurable Products’ Fotorama media gallery at the front end.
Here, I have added some extra content to the media gallery in the first position. You can change the content position as per your requirements.
If you are a vendor and want to attract more customers to your e-commerce store. Explore our WebAR Magento 2 extension.
As we have to add content in the configurable products’ media gallery when we deep-dive into the code, we will find that configurable product images are being changed/loaded from the <magento-root-dir.>/vendor/magento/module-configurable-product/view/frontend/web/js/configurable.js file.
Where, the _changeProductImage() function is responsible for achieving this.
So, to add the custom content I have overridden the _changeProductImage() function and added some required files which are required to achieve our goal.
First of all, we will create a demo module. Here, I have created the Webkul_ExtraContentInFotorama module. Further, follow the below steps:
1. Create catalog_product_view_type_configurable.xml file inside the <magento-root-dir>/app/code/Webkul/ExtraContentInFotorama/view/frontend/layout/ directory.
<?xml version="1.0"?> <!-- /** * Webkul Software. * * @category Webkul * @package Webkul_ExtraContentInFotorama * @author Webkul Software Private Limited * @copyright Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ --> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="product.info.options.wrapper"> <referenceBlock class="Webkul\ExtraContentInFotorama\Block\Product\Renderer\Configurable" name="product.info.options.swatches"> </referenceBlock> </referenceBlock> </body> </page>
2. Create a Configurable.php file inside the <magento-root-dir.>/app/code/Webkul/ExtraContentInFotorama/Block/Product/Renderer/ directory.
<?php /** * Webkul Software. * * @category Webkul * @package Webkul_ExtraContentInFotorama * @author Webkul Software Private Limited * @copyright Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ declare(strict_types = 1); namespace Webkul\ExtraContentInFotorama\Block\Product\Renderer; /** * Swatch renderer block */ class Configurable extends \Magento\Swatches\Block\Product\Renderer\Configurable { /** * Path to default template file with standard Configurable renderer. */ public const CONFIGURABLE_RENDERER_TEMPLATE = 'Webkul_ExtraContentInFotorama::product/view/type/options/configurable.phtml'; /** * Return renderer template * * Template for product with swatches is different from product without swatches * * @return string */ protected function getRendererTemplate() { return $this->isProductHasSwatchAttribute() ? parent::SWATCH_RENDERER_TEMPLATE : self::CONFIGURABLE_RENDERER_TEMPLATE; } }
3. Create a configurable.phtml file inside the <magento-root-dir>/app/code/Webkul/ExtraContentInFotorama/view/frontend/templates/product/view/type/options/ directory.
<?php /** * Webkul Software. * * @category Webkul * @package Webkul_ExtraContentInFotorama * @author Webkul Software Private Limited * @copyright Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ ?> <?php /** @var $block \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable*/ $product = $block->getProduct(); $_attributes = $block->decorateArray($block->getAllowAttributes()); $linkUrl = "https://webkul.com/blog/design-patterns-in-magento-2/"; $thumbnailImage = "Provide a thumbnail Image URL"; $linkContent = "Design Patterns in Magento 2"; ?> <?php if ($product->isSaleable() && count($_attributes)) :?> <?php foreach ($_attributes as $_attribute) : ?> <div class="field configurable required"> <label class="label" for="attribute<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>"> <span><?= $block->escapeHtml($_attribute->getProductAttribute()->getStoreLabel()) ?></span> </label> <div class="control"> <select name="super_attribute[<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>]" data-selector="super_attribute[<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>]" data-validate="{required:true}" id="attribute<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>" class="super-attribute-select"> <option value=""><?= $block->escapeHtml(__('Choose an Option...')) ?></option> </select> </div> </div> <?php endforeach; ?> <script type="text/x-magento-init"> { "#product_addtocart_form": { "configurable": { "spConfig": <?= /* @noEscape */ $block->getJsonConfig() ?>, "gallerySwitchStrategy": "<?= $block->escapeJs($block->getVar( 'gallery_switch_strategy', 'Magento_ConfigurableProduct' ) ?: 'replace'); ?>", "thumbnailImage":"<?= /* @noEscape */$thumbnailImage?>", "linkUrl":"<?= /* @noEscape */ $linkUrl?>", "linkContent":"<?= /* @noEscape */ $linkContent?>" } }, "*" : { "Magento_ConfigurableProduct/js/catalog-add-to-cart": {} } } </script> <?php endif;?>
4. Create a requires-config.js file to mention the mixin file for the configurable.js file inside the <magento-root-dir.>/app/code/Webkul/ExtraContentInFotorama/view/frontend/ directory.
/** * Webkul Software. * * @category Webkul * @package Webkul_ExtraContentInFotorama * @author Webkul Software Private Limited * @copyright Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ var config = { config: { mixins: { 'Magento_ConfigurableProduct/js/configurable' : {'Webkul_ExtraContentInFotorama/js/configurable':true} } } };
5. Create a configurable.js file inside the <magento-root-dir.>/app/code/Webkul/ExtraContentInFotorama/view/frontend/web/js/ directory.
/** * Webkul Software. * * @category Webkul * @package Webkul_ExtraContentInFotorama * @author Webkul Software Private Limited * @copyright Webkul Software Private Limited (https://webkul.com) * @license https://store.webkul.com/license.html */ define([ 'jquery', 'underscore', 'mage/translate' ], function ($, _, $t) { 'use strict'; return function (configurable) { $.widget('mage.configurable', configurable, { /** * Change displayed product image according to chosen options of configurable product * * @private */ _changeProductImage: function () { var self = this; //Thumbnail Image for Custom Content//// var contentThumbnailImage = self.options.thumbnailImage; var images, initialImages = this.options.mediaGalleryInitial, gallery = $(this.options.mediaGallerySelector).data('gallery'); /////////Load Custom Content in Fotorama///// self._loadCustomContent(); ////////////////////////////// if (_.isUndefined(gallery)) { $(this.options.mediaGallerySelector).on('gallery:loaded', function () { this._changeProductImage(); }.bind(this)); return; } images = this.options.spConfig.images[this.simpleProduct]; if (images) { //Remove Extra Content from Fotorama//// initialImages = self._removeExtraContentfromArray(initialImages); images = self._removeExtraContentfromArray(images); //Push Extra Content in Fotorama//// self._pushContent(images, contentThumbnailImage); ////////////////// images = this._sortImages(images); if (this.options.gallerySwitchStrategy === 'prepend') { images = images.concat(initialImages); } images = $.extend(true, [], images); images = this._setImageIndex(images); gallery.updateData(images); this._addFotoramaVideoEvents(false); } else { //Remove Extra Content from Fotorama//// initialImages = self._removeExtraContentfromArray(initialImages); //Push Extra Content in Fotorama//// self._pushContent(initialImages, contentThumbnailImage); gallery.updateData(initialImages); this._addFotoramaVideoEvents(true); } }, /** * Set correct indexes for image set. * * @param {Array} images * @private */ _setImageIndex: function (images) { var length = images.length, i, j = 1; for (i = 0; length > i; i++) { if (images[i].type == "ExtraContent") { images[i].i = 1; } else { images[i].i = j + 1; } } return images; }, /** * Delete Additional content from array * * @param {Array} fotoramaContentArray * @returns {Array} * @private */ _removeExtraContentfromArray: function(fotoramaContentArray) { fotoramaContentArray = fotoramaContentArray.filter( element => element.type !== "ExtraContent" ); return fotoramaContentArray; }, /** * Push content in array * * @param {Array} fotoramaContentArray * @param {string} contentThumbnailImage * @private */ _pushContent: function(fotoramaContentArray, contentThumbnailImage) { var self = this; if (typeof fotoramaContentArray != "undefined" && (self.options.linkUrl != "" || self.options.linkUrl != null)) { fotoramaContentArray.unshift({ thumb: contentThumbnailImage, src: self.options.linkUrl, type: 'ExtraContent', caption: self.options.linkContent, isMain: "true", position: 0 }); } }, /** * Load custom content * * @private */ _loadCustomContent: function() { var self = this; var galleryDivFotorama = $('div.gallery-placeholder > div.fotorama'); var variantText = "None"; var variantTextColor = "#FFED8F"; //Get Selected Variant Value variantText = self._getSelectedVariant(); switch (variantText) { case "Mango Velvet": variantTextColor = "#FF8200"; break; case "Peacock Velvet": variantTextColor = "#A7D46F"; break; } galleryDivFotorama.on('fotorama:load', function fotorama_onLoad(e, fotorama, extra) { if (extra.frame.type === 'ExtraContent' && extra.frame.src != "") { var extraContentHtml = ''; extraContentHtml += '<div id="wkExtraContent" '; extraContentHtml += 'style="background-color:'+variantTextColor+';">'; extraContentHtml += '<h1 style="margin-top:250px">'+'Extra Content'+'</h1>'; ///Show Variant Text/// if (variantText != '') { extraContentHtml += '<p style="font-size:20px">Selected Variant:</p>'; extraContentHtml += '<p style="font-size:18px">'+variantText+'</p><br/>'; } ///////////////// extraContentHtml += '<a href="'+self.options.linkUrl+'" style="font-size:18px">' extraContentHtml += self.options.linkContent+'</a>'; extraContentHtml += '</div>'; extra.frame.$stageFrame.html(extraContentHtml); } }); }, /** * Get Selected Variant Value * * @return {string} * @private */ _getSelectedVariant: function() { var variantTextVal = ""; var variantTextArr = []; var selectedText = $('.product-options-wrapper select[id^="attribute"] option:selected').text(); if (selectedText.indexOf('+') == -1) { variantTextVal = selectedText; } else { variantTextArr = selectedText.split('+'); variantTextVal = $.trim(variantTextArr[0]); } return variantTextVal; }, }); return $.mage.configurable; }; });
6. After adding the above code to your module. Deploy the code and see the result.
Refer to the below image for the result.
Hope this will be helpful. Thanks 🙂
You may also check the Magento 2 Advanced Media Manager extension to edit the images present in the media gallery and add watermarks, filter, rotate, resize, and more.
You can check our next blog Magento 2 Custom Content in Configurable Product Media Gallery to display custom content in the media gallery in text and visual swatch case on the configurable product page.
Be the first to comment.