Search code examples
twigshopwareshopware6

How to get current product or category url equivalent for all other channels in shopware 6?


I need to build a "channel switcher" in shopware6. How can I access current (Product)URL equivalents for all or some other channels in this shop? It should work like a language switcher, keeping the current viewed product or category and redirecting to other channel.

I know how to get current seoUrl of product: {{ seoUrl('frontend.detail.page', { productId: page.product.id }) }}

but is there a way to get all other seoUrls for all other selling channels with the same product.id? And the same for categories?


Solution

  • Rough approach to get all language links

    Looking at

    \Shopware\Core\Framework\Adapter\Twig\Extension\SeoUrlFunctionExtension which is handling the seoUrl() in twig it looks like this:

    public function seoUrl(string $name, array $parameters = []): string
    {
        return $this->seoUrlReplacer->generate($name, $parameters);
    }
    

    This resolves to

    \Shopware\Core\Content\Seo\SeoUrlPlaceholderHandler::generate which always uses the current request:

    public function generate($name, array $parameters = []): string
    {
        $path = $this->router->generate($name, $parameters, RouterInterface::ABSOLUTE_PATH);
    
        $request = $this->requestStack->getMainRequest();
        $basePath = $request ? $request->getBasePath() : '';
        $path = $this->removePrefix($path, $basePath);
    
        return self::DOMAIN_PLACEHOLDER . $path . '#';
    }
    

    Which boils down to \Shopware\Storefront\Framework\Routing\Router::generate

    As an approach I would suggest to dig into those functions. They directly access the current request and context. Thanks to dependency injection, you can create those instances yourself with the target context and an artificial request containing the right base URL from the target channel.

    Approach similar to the language switcher (redirect after POST)

    The above approach might be quite complicated, so looking at what the language switcher does:

    • It just includes the language IDs
    • On selection posts to \Shopware\Storefront\Controller\ContextController::switchLanguage
    • Which does the redirect

    Example Payload of the request:

    languageId: 2fbb5fe2e29a4d70aa5854ce7ce3ff0b
    redirectTo: frontend.navigation.page
    redirectParameters[navigationId]: a11f6b46948c47a7b2c2ac874704fff6
    

    I think you can extend that script for your channel switcher and add the sales channel id to the request,

    then you can reuse / copy or even decorate the switchLanguage controller. You just need to pass in the right context of the target sales channel and it should redirect to the correct URL.