Skip to content

Commit

Permalink
[FEATURE] Allow defining arguments for f:render with f:variable
Browse files Browse the repository at this point in the history
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
  • Loading branch information
NamelessCoder committed Feb 14, 2019
1 parent 60545b6 commit 50a5a30
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/Core/ViewHelper/ViewHelperVariableContainer.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* See LICENSE.txt that was shipped with this package.
*/

use TYPO3Fluid\Fluid\Core\Variables\VariableProviderInterface;
use TYPO3Fluid\Fluid\View\ViewInterface;

/**
Expand All @@ -29,6 +30,30 @@ class ViewHelperVariableContainer
*/
protected $view;

public function pushDelegateVariableContainer($viewHelperClassName, VariableProviderInterface $variableProvider)
{
if (!isset($this->objects[$viewHelperClassName]['delegateVariableProviderStack'])) {
$this->objects[$viewHelperClassName]['delegateVariableProviderStack'] = [];
}
$this->objects[$viewHelperClassName]['delegateVariableProviderStack'][] = $variableProvider;
}

public function getTopmostDelegateVariableContainer($viewHelperClassName)
{
if (!isset($this->objects[$viewHelperClassName]['delegateVariableProviderStack'])) {
return null;
}
return end($this->objects[$viewHelperClassName]['delegateVariableProviderStack']);
}

public function popDelegateVariableContainer($viewHelperClassName)
{
if (isset($this->objects[$viewHelperClassName]['delegateVariableProviderStack'])) {
return array_pop($this->objects[$viewHelperClassName]['delegateVariableProviderStack']);
}
return null;
}

/**
* Add a variable to the Variable Container. Make sure that $viewHelperName is ALWAYS set
* to your fully qualified ViewHelper Class Name
Expand Down
14 changes: 14 additions & 0 deletions src/ViewHelpers/RenderViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,21 @@ public static function renderStatic(array $arguments, \Closure $renderChildrenCl
$delegate = $arguments['delegate'];
/** @var RenderableInterface $renderable */
$renderable = $arguments['renderable'];


// Prepare a delegate variable provider that will be possible to extract after rendering the child closure.
// Any variable defined therein gets used as argument and overrides any argument of the same name.
// Note: not using late static binding here is a conscious decision: if late static binding had been used
// then f:variable would not be able to reference this ViewHelper class' stack variable correctly.
$viewHelperVariableContainer = $renderingContext->getViewHelperVariableContainer();
$collector = $renderingContext->getVariableProvider()->getScopeCopy($variables);

$viewHelperVariableContainer->pushDelegateVariableContainer(self::class, $collector);

$tagContent = $renderChildrenClosure();

$variables = $viewHelperVariableContainer->popDelegateVariableContainer(self::class)->getAll();

if ($arguments['contentAs']) {
$variables[$arguments['contentAs']] = $tagContent;
}
Expand Down
3 changes: 3 additions & 0 deletions src/ViewHelpers/VariableViewHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public static function renderStatic(
) {
$value = $renderChildrenClosure();
$renderingContext->getVariableProvider()->add($arguments['name'], $value);
if ($delegateVariableProvider = $renderingContext->getViewHelperVariableContainer()->getTopmostDelegateVariableContainer(RenderViewHelper::class)) {
$delegateVariableProvider->add($arguments['name'], $value);
}
}

}

0 comments on commit 50a5a30

Please sign in to comment.