Controller

Controller

The default controller of a node is App\Core\Controller\Site\PageController::show. PageController extends Symfony\Bundle\FrameworkBundle\Controller\AbstractController and implements very basic features: a Response builder which retrieves the good template and injects variables to the view.

To create a custom controller, do this way:

// src/Controller/MyController.php
namespace App\Controller;

use App\Core\Controller\Site\PageController;

class MyController extends PageController
{
    public function myAction()
    {
        if (!$this->siteRequest->getPage()) {
            throw $this->createNotFoundException();
        }

        return $this->defaultRender($this->siteRequest->getPage()->getTemplate(), [
            // view datas
        ]);
    }
}

Then edit config/packages/app.yaml and add your controller:

core:
    site:
        controllers:
            - {name: 'My action', action: 'App\Controller\MyController::myAction'}

UrlGenerator

If your controller represents entities and if the associated node is visible in the sitemap, you can use a App\Core\Annotation\UrlGenerator in annotations and implement a generator. See the example below.

// src/UrlGenerator/MyEntityGenerator
namespace App\UrlGenerator;

use App\Core\Entity\Site\Node;
use App\Repository\MyEntityRepositoryQuery;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class MyEntityGenerator
{
    protected MyEntityRepositoryQuery $query;
    protected UrlGeneratorInterface $urlGenerator;

    public function __construct(MyEntityRepositoryQuery $query, UrlGeneratorInterface $urlGenerator)
    {
        $this->query = $query;
        $this->urlGenerator = $urlGenerator;
    }

    public function myActionGenerator(Node $node, array $options): array
    {
        $entities = $this->query->create()->find();

        $urls = [];

        foreach ($entities as $entity) {
            $urls[] = $this->urlGenerator->generate(
                $node->getRouteName(),
                [
                    'entity' => $entity->getId(),
                ],
                UrlGeneratorInterface::ABSOLUTE_URL
            );
        }

        return $urls;
    }
}

Then, the have to annotate the controller like this (note: options is optional):

// src/Controller/MyController.php
namespace App\Controller;

use App\Core\Annotation\UrlGenerator;
use App\Core\Controller\Site\PageController;
use App\UrlGenerator\MyEntityGenerator;

class MyController extends PageController
{
    /**
     * @UrlGenerator(service=MyEntityGenerator::class, method="myActionGenerator", options={})
     */
    public function myAction(MyEntity $entity)
    {
        // do stuff
    }
}

Finally, update config/services.yaml:

services:
    # ...

    App\UrlGenerator\MyEntityGenerator:
        public: true