Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stenope doesn't generate pages for localized routes #187

Open
Alexandre-Fernandez opened this issue Jul 5, 2024 · 3 comments
Open

Stenope doesn't generate pages for localized routes #187

Alexandre-Fernandez opened this issue Jul 5, 2024 · 3 comments

Comments

@Alexandre-Fernandez
Copy link

Alexandre-Fernandez commented Jul 5, 2024

I have the following config :

config/services.yaml

parameters:
  app.supported_locales: "en|fr"

src/Controller/AppController.php

    #[Route("/{_locale<%app.supported_locales%>}", name: "index")]
    public function index(): Response
    { /* ... */ }

When I run php bin/console -e prod stenope:build ./static stenope doesn't generate any page for my route.

EDIT:
I also tried replacing my custom parameter with enabled_locales, and it still doesn't work, is there a workaround ?

@ogizanagi
Copy link
Member

ogizanagi commented Jul 5, 2024

Well, Stenope cannot guess any route containing parameters in its path. It'll start by gathering every routes without parameters, and crawl dynamically the site by collecting URLs rendered by the Symfony URL generator.

In order to crawl these, you need at least one route, without any path parameters, rendering a page referencing the routes with each of the expected values.

If you don't have such pages in your app, nor want to, an alternative is to create a listener on the Stenope build command, in order to call the URL generator for such routes, allowing to collect them.

We have such a listener for routes that are not referenced anywhere in our templates here.

Do the same to generate the URLs of the main entrypoints of your app, in each locale, then Stenope will do the rest.

@Alexandre-Fernandez
Copy link
Author

Alexandre-Fernandez commented Jul 5, 2024

Well, Stenope cannot guess any route containing parameters in its path. It'll start by gathering every routes without parameters, and crawl dynamically the site by collecting URLs rendered by the Symfony URL generator.

In order to crawl these, you need at least one route, without any path parameters, rendering a page referencing the routes with each of the expected values.

If you don't have such pages in your app, nor want to, an alternative is to create a listener on the Stenope build command, in order to call the URL generator for such routes, allowing to collect them.

We have such a listener for routes that are not referenced anywhere in our templates here.

Do the same to generate the URLs of the main entrypoints of your app, in each locale, then Stenope will do the rest.

If stenope can access kernel.enabled_locales then I'm guessing it can guess the urls by replacing _locale, if it doesn't have access to that parameter then it would be nice if you could provide it in the stenope yaml config.

Thanks for the tips, here's my current workaround for parameterless routes :

<?php

namespace App\Bundle\Stenope;

use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleCommandEvent;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RouterInterface;

class StenopeBuildListener implements EventSubscriberInterface
{
    public function __construct(
        private readonly UrlGeneratorInterface $urlGenerator,
        private readonly RouterInterface $router,
        #[Autowire("%kernel.enabled_locales%")]
        private array $enabledLocales,
    ) {
    }

    public static function getSubscribedEvents(): array
    {
        return [ConsoleEvents::COMMAND => "onCommand"];
    }

    public function onCommand(ConsoleCommandEvent $event): void
    {
        if (null !== $event->getCommand() && "stenope:build" !== $event->getCommand()->getName()) {
            return;
        }

        $this->generateLocalizedUrls();
    }

    private function generateLocalizedUrls()
    {
        foreach ($this->router->getRouteCollection() as $name => $route) {
            if (!str_contains($route->getPath(), "_locale")) { // no unlocalized routes
                continue;
            }
            if (!$route->getRequirement("_locale") || count($route->getRequirements()) !== 1) { // no routes with other params than _locale
                continue;
            }
            foreach ($this->enabledLocales as $locale) {
                $this->urlGenerator->generate($name, [
                    "_locale" => $locale,
                ]);
            }
        }
    }
}

@indyjonesnl
Copy link

@Alexandre-Fernandez I ran into the same problem and fixed it (temporarily) with master...indyjonesnl:Stenope:patch-1

There are prettier / better solutions, I agree. But this does allow me to use localized routes with Stenope.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants