How is the integration with twig in these new versions? In 2.8 the setTemplate methods were deprecated and removed in 3.0.
In 2.7 I use the same Action for both html and json responses and FOS Rest decided that Response generate based on Accept
the Controller\Annotations\View was also removed. so i guess we need to do it via ViewHandler or something like that.
That's correct, if you want to use the same action in an HTML context too, you will need to write a bit of code yourself that deals with the template rendering.
@xabbuh no problem with that, i get it that handling twig is sort of out of scope of this bundle. but at the same time, it was pretty useful, especially the View etc annotations. so, what about extracting this mechanism to a standalone repo, let's say "fosrest-twig-bridge", so we don't need to reinvent the wheel?
Sure, if you like to do that, there's absolutely nothing forbidding that. The license allows to reuse the code. Note that the Sulu team did something similar with the routing support.
Some example of how to integrate with 3.x?
@gdbonino well, the simplest & fastest would be this:
set the View data to array like [ 'data' => $myData, 'template' => 'path/to/template.html.twig', 'templateVar' => 'data' ]. then, use custom ViewHandler (or View Response listener) , in which inject Twig and for html format pass this to twig & render, for other formats just replace the actual data array with `$data['data']' member.
Thanks!
Something like this:
<?php declare(strict_types=1);
namespace App\ViewHandler;
use FOS\RestBundle\View\View;
use FOS\RestBundle\View\ViewHandlerInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Twig\Environment;
class FOSRestViewHandlerAdapter implements ViewHandlerInterface
{
private ViewHandlerInterface $decorated;
private Environment $twig;
private RequestStack $requestStack;
public function __construct(ViewHandlerInterface $decorated, Environment $twig, RequestStack $requestStack)
{
$this->decorated = $decorated;
$this->twig = $twig;
$this->requestStack = $requestStack;
}
public function supports($format): bool
{
return $this->decorated->supports($format);
}
public function registerHandler($format, $callable): void
{
$this->decorated->registerHandler($format, $callable);
}
public function handle(View $view, Request $request = null): Response
{
$data = $view->getData();
if ($request === null) {
$request = $this->requestStack->getCurrentRequest();
}
if ('html' === ($view->getFormat() ?: $request->getRequestFormat()) && is_array($data)) {
$template = $data['template'];
$templateVar = $data['templateVar'] ?? 'data';
$templateData = $data['templateData'] ?? [];
$data = $data['data'];
if ($data instanceof FormInterface) {
$data = $data->createView();
}
$templateData[$templateVar] = $data;
$response = $this->twig->render($template, $templateData);
return new Response($response);
}
if (is_array($data)) {
$view->setData($data['data'] ?? $data);
}
return $this->decorated->handle($view, $request);
}
public function createRedirectResponse(View $view, $location, $format): Response
{
return $this->decorated->createRedirectResponse($view, $location, $format);
}
public function createResponse(View $view, Request $request, $format): Response
{
return $this->decorated->createResponse($view, $request, $format);
}
}
with services.yaml:
services:
App\ViewHandler\FOSRestViewHandlerAdapter:
decorates: 'fos_rest.view_handler'
Most helpful comment
Something like this:
with
services.yaml: