63 lines
2.2 KiB
PHP
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);
|
|
}
|
|
}
|