How to create custom product slider
Today we will learn How to create custom product slider. On the basis of your need, you can add your own condition such as product attribute filter, category filter, or join with any other table. Here we will use slick slider to show content. You can show your custom product collection anywhere on the page. You can provide the custom settings for the slick slider in the slick() as a json object.
Here you can find the full configration that can be set in slick function.
https://www.npmjs.com/package/slick-slider
For better understanding of creating module, You can create module as per the give instruction in following link
https://experienceleague.adobe.com/docs/commerce-learn/tutorials/frontend-development/create-new-page.html
Let’s suppose our vendor name is Vendor and Module name is Module.
Note: This blog will work on magento 2.4.3 and later versions.
Let’s create a controller for accessing the page on storefront. This will load the layout page and its required content.
Path:- app/code/Vendor/Module/Controller/Index/MyProdList.php
<?php namespace Vendor\Module\Controller\Index; class MyProdList extends \Magento\Framework\App\Action\Action { protected $_pageFactory; public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Framework\View\Result\PageFactory $pageFactory ) { $this->_pageFactory = $pageFactory; return parent::__construct($context); } public function execute() { return $this->_pageFactory->create(); } }
This is our layout file. You can use 1 column, 2 columns etc as per your need. You can also use the following block in your existing page such as catalog category page, catalog product page, customer pages etc.
Path:- app/code/Vendor/Module/view/frontend/layout/vendormod_index_myprodlist.xml
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <referenceContainer name="content"> <block class="Vendor\Module\Block\ProductList" name="vendormod_index_myprodlist" template="Vendor_Module::index.phtml" /> </referenceContainer> </page>
Here is our block which is responsible for getting product collection and required params for adding product to cart, getting form key, getting price renderer etc. This file extends the block \Magento\Catalog\Block\Product\AbstractProduct.
Path:- app/code/Vendor/Module/Block/ProductList.php
<?php namespace Vendor\Module\Block; use Magento\Catalog\Pricing\Price\FinalPrice; use Magento\Framework\Pricing\Render; use Magento\Framework\App\ActionInterface; class ProductList extends \Magento\Catalog\Block\Product\AbstractProduct { /** * @var \Magento\Framework\Url\Helper\Data */ protected $urlHelper; /** * @var \Magento\Catalog\Model\ProductFactory */ protected $productFactory; /** * @param Context $context * @param \Magento\Framework\Url\Helper\Data $urlHelper * @param \Magento\Catalog\Model\ProductFactory $productloader * @param array $data */ public function __construct( \Magento\Catalog\Block\Product\Context $context, \Magento\Framework\Url\Helper\Data $urlHelper, \Magento\Catalog\Model\ProductFactory $productloader, \Magento\Framework\Data\Form\FormKey $formKey, array $data = [] ) { $this->urlHelper = $urlHelper; $this->productFactory = $productloader; $this->formKey = $formKey; parent::__construct($context, $data); } /** * Get form key * * @return string */ public function getFormKey() { return $this->formKey->getFormKey(); } /** * Load Products collection * * @return Product array */ public function getLoadProducts() { $products = $this->productFactory->create()->getCollection() ->addAttributeToSelect(["name", "price", "image"]) //Custom filter on attributes //category filter //join with other table //->addAttributeToFilter(IndustryType::PRODUCT_ATTRIBUTE_CODE, ["eq" => $attributeValue]) ->addAttributeToFilter("visibility", ['neq' => 1]); return $products; } /** * Load Product * * @return Product array */ public function getLoadProduct($id) { return $this->productFactory->create()->load($id); } /** * Get post parameters * * @param \Magento\Catalog\Model\Product $product * @return array */ public function getAddToCartPostParams(\Magento\Catalog\Model\Product $product) { $url = $this->getAddToCartUrl($product, ['_escape' => false]); return [ 'action' => $url, 'data' => [ 'product' => (int) $product->getEntityId(), ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl($url), ] ]; } /** * Get product price. * * @param \Magento\Catalog\Model\Product $product * @return string */ public function getProductPrice(\Magento\Catalog\Model\Product $product) { $priceRender = $this->getPriceRender($product); $price = ''; if ($priceRender) { $price = $priceRender->render( FinalPrice::PRICE_CODE, $product, [ 'include_container' => true, 'display_minimal_price' => true, 'zone' => Render::ZONE_ITEM_LIST, 'list_category_page' => true ] ); } return $price; } /** * Get price render * * @param \Magento\Catalog\Model\Product $product * @return Render */ protected function getPriceRender($product) { return $this->getLayout()->createBlock(\Magento\Framework\Pricing\Render::class, "product.price.render.default".$product->getSku()) ->setData('is_product_list', true); } }
This is our phtml file which represent the slider on page. You can put the following code before, after or in the middle of the content.
Path:- app/code/Vendor/Module/view/frontend/templates/index.phtml
<?php use Magento\Framework\App\Action\Action; $_productCollection = $block->getLoadProducts(); if ($_productCollection->getSize() <= 0) { return; } ?> <h2><center>Product list carousel</center></h2> <div class="container-"> <?php $_helper = $this->helper('Magento\Catalog\Helper\Output'); ?> <?php $viewMode = 'grid'; $image = 'category_page_grid'; $showDescription = false; $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::SHORT_VIEW; $pos = $block->getPositioned(); $position = ''; $formKey = $block->getFormKey(); ?> <style> .products-grid .product-item-inner{ margin:unset; } </style> <?php $count = 1; ?> <div class="ind-container"> <div class=" products wrapper grid products-grid <?php /* @escapeNotVerified */ echo $viewMode; ?> products-<?php /* @escapeNotVerified */ echo $viewMode; ?>"> <?php $iterator = 1; ?> <div class="products grid items product-items slick-carousel" > <?php $prdCount = 0; ?> <?php foreach($_productCollection as $_product): ?> <?php $_product = $block->getLoadProduct($_product->getEntityId()); ?> <div class="item product product-item"> <div class="product-item-info item" data-container="product-grid"> <?php $productImage = $block->getImage($_product, $image); if ($pos != null) { $position = ' style="left:' . $productImage->getWidth() . 'px;' . 'top:' . $productImage->getHeight() . 'px;"'; } ?> <?php // Product Image ?> <a href="<?php /* @escapeNotVerified */ echo $_product->getProductUrl() ?>" class="product photo product-item-photo" tabindex="-1"> <?php /* @escapeNotVerified */ echo $productImage->toHtml(); ?> <div class="product-discount"> <?php $originalPrice = $_product->getPrice(); $finalPrice = $_product->getFinalPrice(); $discount = 0; if($originalPrice > $finalPrice){ $discount = number_format(($originalPrice - $finalPrice) * 100 / $originalPrice,0); ?> <div class="price_section"> <span class=""><?= $discount.'% Off'; ?></span> </div> <?php } ?> <a href="#" class="action towishlist" title="<?php echo $block->escapeHtml(__('Add to Wishlist')); ?>" aria-label="<?php echo $block->escapeHtml(__('Add to Wishlist')); ?>" data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($_product); ?>' data-action="add-to-wishlist" role="button"> <span><?php /* @escapeNotVerified */ echo __('Add to Wishlist') ?></span> </a> </div> </a> <div class="product details product-item-details"> <?php $_productNameStripped = $block->stripTags($_product->getName(), null, true); ?> <strong class="product name product-item-name"> <a class="product-item-link" href="<?php /* @escapeNotVerified */ echo $_product->getProductUrl() ?>"> <?php /* @escapeNotVerified */ echo $_helper->productAttribute($_product, $_product->getName(), 'name'); ?> </a> </strong> <?php /* @escapeNotVerified */ echo $block->getProductPrice($_product);?> <?php /* @escapeNotVerified */ echo $block->getReviewsSummaryHtml($_product, $templateType); ?> <div class="product-item-inner"> <div class="product actions product-item-actions"<?php /* @escapeNotVerified */ echo strpos($pos, $viewMode . '-actions') ? $position : ''; ?>> <div class="actions-primary"<?php /* @escapeNotVerified */ echo strpos($pos, $viewMode . '-primary') ? $position : ''; ?>> <?php if ($_product->isSaleable()): ?> <?php $postParams = $block->getAddToCartPostParams($_product); ?> <form data-role="tocart-form" data-product-sku="<?= $escaper->escapeHtml($_product->getSku()) ?>" action="<?= $escaper->escapeUrl($postParams['action']) ?>" method="post" > <input type="hidden" name="product" value="<?= /* @noEscape */ $postParams['data']['product'] ?>"> <input type="hidden" name="<?= /* @noEscape */ Action::PARAM_NAME_URL_ENCODED ?>" value="<?= /* @noEscape */ $postParams['data'][Action::PARAM_NAME_URL_ENCODED] ?>"> <input type="hidden" name="form_key" value="<?= /* @noEscape */ $formKey ?>"> <button type="submit" title="<?php echo $block->escapeHtml(__('Add to Cart')); ?>" class="action tocart primary"> <span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span> </button> </form> <?php else: ?> <?php if ($_product->getIsSalable()): ?> <div class="stock available"><span><?php /* @escapeNotVerified */ echo __('In stock') ?></span></div> <?php else: ?> <div class="stock unavailable"><span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span></div> <?php endif; ?> <?php endif; ?> </div> <!-- <div data-role="add-to-links" class="actions-secondary"<?php echo strpos($pos, $viewMode . '-secondary') ? $position : ''; ?>> <?php $compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare'); ?> <a href="#" class="action tocompare" title="<?php echo $block->escapeHtml(__('Add to Compare')); ?>" aria-label="<?php echo $block->escapeHtml(__('Add to Compare')); ?>" data-post='<?php /* @escapeNotVerified */ echo $compareHelper->getPostDataParams($_product); ?>' role="button"> <span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span> </a> </div> --> </div> </div> </div> </div> <script type="text/x-magento-init"> { "[data-role=tocart-form], .form.map.checkout": { "catalogAddToCart": { "product_sku": "<?= /* @noEscape */ $_product->getSku() ?>" } } } </script> </div> <?php endforeach; ?> </div> </div> </div> <?php $count++; ?> <script> require(['jquery', 'jquery/ui', 'slick'], function($) { $(document).ready(function() { $(".slick-carousel").slick({ dots: true, infinite: false, slidesToShow: 4, slidesToScroll: 1 }); }); }); </script>
Output:- After creating all above files, Here is how the output would be shown.

Previous Blog https://webkul.com/blog/how-to-pass-data-using-js-widget-in-magento-2/