Back to Top

How to render the page using pageLoader in Shopware 6

Updated 7 June 2020

In this blog, you are going to learn “How to render the page using pageLoader and event dispatcher in Shopware 6 at the storefront.”
I hope you know the directory structure of Shopware 6 plugin, if you don’t know, see here- https://docs.shopware.com/en/shopware-platform-dev-en/internals/directory-structure.

Firstly, you have to create a folder in <plugin root>/src. In my case, the folder name is "Test", after that, form three files.

Initially in the first file, generate a getter/setter method for the page. Then for the second file, create a loader event for the page. Now whatever you want to do on your page write in the function of the third file.
Let’s take an example:-

First file:- TestProductPage.php

class TestProductPage extends Page 
{
  public $products;
  
  public function getTestProducts()
  {
     return $this->products;
  }

  public function setTestProducts($products)
  {
     $this->products = $products;
  }
}

In above code, there is a two methods, getTestProducts() which return the products and setTestProducts() which set the products.

Start your headless eCommerce
now.
Find out More

Second file:- TestProductPageLoadedEvent.php

class TestProductPageLoadedEvent extends PageLoadedEvent
{
    /**
     * @var TestProductPage
     */
    protected $page;

    public function __construct(TestProductPage $page, SalesChannelContext $salesChannelContext, Request $request)
    {
        $this->page = $page;
        parent::__construct($salesChannelContext, $request);
    }

    public function getPage(): TestProductPage
    {
        return $this->page;
    }
}

Furthermore, use the first file as a construct and after that, we create events for the page. In my case, there is only one event i.e getPage. Likewise, you can create more events.

Third file:- TestProductPageLoader.php

class TestProductPageLoader
{
    /**
     * @var GenericPageLoader
     */
    private $genericLoader;

    /**
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;

    /**
     * @var EntityRepositoryInterface
     */
    private $testRepository;

    public function __construct(
        GenericPageLoader $genericLoader,
        EventDispatcherInterface $eventDispatcher,
        EntityRepositoryInterface $testRepository
    ) {
        $this->genericLoader = $genericLoader;
        $this->eventDispatcher = $eventDispatcher;
        $this->testRepository = $testRepository;
      }

    public function load(Request $request, SalesChannelContext $salesChannelContext): TestProductPage
    {
        $page = $this->genericLoader->load($request, $salesChannelContext);

        $page = TestProductPage::createFrom($page);

        $criteria = new Criteria();
        $testProducts = $this->testRepository->search($criteria, $salesChannelContext->getContext());
        
        $page->setTestProducts($testProducts);

        $this->eventDispatcher->dispatch(
            new TestProductPageLoadedEvent($page, $salesChannelContext, $request)
        );

        return $page;
    }
}

In this file, you have to use a generic pageLoader and an event dispatcher. Generic page loader helps to load the request of your page and event dispatcher help to dispatch the event i.e you create in the second file.

$this->genericLoader call the load function with request and sales channel parameter. $this->testRepository call search function with criteria and context parameters that fetch data from databases of test repository.

$this->eventDispatcher call the dispatch function that load the loader event of the page.

Finally, create a controller that calls the page loader of your page i.e TestProductPageLoader

class TestController extends StorefrontController
{
    /**
     * @var EntityRepositoryInterface
     */
    protected $testRepository;

    /**
     * @var TestProductPageLoader
     */
    protected $testPageLoader;

    public function __construct(EntityRepositoryInterface $testRepository, TestProductPageLoader $testPageLoader)
    {
        $this->testRepository = $testRepository;
        $this->testPageLoader = $testPageLoader;
    }

    /**
     * @Route("/test", name="test", methods={"GET"})
     */

     public function testProductOverview(Request $request, SalesChannelContext $context): Response
     {
        $page = $this->testPageLoader->load($request, $context);
        
        return $this->renderStorefront('@WebkulTest/storefront/page/test/index.html.twig', ['page' => $page]);
     }
}

$this->renderStorefront function render the twig file with data stored in the variable ‘page’.

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

. . .

Leave a Comment

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


Be the first to comment.

Back to Top

Message Sent!

If you have more details or questions, you can reply to the received confirmation email.

Back to Home