Skip to content

Commit

Permalink
[FEATURE] Inline fluid ViewHelper (#415)
Browse files Browse the repository at this point in the history
Allows rendering a variable containing Fluid code as
if the code contained in the variable were part of the
template invoking the ViewHelper.

    $view->assign('variable', 'value of my variable');
    $view->assign('code', 'My variable: {variable}');

And in the template:

    {code -> f:inline()}

Which outputs:

    My variable: value of my variable

You can use this to pass smaller and dynamic pieces of Fluid code
to templates, as an alternative to creating new partial templates.
  • Loading branch information
NamelessCoder authored and mbrodala committed Nov 6, 2018
1 parent e450fb4 commit 944faf5
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/ViewHelpers/InlineViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php
namespace TYPO3Fluid\Fluid\ViewHelpers;

use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithContentArgumentAndRenderStatic;

/**
* Inline Fluid rendering ViewHelper
*
* Renders Fluid code stored in a variable, which you normally would
* have to render before assigning it to the view. Instead you can
* do the following (note, extremely simplified use case):
*
* $view->assign('variable', 'value of my variable');
* $view->assign('code', 'My variable: {variable}');
*
* And in the template:
*
* {code -> f:inline()}
*
* Which outputs:
*
* My variable: value of my variable
*
* You can use this to pass smaller and dynamic pieces of Fluid code
* to templates, as an alternative to creating new partial templates.
*/
class InlineViewHelper extends AbstractViewHelper
{
use CompileWithContentArgumentAndRenderStatic;

protected $escapeChildren = false;

protected $escapeOutput = false;

/**
* @return void
*/
public function initializeArguments()
{
$this->registerArgument(
'code',
'string',
'Fluid code to be rendered as if it were part of the template rendering it. Can be passed as inline argument or tag content'
);
}

/**
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
* @return mixed|string
*/
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
return $renderingContext->getTemplateParser()->parse($renderChildrenClosure())->render($renderingContext);
}
}
47 changes: 47 additions & 0 deletions tests/Unit/ViewHelpers/InlineViewHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
namespace TYPO3Fluid\Fluid\Tests\Unit\ViewHelpers;

/*
* This file belongs to the package "TYPO3 Fluid".
* See LICENSE.txt that was shipped with this package.
*/

use TYPO3Fluid\Fluid\Core\Parser\ParsedTemplateInterface;
use TYPO3Fluid\Fluid\Core\Parser\TemplateParser;
use TYPO3Fluid\Fluid\Tests\Unit\Core\Rendering\RenderingContextFixture;
use TYPO3Fluid\Fluid\ViewHelpers\InlineViewHelper;

/**
* Class InlineViewHelperTest
*/
class InlineViewHelperTest extends ViewHelperBaseTestcase
{
/**
* @test
*/
public function testInitializeArguments()
{
$instance = $this->getMockBuilder(InlineViewHelper::class)->setMethods(['registerArgument'])->getMock();
$instance->expects($this->at(0))->method('registerArgument')->with('code', 'string', $this->anything());
$instance->initializeArguments();
}

/**
* @test
*/
public function testCallsExpectedDelegationMethodFromRenderStatic()
{
$contextFixture = new RenderingContextFixture();

$parsedTemplateMock = $this->getMockBuilder(ParsedTemplateInterface::class)->getMock();
$parsedTemplateMock->expects($this->once())->method('render')->with($contextFixture)->willReturn('bar');

$parserMock = $this->getMockBuilder(TemplateParser::class)->setMethods(['parse'])->getMock();
$parserMock->expects($this->once())->method('parse')->with('foo')->willReturn($parsedTemplateMock);

$contextFixture->setTemplateParser($parserMock);

$result = InlineViewHelper::renderStatic([], function() { return 'foo'; }, $contextFixture);
$this->assertEquals('bar', $result);
}
}

0 comments on commit 944faf5

Please sign in to comment.