0

I have a scenario, i want to list a marketing/ads product on interval of 9 product on category listing page. So every 10th number of product is a marketing/ads product. For example i add following images. In the image the ads product coming after every 2 products.

enter image description here

Any ideas how to get solution around this?

5
  • Will you assign categories to marketing/ads product ?
    – ZealousWeb
    Commented Mar 5, 2021 at 11:37
  • I update questing with a image that i need. Hope this help you. Commented Mar 5, 2021 at 12:07
  • I have a solution for it. I am posting an answer in sometime.
    – ZealousWeb
    Commented Mar 5, 2021 at 12:08
  • Please check answer and let me know on this. @Raghwendra Ojha
    – ZealousWeb
    Commented Mar 5, 2021 at 12:33
  • Have you checked?
    – ZealousWeb
    Commented Mar 5, 2021 at 14:06

1 Answer 1

1

You can achieve this by override ListProduct block in your custom module. Please follow below steps to achieve this.

Step 1: Please create di.xml file under path PackageName/Vendor/etc/

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\ListProduct" type="PackageName\Vendor\Block\Rewrite\Product\ListProduct" />
</config>

Step 2: Please create file ListProduct.php file under path PackageName/Vendor/Block/Rewrite/Product/

<?php

namespace PackageName\Vendor\Block\Rewrite\Product;

class ListProduct extends \Magento\Catalog\Block\Product\ListProduct
{
    /**
     * @var \Magento\Catalog\Model\ProductFactory
     */
    protected $_productloader;

    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,
        \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
        \Magento\Framework\Url\Helper\Data $urlHelper,
        \Magento\Catalog\Model\ProductFactory $productloader,
        array $data = []
    ) {
        $this->_productloader = $productloader;
        parent::__construct($context, $postDataHelper, $layerResolver,
            $categoryRepository, $urlHelper, $data);
    }

    public function getCustomLoadedProductCollection()
    {
        $productCollection = $this->_getProductCollection();
        $data = array();
        $productObject = $this->getLoadProduct(1818);

        $i = 0;
        foreach ($productCollection as $_product) {
            $productArray = array();
            if ($i != 0 && $i % 4 == 0) {
                array_push($data, $productObject);
            }
            array_push($data, $_product);
            $i++;
        }   
        return $data;
    }

    /**
     * Load product by id
     * 
     * @param $id
     * @return \Magento\Catalog\Model\Product
     */
    public function getLoadProduct($id)
    {
       try {
            $product = $this->_productloader->create()->load($id);
        } catch (\Magento\Framework\Exception\NoSuchEntityException $e){
            $product = false;
        }
        return $product;
    }
}

In above code please pass product id as per you want to show. I have shown my product in the loop every 5th time. Please change iteration in loop according to your need.

Step 3: Set custom template for list.phtml file. Please create catalog_category_view.xml file under path PackageName/Vendor/view/frontend/layout

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance dc" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <referenceBlock name="category.products.list">
        <action method="setTemplate">
            <argument name="template" xsi:type="string">PackageName_Vendor::product/list.phtml</argument>
        </action>
    </referenceBlock>
</page>

Step 4: Please create file list.phtml under path PackageName/Vendor/view/frontend/templates/product

Paste your theme's list.phtml file code into this custom file and change function and count as per shown in below code.

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
use Magento\Framework\App\Action\Action;

?>
<?php
/**
 * Product list template
 *
 * @var $block \Magento\Catalog\Block\Product\ListProduct
 * @var \Magento\Framework\Escaper $escaper
 * @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer
 */
?>
<?php
$_productCollection = $block->getCustomLoadedProductCollection();
/** @var \Magento\Catalog\Helper\Output $_helper */
$_helper = $block->getData('outputHelper');
?>
<?php if (!count($_productCollection)):?>
    <div class="message info empty">
        <div><?= $escaper->escapeHtml(__('We can\'t find products matching the selection.')) ?></div>
    </div>
