diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 859a64b88d9ae..8dda43a6d95a5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -4,6 +4,7 @@ CHANGELOG 6.4 --- + * Add `AbstractController::renderBlock()` and `renderBlockView()` * Add native return type to `Translator` and to `Application::reset()` * Deprecate the integration of Doctrine annotations, either uninstall the `doctrine/annotations` package or disable the integration by setting `framework.annotations` to `false` * Enable `json_decode_detailed_errors` context for Serializer by default if `kernel.debug` is true and the `seld/jsonlint` package is installed diff --git a/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php b/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php index 4590b5a18bd93..9bcc34606135c 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php +++ b/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php @@ -229,17 +229,17 @@ protected function denyAccessUnlessGranted(mixed $attribute, mixed $subject = nu */ protected function renderView(string $view, array $parameters = []): string { - if (!$this->container->has('twig')) { - throw new \LogicException('You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".'); - } - - foreach ($parameters as $k => $v) { - if ($v instanceof FormInterface) { - $parameters[$k] = $v->createView(); - } - } + return $this->doRenderView($view, null, $parameters, __FUNCTION__); + } - return $this->container->get('twig')->render($view, $parameters); + /** + * Returns a rendered block from a view. + * + * Forms found in parameters are auto-cast to form views. + */ + protected function renderBlockView(string $view, string $block, array $parameters = []): string + { + return $this->doRenderView($view, $block, $parameters, __FUNCTION__); } /** @@ -250,21 +250,18 @@ protected function renderView(string $view, array $parameters = []): string */ protected function render(string $view, array $parameters = [], Response $response = null): Response { - $content = $this->renderView($view, $parameters); - $response ??= new Response(); - - if (200 === $response->getStatusCode()) { - foreach ($parameters as $v) { - if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) { - $response->setStatusCode(422); - break; - } - } - } - - $response->setContent($content); + return $this->doRender($view, null, $parameters, $response, __FUNCTION__); + } - return $response; + /** + * Renders a block in a view. + * + * If an invalid form is found in the list of parameters, a 422 status code is returned. + * Forms found in parameters are auto-cast to form views. + */ + protected function renderBlock(string $view, string $block, array $parameters = [], Response $response = null): Response + { + return $this->doRender($view, $block, $parameters, $response, __FUNCTION__); } /** @@ -431,4 +428,42 @@ protected function sendEarlyHints(iterable $links = [], Response $response = nul return $response; } + + private function doRenderView(string $view, ?string $block, array $parameters, string $method): string + { + if (!$this->container->has('twig')) { + throw new \LogicException(sprintf('You cannot use the "%s" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".', $method)); + } + + foreach ($parameters as $k => $v) { + if ($v instanceof FormInterface) { + $parameters[$k] = $v->createView(); + } + } + + if (null !== $block) { + return $this->container->get('twig')->load($view)->renderBlock($block, $parameters); + } + + return $this->container->get('twig')->render($view, $parameters); + } + + private function doRender(string $view, ?string $block, array $parameters, ?Response $response, string $method): Response + { + $content = $this->doRenderView($view, $block, $parameters, $method); + $response ??= new Response(); + + if (200 === $response->getStatusCode()) { + foreach ($parameters as $v) { + if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) { + $response->setStatusCode(422); + break; + } + } + } + + $response->setContent($content); + + return $response; + } }