Skip to content

Commit

Permalink
Support yield rendering strategy in Twig 3.9+
Browse files Browse the repository at this point in the history
  • Loading branch information
emodric committed May 21, 2024
1 parent ecf91a4 commit 6e4feb5
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 18 deletions.
2 changes: 2 additions & 0 deletions bundles/LayoutsBundle/Templating/Twig/Node/DefaultContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@

namespace Netgen\Bundle\LayoutsBundle\Templating\Twig\Node;

use Twig\Attribute\YieldReady;
use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Node;

#[YieldReady]
final class DefaultContext extends Node
{
public function __construct(AbstractExpression $expr, int $line = 0, ?string $tag = null)
Expand Down
17 changes: 15 additions & 2 deletions bundles/LayoutsBundle/Templating/Twig/Node/RenderZone.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
use Netgen\Layouts\API\Values\Layout\Zone;
use Netgen\Layouts\View\Twig\ContextualizedTwigTemplate;
use Netgen\Layouts\View\ViewInterface;
use Twig\Attribute\YieldReady;
use Twig\Compiler;
use Twig\Environment;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Node;

use const PHP_EOL;

#[YieldReady]
final class RenderZone extends Node
{
public function __construct(AbstractExpression $zone, ?AbstractExpression $context = null, int $line = 0, ?string $tag = null)
Expand All @@ -36,9 +39,8 @@ public function compile(Compiler $compiler): void
->write('$nglZoneIdentifier = $nglZone instanceof ' . Zone::class . ' ? $nglZone->getIdentifier() : $nglZone;' . PHP_EOL);

$this->compileContextNode($compiler);

$compiler->write('$nglTemplate = new ' . ContextualizedTwigTemplate::class . '($this, $context, $blocks);' . PHP_EOL);
$compiler->write('$this->env->getRuntime("' . RenderingRuntime::class . '")->displayZone($context["nglayouts"]->getLayout(), $nglZoneIdentifier, $nglContext, $nglTemplate);' . PHP_EOL);
$this->compileRenderNode($compiler);
}

/**
Expand All @@ -62,4 +64,15 @@ private function compileContextNode(Compiler $compiler): void

$compiler->write('$nglContext = ' . ViewInterface::class . '::CONTEXT_DEFAULT;' . PHP_EOL);
}

private function compileRenderNode(Compiler $compiler): void
{
if (Environment::VERSION_ID >= 30900) {
$compiler->write('yield $this->env->getRuntime("' . RenderingRuntime::class . '")->renderZone($context["nglayouts"]->getLayout(), $nglZoneIdentifier, $nglContext, $nglTemplate);' . PHP_EOL);

return;
}

$compiler->write('echo $this->env->getRuntime("' . RenderingRuntime::class . '")->renderZone($context["nglayouts"]->getLayout(), $nglZoneIdentifier, $nglContext, $nglTemplate);' . PHP_EOL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
use Ramsey\Uuid\Uuid;
use Throwable;
use Twig\Environment;
use Twig\Extension\CoreExtension;

use function array_unshift;
use function is_string;
use function method_exists;
use function twig_date_converter;

final class HelpersRuntime
Expand Down Expand Up @@ -121,7 +123,11 @@ public function getCountryFlag(string $countryCode): string
*/
public function formatDateTime(Environment $twig, $dateTime, string $dateFormat = 'medium', string $timeFormat = 'medium'): string
{
$dateTime = twig_date_converter($twig, $dateTime);
$coreExtension = $twig->getExtension(CoreExtension::class);

$dateTime = method_exists($coreExtension, 'convertDate') ?
$coreExtension->convertDate($dateTime) :
twig_date_converter($twig, $dateTime);

$formatValues = [
'none' => IntlDateFormatter::NONE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,9 @@ public function renderValue(array $context, $value, array $parameters = [], ?str
}

/**
* Displays the provided zone.
* Renders the provided zone.
*/
public function displayZone(Layout $layout, string $zoneIdentifier, string $viewContext, ContextualizedTwigTemplate $twigTemplate): void
public function renderZone(Layout $layout, string $zoneIdentifier, string $viewContext, ContextualizedTwigTemplate $twigTemplate): string
{
$locales = null;

Expand All @@ -178,7 +178,7 @@ public function displayZone(Layout $layout, string $zoneIdentifier, string $view
$locales,
);

echo $this->renderValue(
return $this->renderValue(
[],
new ZoneReference($layout, $zoneIdentifier),
[
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"symfony/twig-bundle": "^3.4.47 || ^5.4 || ^6.2",
"symfony/validator": "^3.4.47 || ^5.4 || ^6.2",
"symfony/yaml": "^3.4.47 || ^5.4 || ^6.2",
"twig/twig": "^2.15 || ^3.4",
"twig/twig": "^2.15 || ^3.9",
"sensio/framework-extra-bundle": "^5.4 || ^6.2",
"doctrine/dbal": "^2.13 || ^3.5",
"doctrine/doctrine-bundle": "^1.12 || ^2.7",
Expand Down
5 changes: 1 addition & 4 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ parameters:
treatPhpDocTypesAsCertain: false
dynamicConstantNames:
- Symfony\Component\HttpKernel\Kernel::VERSION_ID
- Twig\Environment::VERSION_ID

ignoreErrors:
# Doctrine DBAL
Expand Down Expand Up @@ -49,10 +50,6 @@ parameters:
- "#Call to function method_exists\\(\\) with Symfony\\\\Component\\\\HttpFoundation\\\\Request and 'getContentTypeFormat' will always evaluate to true.#"
- "#Call to function method_exists\\(\\) with Symfony\\\\Component\\\\DependencyInjection\\\\ContainerBuilder and 'registerAttributeFo…' will always evaluate to true.#"

-
message: '#twig_date_converter not found.#'
path: bundles/LayoutsBundle/Templating/Twig/Runtime/HelpersRuntime.php

# Netgen Layouts specifics

- "#Call to function method_exists\\(\\) with Netgen\\\\Layouts\\\\Layout\\\\Resolver\\\\(Condition|Target)TypeInterface and '(export|import)' will always evaluate to true.#"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected function setUp(): void
}

/**
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::displayZone
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::renderZone
*
* @dataProvider getTests
*
Expand All @@ -74,7 +74,7 @@ public function testIntegration($file, $message, $condition, $templates, $except
}

/**
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::displayZone
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::renderZone
*
* @dataProvider getTests
*
Expand All @@ -97,7 +97,7 @@ public function testIntegrationWithLocale($file, $message, $condition, $template
}

/**
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::displayZone
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::renderZone
*
* @dataProvider getLegacyTests
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
/**
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Node\RenderZone::compile
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Node\RenderZone::compileContextNode
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Node\RenderZone::compileRenderNode
*/
final class RenderZoneTest extends NodeTestBase
{
Expand Down Expand Up @@ -69,7 +70,7 @@ public static function getTests(): array
\$nglZoneIdentifier = \$nglZone instanceof {$zoneClass} ? \$nglZone->getIdentifier() : \$nglZone;
\$nglContext = {$contextNodeGetter};
\$nglTemplate = new {$templateClass}(\$this, \$context, \$blocks);
\$this->env->getRuntime("{$runtimeClass}")->displayZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
yield \$this->env->getRuntime("{$runtimeClass}")->renderZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
EOT
,
$environment,
Expand All @@ -82,7 +83,7 @@ public static function getTests(): array
\$nglZoneIdentifier = \$nglZone instanceof {$zoneClass} ? \$nglZone->getIdentifier() : \$nglZone;
\$nglContext = {$contextNodeGetter};
\$nglTemplate = new {$templateClass}(\$this, \$context, \$blocks);
\$this->env->getRuntime("{$runtimeClass}")->displayZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
yield \$this->env->getRuntime("{$runtimeClass}")->renderZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
EOT
,
$environment,
Expand All @@ -95,7 +96,7 @@ public static function getTests(): array
\$nglZoneIdentifier = \$nglZone instanceof {$zoneClass} ? \$nglZone->getIdentifier() : \$nglZone;
\$nglContext = {$viewInterface}::CONTEXT_DEFAULT;
\$nglTemplate = new {$templateClass}(\$this, \$context, \$blocks);
\$this->env->getRuntime("{$runtimeClass}")->displayZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
yield \$this->env->getRuntime("{$runtimeClass}")->renderZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
EOT
,
$environment,
Expand All @@ -108,7 +109,7 @@ public static function getTests(): array
\$nglZoneIdentifier = \$nglZone instanceof {$zoneClass} ? \$nglZone->getIdentifier() : \$nglZone;
\$nglContext = {$viewInterface}::CONTEXT_DEFAULT;
\$nglTemplate = new {$templateClass}(\$this, \$context, \$blocks);
\$this->env->getRuntime("{$runtimeClass}")->displayZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
yield \$this->env->getRuntime("{$runtimeClass}")->renderZone(\$context["nglayouts"]->getLayout(), \$nglZoneIdentifier, \$nglContext, \$nglTemplate);
EOT
,
$environment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@

namespace Netgen\Bundle\LayoutsBundle\Tests\Templating\Twig\Runtime;

use Doctrine\Common\Collections\ArrayCollection;
use Exception;
use Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime;
use Netgen\Layouts\API\Service\BlockService;
use Netgen\Layouts\API\Values\Block\Block;
use Netgen\Layouts\API\Values\Block\BlockList;
use Netgen\Layouts\API\Values\Block\Placeholder;
use Netgen\Layouts\API\Values\Collection\Item;
use Netgen\Layouts\API\Values\Collection\Slot;
use Netgen\Layouts\API\Values\Layout\Layout;
use Netgen\Layouts\API\Values\Layout\Zone;
use Netgen\Layouts\API\Values\LayoutResolver\RuleCondition;
use Netgen\Layouts\Block\BlockDefinition;
use Netgen\Layouts\Collection\Result\ManualItem;
Expand All @@ -21,6 +25,7 @@
use Netgen\Layouts\Tests\Stubs\ErrorHandler;
use Netgen\Layouts\View\RendererInterface;
use Netgen\Layouts\View\Twig\ContextualizedTwigTemplate;
use Netgen\Layouts\View\View\ZoneView\ZoneReference;
use Netgen\Layouts\View\ViewInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -60,6 +65,54 @@ protected function setUp(): void
);
}

/**
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::__construct
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::getViewContext
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::renderZone
*/
public function testRenderZone(): void
{
$zone = Zone::fromArray([]);
$blocks = new BlockList();
$layout = Layout::fromArray(['zones' => new ArrayCollection(['zone' => $zone])]);

$twigTemplate = new ContextualizedTwigTemplate($this->createMock(Template::class));

$this->blockServiceMock
->expects(self::once())
->method('loadZoneBlocks')
->with(
self::identicalTo($zone),
self::isNull(),
)
->willReturn($blocks);

$this->rendererMock
->expects(self::once())
->method('renderValue')
->with(
self::isInstanceOf(ZoneReference::class),
self::identicalTo(ViewInterface::CONTEXT_DEFAULT),
self::identicalTo(
[
'blocks' => $blocks,
'twig_template' => $twigTemplate,
],
),
)
->willReturn('rendered zone');

self::assertSame(
'rendered zone',
$this->runtime->renderZone(
$layout,
'zone',
ViewInterface::CONTEXT_DEFAULT,
$twigTemplate,
),
);
}

/**
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::__construct
* @covers \Netgen\Bundle\LayoutsBundle\Templating\Twig\Runtime\RenderingRuntime::getViewContext
Expand Down

0 comments on commit 6e4feb5

Please sign in to comment.