<?php else:?>
    <?= $block->getToolbarHtml() ?>
    <?= $block->getAdditionalHtml() ?>
    <?php
    if ($block->getMode() == 'grid') {
        $viewMode = 'grid';
        $imageDisplayArea = 'category_page_grid';
        $showDescription = false;
        $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::SHORT_VIEW;
    } else {
        $viewMode = 'list';
        $imageDisplayArea = 'category_page_list';
        $showDescription = true;
        $templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::FULL_VIEW;
    }
    /**
     * Position for actions regarding image size changing in vde if needed
     */
    $pos = $block->getPositioned();
    ?>
    <div class="products wrapper <?= /* @noEscape */ $viewMode ?> products-<?= /* @noEscape */ $viewMode ?>">
        <ol class="products list items product-items">
            <?php /** @var $_product \Magento\Catalog\Model\Product */ ?>
            <?php foreach ($_productCollection as $_product):?>
            <li class="item product product-item">
                <div class="product-item-info"
                     id="product-item-info_<?= /* @noEscape */ $_product->getId() ?>"
                     data-container="product-<?= /* @noEscape */ $viewMode ?>">
                    <?php
                    $productImage = $block->getImage($_product, $imageDisplayArea);
                    if ($pos != null) {
                        $position = 'left:' . $productImage->getWidth() . 'px;'
                            . 'top:' . $productImage->getHeight() . 'px;';
                    }
                    ?>
                    <?php // Product Image ?>
                    <a href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>"
                       class="product photo product-item-photo"
                       tabindex="-1">
                        <?= $productImage->toHtml() ?>
                    </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="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>">
                                <?=/* @noEscape */ $_helper->productAttribute($_product, $_product->getName(), 'name')?>
                            </a>
                        </strong>
                        <?= $block->getReviewsSummaryHtml($_product, $templateType) ?>
                        <?= /* @noEscape */ $block->getProductPrice($_product) ?>
                        <?php if ($_product->isAvailable()):?>
                            <?= $block->getProductDetailsHtml($_product) ?>
                        <?php endif; ?>

                        <div class="product-item-inner">
                            <div class="product actions product-item-actions">
                                <div class="actions-primary">
                                    <?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]
                                                    ?>">
                                            <?= $block->getBlockHtml('formkey') ?>
                                            <button type="submit"
                                                    title="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
                                                    class="action tocart primary">
                                                <span><?= $escaper->escapeHtml(__('Add to Cart')) ?></span>
                                            </button>
                                        </form>
                                    <?php else:?>
                                        <?php if ($_product->isAvailable()):?>
                                            <div class="stock available">
                                                <span><?= $escaper->escapeHtml(__('In stock')) ?></span></div>
                                        <?php else:?>
                                            <div class="stock unavailable">
                                                <span><?= $escaper->escapeHtml(__('Out of stock')) ?></span></div>
                                        <?php endif; ?>
                                    <?php endif; ?>
                                </div>
                                <?= strpos($pos, $viewMode . '-primary') ?
                                    /* @noEscape */ $secureRenderer->renderStyleAsTag(
                                        $position,
                                        'product-item-info_' . $_product->getId() . ' div.actions-primary'
                                    ) : '' ?>
                                <div data-role="add-to-links" class="actions-secondary">
                                    <?php if ($addToBlock = $block->getChildBlock('addto')):?>
                                        <?= $addToBlock->setProduct($_product)->getChildHtml() ?>
                                    <?php endif; ?>
                                </div>
                                <?= strpos($pos, $viewMode . '-secondary') ?
                                    /* @noEscape */ $secureRenderer->renderStyleAsTag(
                                        $position,
                                        'product-item-info_' . $_product->getId() . ' div.actions-secondary'
                                    ) : '' ?>
                            </div>
                            <?php if ($showDescription):?>
                                <div class="product description product-item-description">
                                    <?= /* @noEscape */ $_helper->productAttribute(
                                        $_product,
                                        $_product->getShortDescription(),
                                        'short_description'
                                    ) ?>
                                    <a href="<?= $escaper->escapeUrl($_product->getProductUrl()) ?>"
                                       title="<?= /* @noEscape */ $_productNameStripped ?>"
                                       class="action more"><?= $escaper->escapeHtml(__('Learn More')) ?></a>
                                </div>
                            <?php endif; ?>
                        </div>
                    </div>
                </div>
                <?= strpos($pos, $viewMode . '-actions') ?
                /* @noEscape */ $secureRenderer->renderStyleAsTag(
                    $position,
                    'product-item-info_' . $_product->getId() . ' div.product-item-actions'
                ) : '' ?>
            </li>
            <?php endforeach; ?>
        </ol>
    </div>
    <?= $block->getToolbarHtml() ?>
    <?php if (!$block->isRedirectToCartEnabled()):?>
        <script type="text/x-magento-init">
        {
            "[data-role=tocart-form], .form.map.checkout": {
                "catalogAddToCart": {
                    "product_sku": "<?= $escaper->escapeJs($_product->getSku()) ?>"
                }
            }
        }
        </script>
    <?php endif; ?>
<?php endif; ?>

This will surely work for you. Please check and let me know if you face issue anywhere.

Thanks Cheers!

9
  • Please follow all the steps and let me know if you have any query.
    – ZealousWeb
    Commented Mar 5, 2021 at 13:05
  • Getting error - Exception #0 (Exception): Notice: Undefined variable: escaper in list.phtml on line 63 Commented Mar 5, 2021 at 14:18
  • On which version you are working? My list.phtml file code is from magento 2.4.1 version. Please copy your list.phtml file code according to your version
    – ZealousWeb
    Commented Mar 5, 2021 at 14:40
  • Please change only 2 lines in your list.phtml file. One is change function - $_productCollection = $block->getCustomLoadedProductCollection(); and second one is please change condition of count like this - <?php if (!count($_productCollection)):?>. Except this change i have not done any changes in list.phtml file
    – ZealousWeb
    Commented Mar 5, 2021 at 14:42
  • 1
    Yes please and its working. Thank you so much for your help. Commented Mar 10, 2021 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.