Question

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?

Était-ce utile?

La solution

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!

Licencié sous: CC-BY-SA avec attribution
Non affilié à magento.stackexchange
scroll top