# 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:

```php-inline title="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:

```yaml
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.

```php-inline title="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(),
					'_domain' => $options['_domain'],
                ],
                UrlGeneratorInterface::ABSOLUTE_URL
            );
        }

        return $urls;
    }
}
```

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

```php-inline title="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`:

```yaml
services:
    # ...

    App\UrlGenerator\MyEntityGenerator:
        public: true
```
