8000 feature #51327 [FrameworkBundle] Add `AbstractController::renderBlock… · symfony/symfony@9a0f178 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9a0f178

Browse files
feature #51327 [FrameworkBundle] Add AbstractController::renderBlock() and renderBlockView() (nicolas-grekas)
This PR was merged into the 6.4 branch. Discussion ---------- [FrameworkBundle] Add `AbstractController::renderBlock()` and `renderBlockView()` | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - This would be especially useful when generating turbo-stream responses. Right now, [the doc](https://symfony.com/bundles/ux-turbo/current/index.html#coming-alive-with-turbo-streams) recommends creating new partial templates, but this increases the complexity and scatters HTML fragments. Instead, we could encourage using twig blocks. Adding this could help remove some boilerplate. before (using blocks): ```php return new Response($this->container->get('twig')->load('foo.html.twig')->renderBlock('the_block', $context)); ``` after: ```php return $this->renderBlock('foo.html.twig', 'the_block', $context); ``` Commits ------- fbf3814 [FrameworkBundle] Add `AbstractController::renderBlock()` and `renderBlockView()`
2 parents 4439602 + fbf3814 commit 9a0f178

File tree

2 files changed

+60
-24
lines changed

2 files changed

+60
-24
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
6.4
55
---
66

7+
* Add `AbstractController::renderBlock()` and `renderBlockView()`
78
* Add native return type to `Translator` and to `Application::reset()`
89
* Deprecate the integration of Doctrine annotations, either uninstall the `doctrine/annotations` package or disable the integration by setting `framework.annotations` to `false`
910
* Enable `json_decode_detailed_errors` context for Serializer by default if `kernel.debug` is true and the `seld/jsonlint` package is installed

src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php

+59-24
Original file line numberDiff line numberDiff line change
@@ -229,17 +229,17 @@ protected function denyAccessUnlessGranted(mixed $attribute, mixed $subject = nu
229229
*/
230230
protected function renderView(string $view, array $parameters = []): string
231231
{
232-
if (!$this->container->has('twig')) {
233-
throw new \LogicException('You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".');
234-
}
235-
236-
foreach ($parameters as $k => $v) {
237-
if ($v instanceof FormInterface) {
238-
$parameters[$k] = $v->createView();
239-
}
240-
}
232+
return $this->doRenderView($view, null, $parameters, __FUNCTION__);
233+
}
241234

242-
return $this->container->get('twig')->render($view, $parameters);
235+
/**
236+
* Returns a rendered block from a view.
237+
*
238+
* Forms found in parameters are auto-cast to form views.
239+
*/
240+
protected function renderBlockView(string $view, string $block, array $parameters = []): string
241+
{
242+
return $this->doRenderView($view, $block, $parameters, __FUNCTION__);
243243
}
244244

245245
/**
@@ -250,21 +250,18 @@ protected function renderView(string $view, array $parameters = []): string
250250
*/
251251
protected function render(string $view, array $parameters = [], Response $response = null): Response
252252
{
253-
$content = $this->renderView($view, $parameters);
254-
$response ??= new Response();
255-
256-
if (200 === $response->getStatusCode()) {
257-
foreach ($parameters as $v) {
258-
if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) {
259-
$response->setStatusCode(422);
260-
break;
261-
}
262-
}
263-
}
264-
265-
$response->setContent($content);
253+
return $this->doRender($view, null, $parameters, $response, __FUNCTION__);
254+
}
266255

267-
return $response;
256+
/**
257+
* Renders a block in a view.
258+
*
259+
* If an invalid form is found in the list of parameters, a 422 status code is returned.
260+
* Forms found in parameters are auto-cast to form views.
261+
*/
262+
protected function renderBlock(string $view, string $block, array $parameters = [], Response $response = null): Response
263+
{
264+
return $this->doRender($view, $block, $parameters, $response, __FUNCTION__);
268265
}
269266

270267
/**
@@ -431,4 +428,42 @@ protected function sendEarlyHints(iterable $links = [], Response $response = nul
431428

432429
return $response;
433430
}
431+
432+
private function doRenderView(string $view, ?string $block, array $parameters, string $method): string
433+
{
434+
if (!$this->container->has('twig')) {
435+
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));
436+
}
437+
438+
foreach ($parameters as $k => $v) {
439+
if ($v instanceof FormInterface) {
440+
$parameters[$k] = $v->createView();
441+
}
442+
}
443+
444+
if (null !== $block) {
445+
return $this->container->get('twig')->load($view)->renderBlock($block, $parameters);
446+
}
447+
448+
return $this->container->get('twig')->render($view, $parameters);
449+
}
450+
451+
private function doRender(string $view, ?string $block, array $parameters, ?Response $response, string $method): Response
452+
{
453+
$content = $this->doRenderView($view, $block, $parameters, $method);
454+
$response ??= new Response();
455+
456+
if (200 === $response->getStatusCode()) {
457+
foreach ($parameters as $v) {
458+
if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) {
459+
$response->setStatusCode(422);
460+
break;
461+
}
462+
}
463+
}
464+
465+
$response->setContent($content);
466+
467+
return $response;
468+
}
434469
}

0 commit comments

Comments
 (0)
0