Files
kupshop/bundles/KupShop/StorybookBundle/Controller/StorybookController.php
2025-08-02 16:30:27 +02:00

63 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
namespace KupShop\StorybookBundle\Controller;
use KupShop\ComponentsBundle\Utils\ComponentsLocator;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Util\System\UrlFinder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Twig\Environment;
class StorybookController extends AbstractController
{
public function __construct(
private readonly Environment $twig,
) {
}
private function parseRequestQuery(Request $request): array
{
return array_map(function ($item) {
if ($result = json_decode($item, false)) {
return $result;
}
return $item;
}, $request->query->all());
}
#[Route(
'/storybook/component/{id}',
// The id can contain slashes, so we need to use a regex
requirements: ['id' => '.+'],
)]
public function serveStorybookComponent(Request $request, string $id, ComponentsLocator $componentsLocator, UrlFinder $urlFinder): Response
{
$request->attributes->set('_storybook', true);
// $id is the path to the Twig template in the storybook/ directory
// Args are read from the query parameters and sent to the template
$component = $componentsLocator->findComponentByName($id);
// Force to generate absolute urls
$urlFinder->setCdnPrefix(rtrim(Config::get()['Addr']['full'], '/'));
$template = preg_replace('/\.\d+\.html\.twig/', '.stories.html.twig', $component['template']);
$template_fallback = '@Components/storybook/preview.html.twig';
$context = ['args' => $this->parseRequestQuery($request), 'id' => $id];
$content = $this->twig->render($this->twig->resolveTemplate([$template, $template_fallback]), $context);
// During development, storybook is served from a different port than the Symfony app
// You can use nelmio/cors-bundle to set the Access-Control-Allow-Origin header correctly
$headers = ['Access-Control-Allow-Origin' => '*'];
return new Response($content, Response::HTTP_OK, $headers);
}
}