First, we create a controller in our custom plugin:

There are two ways to use repository in controller:

  • 1. Using container of current controller
  • 2. By sending the repository from services.xml file.

/custom/plugins/PluginName/src/Controller

<?php declare(strict_types=1);

namespace PluginName\Controller;

use Shopware\Core\Content\Cms\Exception\PageNotFoundException;
use Shopware\Core\Content\Cms\SalesChannel\SalesChannelCmsPageLoaderInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
use Shopware\Storefront\Page\Navigation\NavigationPage;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;

/**
 * @RouteScope(scopes={"storefront"})
 */
class ProductController extends StorefrontController
{

   private $productCategoryRepository;

     /**
     * @var EntityRepositoryInterface
     */

    private $productRepository;

    public function __construct(EntityRepositoryInterface $productRepository)
    {
        $this->productRepository= $productRepository;
    }

    /**
     * @HttpCache()
     * @Route("/products", name="frontend.products.detail", methods={"GET"})
     */
    public function detailAction(Request $request, SalesChannelContext $context, Context $con): Response
{

        $criteria1 = new Criteria();
$criteria1->addAssociations(['media', 'properties', 'properties.group', 'unit', 'tax']);
        // using reference of repository sent from services.xml
        $products = $this->productRepository->search($criteria1, $con)->getEntities();
        
        $productIds;
        foreach($products as $key => $p){
            foreach($p as $k => $pr){
                    $productIds[] = $pr;
            }
        }
        
        // using current class reference controller
        $this->productPriceRepository = $this->container->get('product_price.repository');

        $criteria2 = new Criteria();
        $productPrice = $this->productPriceRepository->search($criteria2, $con);
        
        return $this->renderStorefront('@Storefront/storefront/page/content/index.html.twig', [
            'products' => $products,
            'productPrice' => $productPrice,
        ]);
    }
}

Then you need to create routes.xml file:

/custom/plugins/PluginName/src/Resources/config/routes.xml

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing
        http://symfony.com/schema/routing/routing-1.0.xsd">

    <import resource="../../Controller" type="annotation" />
</routes>

Then Next you need to create services.xml

/custom/plugins/PluginName/src/Resources/config/services.xml

<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
    <services>
        <service id="PluginName\Controller\ProductController" public="true">
            <argument type="service" id="product.repository"/>
            <call method="setContainer">
                <argument type="service" id="service_container"/>
            </call>
        </service>
    </services>
</container>

Here I am creating two pages to show the product data on html.twig file
custom/plugins/PluginName/src/Resources/views/storefront/page/content/index.html.twig

{% sw_extends '@Storefront/storefront/page/content/index.html.twig' %}

{% block base_main_inner %}
    <div class="container-main">
        {% block page_content %}
            {% block cms_content %}
                <div class="cms-page">
                    {% block page_content_blocks %}
                        {% sw_include "@Storefront/storefront/page/content/product_detail.html.twig" %}
                    {% endblock %}
                </div>
            {% endblock %}
        {% endblock %}
    </div>
{% endblock %}

custom/plugins/PluginName/src/Resources/views/storefront/page/content/product_detail.html.twig

This code will show the Product detail on the page I have only 3 products you can show more products according to your need:

<div class="cms-block product-listing-part pos-1 cms-block-product-three-column section-products" style="">
    <div class="cms-block-container" style="padding: 20px 20px 20px 20px;">
        <div class="cms-block-container-row row cms-row ">
            {% set i = 0 %}
            
            {% for product in products %}
                {% if i <= 2 %}
                {% set i = (i+1) %}
                <div class="col-md-4 card-col" data-cms-element-id="d3c7873569b844239e5756f6a89c1f7f">
                    <div class="cms-element-product-box">
                        <div class="card product-box box-minimal">
                            <div class="card-body">
                                <div class="product-badges"></div>
                                    <meta  content="">
                                    <meta  content="SW10011">
                                    <div class="product-image-wrapper">
                                        <a href="{{ seoUrl('frontend.detail.page', {'productId': product.id}) }}" title="AIX Rosé Copy" class="product-image-link is-standard" "="">
                                            
                                            {% for element in product.media.elements %}
                                                {% if element.id == product.coverId %}
                                                    <img src="{{element.media.url}}" class="product-image is-standard" alt="{{product.translated.name}}" title="{{product.translated.name}}">
                                                {%endif%}
                                            {% endfor %}
                                        </a>
                                    </div>

                                    <div class="product-info">
                                        <span class="product-subtext">
                                            {% set comma = null %}{% for element in product.properties.elements %}{{(comma ~ ' ' ~ element.translated.name)|trim|trans}}{% set comma=','%}{% endfor %}
                                        </span>

                                        <a href="{{ seoUrl('frontend.detail.page', {'productId': product.id}) }}" class="product-name" title="{{product.translated.name}}">{{product.translated.name}}</a>
                                        <div class="product-price-info">

                                            <div class="product-price-wrapper">
                                                <span class="product-price">
                                                    {% set listPrice = 0 %}
                                                    {% for element in product.cheapestPrice.price.elements %}
                                                        {% if element.listPrice != null %}
                                                            {{element.listPrice.net|currency}}{{ "general.star"|trans|sw_sanitize }}
                                                            {% set listPrice = element.listPrice.net %}
                                                        {%endif%}
                                                    {% endfor %}
                                                </span>
                                            </div>
                                        <br>
                                        <p class="product-price-unit">
                                            <span class="price-unit-content">
                                                {{product.purchaseUnit}} {{product.unit.translated.name}}
                                                {# for element in product.cheapestPriceContainer.value #}
                                                    {#element.default.purchase_unit#}
                                                {# endfor #}
                                            </span>

                                            <span class="price-unit-reference">
                                                {% set pricePerUnit = (((listPrice/product.purchaseUnit)*product.referenceUnit)|number_format(2))*1 %}

                                                ({{pricePerUnit|currency }} {{ "general.star"|trans|sw_sanitize }} / {{product.referenceUnit}} {{product.unit.translated.name}})
                                            </span>
                                            <br>
                                             {% set taxText = "general.grossTaxInformation"|trans|sw_sanitize %}
                                             {% if taxText == null or taxText == ''%}
                                             {% set taxText = "general.netTaxInformation"|trans|sw_sanitize %}
                                             {% endif %}
                                            <span class="product-detail-tax">
                                                {{taxText}}
                                            </span>
                                        </p>
                                    </div>


                                    

                                    <input type="hidden" name="product-name" value="{{product.translated.name}}">
                                    <input type="hidden" name="product-id" value="{{product.id}}">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                {% endif %}
            {% endfor %}
            
        </div>
    </div>
</div>
Avatar photo
Author

Founder and tech lead at Emizentech, Mr. Vivek has over ten years of experience in developing IT infrastructures and solutions. With his profound knowledge in eCommerce technologies like Shopware, Magento, and Shopify, Mr. Vivek has been assisting SMEs to enterprises across the globe by developing and maintaining their eCommerce applications. Technology innovation and trends insight come easy to Vivek with his thorough knowledge in the eCommerce domain. See him talking about ideas, trends, and technology in this blog. To know more about how Team Vivek can assist you in your eCommerce strategy? Connect team Vivek here.

whatsapp