Skip to content

Commit 50a5a30

Browse files
committed
[FEATURE] Allow defining arguments for f:render with f:variable
This patch allows you to define arguments that get passed to f:render by using f:variable in the tag contents. ```xml <f:render partial="Something"> <f:variable name="arg1">Special value for arg1 variable</f:variable> <f:variable name="arg2">Special value for arg2 variable</f:variable> </f:render> ``` Any argument specified with f:variable this way will override the argument of the same name if it was passed in the “arguments” array as well. The combined result will be used as variables for the sub-rendering call. References: #427
1 parent 60545b6 commit 50a5a30

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

src/Core/ViewHelper/ViewHelperVariableContainer.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* See LICENSE.txt that was shipped with this package.
77
*/
88

9+
use TYPO3Fluid\Fluid\Core\Variables\VariableProviderInterface;
910
use TYPO3Fluid\Fluid\View\ViewInterface;
1011

1112
/**
@@ -29,6 +30,30 @@ class ViewHelperVariableContainer
2930
*/
3031
protected $view;
3132

33+
public function pushDelegateVariableContainer($viewHelperClassName, VariableProviderInterface $variableProvider)
34+
{
35+
if (!isset($this->objects[$viewHelperClassName]['delegateVariableProviderStack'])) {
36+
$this->objects[$viewHelperClassName]['delegateVariableProviderStack'] = [];
37+
}
38+
$this->objects[$viewHelperClassName]['delegateVariableProviderStack'][] = $variableProvider;
39+
}
40+
41+
public function getTopmostDelegateVariableContainer($viewHelperClassName)
42+
{
43+
if (!isset($this->objects[$viewHelperClassName]['delegateVariableProviderStack'])) {
44+
return null;
45+
}
46+
return end($this->objects[$viewHelperClassName]['delegateVariableProviderStack']);
47+
}
48+
49+
public function popDelegateVariableContainer($viewHelperClassName)
50+
{
51+
if (isset($this->objects[$viewHelperClassName]['delegateVariableProviderStack'])) {
52+
return array_pop($this->objects[$viewHelperClassName]['delegateVariableProviderStack']);
53+
}
54+
return null;
55+
}
56+
3257
/**
3358
* Add a variable to the Variable Container. Make sure that $viewHelperName is ALWAYS set
3459
* to your fully qualified ViewHelper Class Name

src/ViewHelpers/RenderViewHelper.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,21 @@ public static function renderStatic(array $arguments, \Closure $renderChildrenCl
121121
$delegate = $arguments['delegate'];
122122
/** @var RenderableInterface $renderable */
123123
$renderable = $arguments['renderable'];
124+
125+
126+
// Prepare a delegate variable provider that will be possible to extract after rendering the child closure.
127+
// Any variable defined therein gets used as argument and overrides any argument of the same name.
128+
// Note: not using late static binding here is a conscious decision: if late static binding had been used
129+
// then f:variable would not be able to reference this ViewHelper class' stack variable correctly.
130+
$viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
131+
$collector = $renderingContext->getVariableProvider()->getScopeCopy($variables);
132+
133+
$viewHelperVariableContainer->pushDelegateVariableContainer(self::class, $collector);
134+
124135
$tagContent = $renderChildrenClosure();
136+
137+
$variables = $viewHelperVariableContainer->popDelegateVariableContainer(self::class)->getAll();
138+
125139
if ($arguments['contentAs']) {
126140
$variables[$arguments['contentAs']] = $tagContent;
127141
}

src/ViewHelpers/VariableViewHelper.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ public static function renderStatic(
5757
) {
5858
$value = $renderChildrenClosure();
5959
$renderingContext->getVariableProvider()->add($arguments['name'], $value);
60+
if ($delegateVariableProvider = $renderingContext->getViewHelperVariableContainer()->getTopmostDelegateVariableContainer(RenderViewHelper::class)) {
61+
$delegateVariableProvider->add($arguments['name'], $value);
62+
}
6063
}
6164

6265
}

0 commit comments

Comments
 (0)