Menu Close
    Searching for an experienced Shopware Development Company ?

    How to add the custom listing in the storefront at the Shopware

    In this blog, you are going to learn “How to add the custom listing in the storefront at the Shopware.”
    I hope you know the directory structure of Shopware 6 plugin, if you don’t know, see here-

    New product listing filters can be registered via the event \Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent. This event will be fire when the Criteria object is creating for the listing. The event can use to respond to the request to add new filters or aggregations to the Criteria object. Afterward, it is important to register for the event \Shopware\Core\Content\Product\Events\ProductListingResultEvent to add the filtered values to the result. 

    namespace Shopware\Core\Content\Product\SalesChannel\Listing;
    use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
    use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
    use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Metric\EntityAggregation;
    use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Symfony\Component\HttpFoundation\Request;
    class ExampleListingSubscriber implements EventSubscriberInterface
        public static function getSubscribedEvents()
            return [
                ProductListingCriteriaEvent::class => 'handleRequest',
                ProductListingResultEvent::class => 'handleResult',
        public function handleRequest(ProductListingCriteriaEvent $event)
            $criteria = $event->getCriteria();
            $request = $event->getRequest();
                new EntityAggregation('manufacturer', 'product.manufacturerId', 'product_manufacturer')
            $ids = $this->getManufacturerIds($request);
            if (empty($ids)) {
            $criteria->addPostFilter(new EqualsAnyFilter('product.manufacturerId', $ids));
        public function handleResult(ProductListingResultEvent $event)
            $event->getResult()->addCurrentFilter('manufacturer', $this->getManufacturerIds($event->getRequest()));
        private function getManufacturerIds(Request $request): array
            $ids = $request->query->get('manufacturer', '');
            $ids = explode('|', $ids);
            return array_filter($ids);

    The sorting in the product listing is controlled by the \Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingSortingRegistry. All classes in this registry represent a selectable sort in the listing. The \Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingSorting can easily be defined via DI-Container. By the container tag shopware.sales_channel.product_listing.sorting these are then registered in the registry.


    <service id="product_listing.sorting.name_descending" class="Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingSorting">
        <argument type="collection">
            <argument key="">desc</argument>
        <tag name="shopware.sales_channel.product_listing.sorting" />
    $sorting = new ProductListingSorting(
            '' => 'desc',
            ''   => 'asc'

    Entity extension

    If you’re wondering how to extend existing core entities, this ‘HowTo’ will have you covered. Do not confuse entity extensions with entities’ custom fields though, as they serve a different purpose. In short: Extensions are technical and not configurable by the admin user just like that. Also, they can deal with more complex types than scalar ones. Custom fields are, by default, configurable by the admin user in the administration and they mostly support scalar types, e.g. a text-field, a number field 

    Own entities can be integrated into the core via the corresponding entry in the services.xml. To extend existing entities, the abstract class \Shopware\Core\Framework\DataAbstractionLayer\EntityExtension is used. The EntityExtension must define which entity should extend in the method. Once this extension access in the system, the extension can add more fields to it:

    <?php declare(strict_types=1);
    namespace Webkul\EntityExtension\Extension\Content\Product;
    use Shopware\Core\Content\Product\ProductDefinition;
    use Shopware\Core\Framework\DataAbstractionLayer\EntityExtension;
    use Shopware\Core\Framework\DataAbstractionLayer\Field\Flag\Runtime;
    use Shopware\Core\Framework\DataAbstractionLayer\Field\ObjectField;
    use Shopware\Core\Framework\DataAbstractionLayer\FieldCollection;
    class CustomExtension extends EntityExtension
        public function extendFields(FieldCollection $collection): void
                (new ObjectField('custom_struct', 'customStruct'))->addFlags(new Runtime())
        public function getDefinitionClass(): string
            return ProductDefinition::class;

    This example adds another association named custom_struct to the ProductDefinition. The Runtime flag tells the data abstraction layer, that you’re going to take care of the field’s content yourself. Have a look at our detailed list of flags and what their purpose is, or find out which field types are available in Shopware 6.

    So, time to take care of the product entities’ new field yourself. You’re going to need a new subscriber for this. Have a look here to find out how to properly add your own subscriber class.

    <?php declare(strict_types=1);
    namespace Webkul\EntityExtension\Subscriber;
    use Swag\EntityExtension\Struct\MyCustomStruct;
    use Shopware\Core\Content\Product\ProductEntity;
    use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use Shopware\Core\Content\Product\ProductEvents;
    class MySubscriber implements EventSubscriberInterface
        public static function getSubscribedEvents(): array
            return [
                ProductEvents::PRODUCT_LOADED_EVENT => 'onProductsLoaded'
        public function onProductsLoaded(EntityLoadedEvent $event): void
            /** @var ProductEntity $productEntity */
            foreach ($event->getEntities() as $productEntity) {
                $productEntity->addExtension('custom_struct', new MyCustomStruct());

    As you can see, the subscriber listens to the PRODUCT_LOADED event, which is triggered every time a set of products is requested. The listener onProductsLoaded then adds a custom struct into the new field.


    <?xml version="1.0" ?>
    <container xmlns=""
            <service id="Webkul\EntityExtension\Extension\Content\Product\CustomExtension">
                <tag name="shopware.entity.extension"/>
            <service id="Webkul\EntityExtension\Subscriber\MySubscriber">
                <tag name="kernel.event_subscriber" />

    I hope it will help you. Thanks for reading. Happy Coding 🙂

    Please explore our shopware development services and Quality shopware extensions.

    Thank You.

    . . .
    Discuss on Helpdesk

    Leave a Comment

    Your email address will not be published. Required fields are marked*


  • Rafaëla Bg
    Hi, would you please make a tutorial on how to show the top sellers product for a given category ?

    Good job for the tutorials.

    • Adarsh Shukla (Moderator)
      Hello, Thanks for your valuable comment. Glad to know that it helps you. We will create a user guide. For any other queries, please mail us at [email protected]
  • Back to Top