skip to Main Content

I’m trying to add a custom dynamic SEO url, but when I save the entity in the administration I’m getting the error Route by name frontend.faq.category not found. The entity is saved, but the URL isn’t generated.

What am I missing and how can I fix this? Is it something in the administration that I have to fix or is there something wrong/a typo in one of my files?

I’ve got a custom controller with this defined:

/**
     * @RouteScope(scopes={"storefront"})
     * @Route("/faq/category/{faqCategoryId}", name="frontend.faq.category", methods={"GET"}, defaults={"XmlHttpRequest": true})
     */

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="../../Storefront/Controller/*Controller.php" type="annotation" />
</routes>

Subscriber


class FAQCategorySubscriber implements EventSubscriberInterface
{
    private SeoUrlUpdater $seoUrlUpdater;

    public function __construct(SeoUrlUpdater $seoUrlUpdater) {
        $this->seoUrlUpdater = $seoUrlUpdater;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            'faq_category.written' => 'onEntityWritten'
        ];
    }

    public function onEntityWritten(EntityWrittenEvent $event): void
    {
        $this->seoUrlUpdater->update(FAQCategoryPageSeoUrlRoute::ROUTE_NAME, $event->getIds());
    }
}

SeoUrlRoute

class FAQCategoryPageSeoUrlRoute implements SeoUrlRouteInterface
{
    public const ROUTE_NAME = 'frontend.faq.category';
    public const DEFAULT_TEMPLATE = '{{ faq.category.name }}';

    private FAQCategoryDefinition $faqCategoryDefinition;

    public function __construct(FAQCategoryDefinition $faqCategoryDefinition)
    {
        $this->faqCategoryDefinition = $faqCategoryDefinition;
    }

    public function getConfig(): SeoUrlRouteConfig
    {
        return new SeoUrlRouteConfig(
            $this->faqCategoryDefinition,
            self::ROUTE_NAME,
            self::DEFAULT_TEMPLATE,
            true
        );
    }

    public function prepareCriteria(Criteria $criteria): void
    {
    }

    public function getMapping(Entity $faqcategory, ?SalesChannelEntity $salesChannel): SeoUrlMapping
    {
        if (!$faqcategory instanceof FAQCategoryEntity) {
            throw new InvalidArgumentException('Expected FAQCategoryEntity');
        }

        $faqcategoryJson = $faqcategory->jsonSerialize();

        return new SeoUrlMapping(
            $faqcategory,
            ['faqCategoryId' => $faqcategory->getId()],
            [
                'faqcategory' => $faqcategoryJson,
            ]
        );
    }
}

2

Answers


  1. Which version are you using? RouteScope had been deprecated for a while and should’ve been removed by now. Use only the Route annotation.

    use ShopwareStorefrontControllerStorefrontController;
    use SymfonyComponentHttpFoundationResponse;
    use SymfonyComponentRoutingAnnotationRoute;
    
    /**
     * @Route(defaults={"_routeScope"={"storefront"}})
     */
    class MyStorefrontController extends StorefrontController
    {
        /**
         * @Route("/faq/category/{faqCategoryId}", name="frontend.faq.category", methods={"GET"}, defaults={"XmlHttpRequest"=true})
         */
        public function myRoute(string $faqCategoryId): Response
        {
            // ..
        }
    }
    
    Login or Signup to reply.
  2. Your SeoUrlRoute class needs to receive the tag shopware.seo_url.route in the services.xml declaration.

    For example:

    <service id="MyAppFrameworkSeoFAQCategoryPageSeoUrlRoute">
        <argument type="service" id="MyAppCoreContent FAQCategoryFAQCategoryDefinition"/>
    
        <tag name="shopware.seo_url.route"/>
    </service>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search