skip to Main Content

I am trying to lookup the seoUrl of variants displayed on a product detail page – in the configurator.html.twig file. I have the option Id and have tried passing it as productId for the seoUrl function – but it doesn’t return the correct seoUrl.

Searching for a solution, I found this question: Show all variations on the product detail page in Shopware 6 – which also lacks an answer.
But it hinted that you should add the data using a Subscriber – is that really necessary?

2

Answers


  1. Yes, the best solution would be to fetch all variants based on the parentId in a subscriber.

    This is necessary because you want to have more data then just the productId. You should also consider this information as necessary:

    1. minPurchase
    2. calculatedMaxPurchase
    3. purchaseSteps

    And optional:

    1. packUnit
    2. packUnitPlural

    Without the necessary product information the end user will possibly encounter errors when adding a product with a invalid quantity to the cart.

    Login or Signup to reply.
  2. You may decorate the ProductDetailRoute, fetch the parent and with its children association and iterate them in the storefront template.

    <service id="MyPluginCoreContentProductSalesChannelDetailProductDetailRouteDecorator" public="true" decorates="ShopwareCoreContentProductSalesChannelDetailProductDetailRoute">
        <argument type="service" id="MyPluginCoreContentProductSalesChannelDetailProductDetailRouteDecorator.inner"/>
        <argument type="service" id="sales_channel.product.repository"/>
    </service>
    
    class ProductDetailRouteDecorator extends AbstractProductDetailRoute
    {
        private SalesChannelRepositoryInterface $productRepository;
    
        private AbstractProductDetailRoute $decorated;
    
        public function __construct(
            AbstractProductDetailRoute $decorated,
            SalesChannelRepositoryInterface $productRepository
        ) {
            $this->decorated = $decorated;
            $this->productRepository = $productRepository;
        }
    
        public function getDecorated(): AbstractProductDetailRoute
        {
            return $this->decorated;
        }
    
        public function load(string $productId, Request $request, SalesChannelContext $context, Criteria $criteria): ProductDetailRouteResponse
        {
            $response = $this->getDecorated()->load($productId, $request, $context, $criteria);
            $product = $response->getProduct();
    
            if (!$product->getParentId()) {
                return $response;
            }
    
            $criteria = new Criteria([$product->getParentId()]);
            $criteria->addAssociation('children');
    
            $parent = $this->productRepository->search($criteria, $context)->first();
            $product->setParent($parent);
    
            return new ProductDetailRouteResponse($product, $response->getConfigurator());
        }
    }
    
    {% if page.product.parent.children is defined %}
        {% for child in page.product.parent.children %}
            {{ seoUrl('frontend.detail.page', { productId: child.id }) }}
        {% endfor %}
        <br>
    {% endif %}
    

    Sample output:

    http://localhost/Intelligent-Marble-Ultra-Beef/0491895660e94e32938022263595f861
    http://localhost/Intelligent-Marble-Ultra-Beef/7c9f91d9051e40e0ba13d0e885e98d83
    http://localhost/Intelligent-Marble-Ultra-Beef/f25c641abee446df82e1227cf200186c
    

    Variation on this solution

    A little more complex but with a lesser performance impact:

    $criteria = new Criteria();
    $criteria->addFilter(new EqualsFilter('parentId', $product->getParentId()));
    
    $ids = $this->productRepository->searchIds($criteria, $context)->getIds();
    $product->addExtension('childrenIds', new ArrayStruct($ids));
    
    {% if page.product.extensions.childrenIds is defined %}
        {% for childId in page.product.extensions.childrenIds.all() %}
            {{ seoUrl('frontend.detail.page', { productId: childId }) }}
            <br>
        {% endfor %}
    {% endif %}
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search