diff --git a/composer.json b/composer.json
index 4d5b3353f6..b63e2aaa8a 100644
--- a/composer.json
+++ b/composer.json
@@ -35,6 +35,7 @@
"winter/wn-backend-module": "dev-wip-laravel-11",
"winter/wn-cms-module": "dev-wip-laravel-11",
"laravel/framework": "^11.0",
+ "twig/twig": "^3.9.0",
"wikimedia/composer-merge-plugin": "~2.1.0"
},
"require-dev": {
diff --git a/modules/cms/twig/ComponentNode.php b/modules/cms/twig/ComponentNode.php
index 4787fe9b2d..fe51a89c10 100644
--- a/modules/cms/twig/ComponentNode.php
+++ b/modules/cms/twig/ComponentNode.php
@@ -1,5 +1,6 @@
write("echo \$this->env->getExtension('Cms\Twig\Extension')->componentFunction(")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->componentFunction(")
->subcompile($this->getNode('nodes')->getNode(0))
->write(", \$context['__cms_component_params']")
->write(");\n")
diff --git a/modules/cms/twig/ContentNode.php b/modules/cms/twig/ContentNode.php
index 663850f158..d8aaf91a61 100644
--- a/modules/cms/twig/ContentNode.php
+++ b/modules/cms/twig/ContentNode.php
@@ -1,5 +1,6 @@
write("echo \$this->env->getExtension('Cms\Twig\Extension')->contentFunction(")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->contentFunction(")
->subcompile($this->getNode('nodes')->getNode(0))
->write(", \$context['__cms_content_params']")
->write(", true")
diff --git a/modules/cms/twig/DefaultNode.php b/modules/cms/twig/DefaultNode.php
index bcf05b501d..77e30bda2d 100644
--- a/modules/cms/twig/DefaultNode.php
+++ b/modules/cms/twig/DefaultNode.php
@@ -1,5 +1,6 @@
addDebugInfo($this)
- ->write("echo '';\n")
+ ->write("yield '';\n")
;
}
}
diff --git a/modules/cms/twig/FrameworkNode.php b/modules/cms/twig/FrameworkNode.php
index 4e3146f3c6..00a3dee0ef 100644
--- a/modules/cms/twig/FrameworkNode.php
+++ b/modules/cms/twig/FrameworkNode.php
@@ -2,6 +2,7 @@
use System\Models\Parameter;
use System\Classes\CombineAssets;
+use Twig\Attribute\YieldReady;
use Twig\Node\Node as TwigNode;
use Twig\Compiler as TwigCompiler;
use Url;
@@ -12,6 +13,7 @@
* @package winter\wn-cms-module
* @author Alexey Bobkov, Samuel Georges
*/
+#[YieldReady]
class FrameworkNode extends TwigNode
{
public function __construct($name, $lineno, $tag = 'framework')
@@ -41,20 +43,20 @@ public function compile(TwigCompiler $compiler)
$compiler
->write("if (\$_minify) {" . PHP_EOL)
->indent()
- ->write("echo ''.PHP_EOL;" . PHP_EOL)
+ ->write("yield ''.PHP_EOL;" . PHP_EOL)
->outdent()
->write("}" . PHP_EOL)
->write("else {" . PHP_EOL)
->indent()
- ->write("echo ''.PHP_EOL;" . PHP_EOL)
- ->write("echo ''.PHP_EOL;" . PHP_EOL)
+ ->write("yield ''.PHP_EOL;" . PHP_EOL)
+ ->write("yield ''.PHP_EOL;" . PHP_EOL)
->outdent()
->write("}" . PHP_EOL)
- ->write("echo ''.PHP_EOL;" . PHP_EOL)
+ ->write("yield ''.PHP_EOL;" . PHP_EOL)
;
}
else {
- $compiler->write("echo ''.PHP_EOL;" . PHP_EOL);
+ $compiler->write("yield ''.PHP_EOL;" . PHP_EOL);
}
$compiler->write('unset($_minify);' . PHP_EOL);
diff --git a/modules/cms/twig/PageNode.php b/modules/cms/twig/PageNode.php
index f4481c9185..1dc750c8a3 100644
--- a/modules/cms/twig/PageNode.php
+++ b/modules/cms/twig/PageNode.php
@@ -1,5 +1,6 @@
addDebugInfo($this)
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->pageFunction();\n")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->pageFunction();\n")
;
}
}
diff --git a/modules/cms/twig/PartialNode.php b/modules/cms/twig/PartialNode.php
index 34578dec7f..5952b8c842 100644
--- a/modules/cms/twig/PartialNode.php
+++ b/modules/cms/twig/PartialNode.php
@@ -1,5 +1,6 @@
write("echo \$this->env->getExtension('Cms\Twig\Extension')->partialFunction(")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->partialFunction(")
->subcompile($this->getNode('nodes')->getNode(0))
->write(", \$context['__cms_partial_params']")
->write(", true")
diff --git a/modules/cms/twig/PlaceholderNode.php b/modules/cms/twig/PlaceholderNode.php
index 46d8a809a6..ad042e6d60 100644
--- a/modules/cms/twig/PlaceholderNode.php
+++ b/modules/cms/twig/PlaceholderNode.php
@@ -1,5 +1,6 @@
addDebugInfo($this);
if (!$isText) {
- $compiler->write("echo \$this->env->getExtension('Cms\Twig\Extension')->displayBlock(");
+ $compiler->write("yield \$this->env->getExtension('Cms\Twig\Extension')->displayBlock(");
}
else {
- $compiler->write("echo twig_escape_filter(\$this->env, \$this->env->getExtension('Cms\Twig\Extension')->displayBlock(");
+ $compiler->write("yield twig_escape_filter(\$this->env, \$this->env->getExtension('Cms\Twig\Extension')->displayBlock(");
}
$compiler
diff --git a/modules/cms/twig/PutNode.php b/modules/cms/twig/PutNode.php
index 6b3927ac02..795c2e3697 100644
--- a/modules/cms/twig/PutNode.php
+++ b/modules/cms/twig/PutNode.php
@@ -1,5 +1,6 @@
addDebugInfo($this)
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->startBlock(")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->startBlock(")
->raw("'".$this->getAttribute('name')."'")
->write(");\n")
;
@@ -36,7 +38,7 @@ public function compile(TwigCompiler $compiler)
$compiler
->addDebugInfo($this)
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->endBlock(")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->endBlock(")
->raw($isOverwrite ? 'false' : 'true')
->write(");\n")
;
diff --git a/modules/cms/twig/ScriptsNode.php b/modules/cms/twig/ScriptsNode.php
index 2640613547..80c7dff148 100644
--- a/modules/cms/twig/ScriptsNode.php
+++ b/modules/cms/twig/ScriptsNode.php
@@ -1,5 +1,6 @@
addDebugInfo($this)
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('js');\n")
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('vite');\n")
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('scripts');\n")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('js');\n")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('vite');\n")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('scripts');\n")
;
}
}
diff --git a/modules/cms/twig/SnowboardNode.php b/modules/cms/twig/SnowboardNode.php
index 0471f9d6ab..1a88746f12 100644
--- a/modules/cms/twig/SnowboardNode.php
+++ b/modules/cms/twig/SnowboardNode.php
@@ -3,6 +3,7 @@
use Config;
use System\Classes\CombineAssets;
use System\Models\Parameter;
+use Twig\Attribute\YieldReady;
use Twig\Compiler as TwigCompiler;
use Twig\Node\Node as TwigNode;
use Url;
@@ -13,6 +14,7 @@
* @package winter\wn-cms-module
* @author Winter CMS
*/
+#[YieldReady]
class SnowboardNode extends TwigNode
{
/**
@@ -55,17 +57,17 @@ public function compile(TwigCompiler $compiler)
if (!static::$baseLoaded) {
// Add manifest and vendor files
$compiler
- ->write("echo ''.PHP_EOL;" . PHP_EOL);
+ ->write("yield ''.PHP_EOL;" . PHP_EOL);
$vendorJs = $moduleMap['vendor'];
$compiler
- ->write("echo ''.PHP_EOL;" . PHP_EOL);
+ ->write("yield ''.PHP_EOL;" . PHP_EOL);
// Add base script
$baseJs = $moduleMap['base'];
$baseUrl = Url::to('/');
$assetUrl = Url::asset('/');
$compiler
- ->write("echo ''.PHP_EOL;" . PHP_EOL);
+ ->write("yield ''.PHP_EOL;" . PHP_EOL);
static::$baseLoaded = true;
}
@@ -73,7 +75,7 @@ public function compile(TwigCompiler $compiler)
foreach ($modules as $module) {
$moduleJs = $moduleMap[$module];
$compiler
- ->write("echo ''.PHP_EOL;" . PHP_EOL);
+ ->write("yield ''.PHP_EOL;" . PHP_EOL);
}
}
}
diff --git a/modules/cms/twig/StylesNode.php b/modules/cms/twig/StylesNode.php
index 35a442c2f5..ffd0898543 100644
--- a/modules/cms/twig/StylesNode.php
+++ b/modules/cms/twig/StylesNode.php
@@ -1,5 +1,6 @@
addDebugInfo($this)
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('css');\n")
- ->write("echo \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('styles');\n")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->assetsFunction('css');\n")
+ ->write("yield \$this->env->getExtension('Cms\Twig\Extension')->displayBlock('styles');\n")
;
}
}
diff --git a/modules/system/twig/MailPartialNode.php b/modules/system/twig/MailPartialNode.php
index 8810d9f212..88a9af3129 100644
--- a/modules/system/twig/MailPartialNode.php
+++ b/modules/system/twig/MailPartialNode.php
@@ -1,5 +1,6 @@
write("echo \System\Classes\MailManager::instance()->renderPartial(")
+ ->write("yield \System\Classes\MailManager::instance()->renderPartial(")
->subcompile($this->getNode('nodes')->getNode(0))
->write(", \$context['__system_partial_params']")
->write(");\n")
diff --git a/modules/system/twig/SpacelessNode.php b/modules/system/twig/SpacelessNode.php
index 939326596c..a471f84701 100644
--- a/modules/system/twig/SpacelessNode.php
+++ b/modules/system/twig/SpacelessNode.php
@@ -1,5 +1,6 @@
*/
+#[YieldReady]
class SpacelessNode extends Node implements NodeOutputInterface
{
public function __construct(Node $body, int $lineno, string $tag = 'spaceless')
@@ -25,14 +27,8 @@ public function compile(Compiler $compiler)
$compiler
->addDebugInfo($this)
;
- if ($compiler->getEnvironment()->isDebug()) {
- $compiler->write("ob_start();\n");
- } else {
- $compiler->write("ob_start(function () { return ''; });\n");
- }
$compiler
- ->subcompile($this->getNode('body'))
- ->write("echo trim(preg_replace('/>\s+', '><', ob_get_clean()));\n")
+ ->write(sprintf("yield trim(preg_replace('/>\s+', '><', '%s'));\n", $this->getNode('body')->getAttribute('data')))
;
}
}
diff --git a/modules/system/twig/SpacelessTokenParser.php b/modules/system/twig/SpacelessTokenParser.php
index d17eab1500..807aa4f09a 100644
--- a/modules/system/twig/SpacelessTokenParser.php
+++ b/modules/system/twig/SpacelessTokenParser.php
@@ -10,9 +10,9 @@ public function parse(Token $token)
$stream = $this->parser->getStream();
$lineno = $token->getLine();
- $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
+ $stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse([$this, 'decideSpacelessEnd'], true);
- $stream->expect(/* Token::BLOCK_END_TYPE */ 3);
+ $stream->expect(Token::BLOCK_END_TYPE);
return new SpacelessNode($body, $lineno, $this->getTag());
}