Skip to content

Commit

Permalink
[FEATURE] Introduce render parent viewhelper
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminkott committed Aug 25, 2023
1 parent e11054b commit 8c56e8b
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 0 deletions.
71 changes: 71 additions & 0 deletions Classes/ViewHelpers/Render/ParentViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php declare(strict_types=1);

/*
* This file is part of the package bk2k/bootstrap-package.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace BK2K\BootstrapPackage\ViewHelpers\Render;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
use TYPO3\CMS\Fluid\View\StandaloneView;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;

class ParentViewHelper extends AbstractViewHelper
{
use CompileWithRenderStatic;

/**
* @var bool
*/
protected $escapeOutput = false;

/**
* @return void
*/
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('partial', 'string', 'Partial to render');
}

/**
* @return string
*/
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
{
$partial = $arguments['partial'] ?? null;
if ($partial === null) {
return '';
}

$format = 'html';
$variables = (array) $renderingContext->getVariableProvider()->getAll();
$partialRootPaths = $variables['__unprocessedPartialRootPaths'] ?? $renderingContext->getTemplatePaths()->getPartialRootPaths();
$partialRootPaths = array_filter($partialRootPaths, function ($path) use ($partial, $format) {
return file_exists($path . $partial . '.' . $format);
});
if (count($partialRootPaths) === 1) {
return '';
}
array_pop($partialRootPaths);
$currentTemplate = end($partialRootPaths) . $partial . '.' . $format;

$context = GeneralUtility::makeInstance(RenderingContextFactory::class)->create();
$context->setRequest($renderingContext->getRequest());
$view = GeneralUtility::makeInstance(StandaloneView::class, $context);
$view->assignMultiple($variables);
$view->assign('__unprocessedPartialRootPaths', $partialRootPaths);
$view->setLayoutRootPaths($renderingContext->getTemplatePaths()->getLayoutRootPaths());
$view->setPartialRootPaths($renderingContext->getTemplatePaths()->getPartialRootPaths());
$view->setTemplateRootPaths($renderingContext->getTemplatePaths()->getTemplateRootPaths());
$view->setTemplatePathAndFilename($currentTemplate);

return $view->render();
}
}
168 changes: 168 additions & 0 deletions Tests/Functional/ViewHelpers/Render/ParentViewHelperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<?php declare(strict_types=1);

/*
* This file is part of the package bk2k/bootstrap-package.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers;

use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
use TYPO3\CMS\Fluid\View\TemplateView;
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
use TYPO3Fluid\Fluid\View\Exception\InvalidTemplateResourceException;

final class ParentViewHelperTest extends FunctionalTestCase
{
protected array $testExtensionsToLoad = [
'typo3conf/ext/bootstrap_package',
'typo3conf/ext/demo_package'
];

/**
* @test
*/
public function renderExistAll(): void
{
$context = $this->get(RenderingContextFactory::class)->create([
'partialRootPaths' => [
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level1/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level2/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level3/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level4/',
]
]);

$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
$view = (new TemplateView($context));

self::assertSame(
implode(
PHP_EOL,
[
'',
'BASIC - LEVEL1',
'',
'BASIC - LEVEL2',
'',
'BASIC - LEVEL3',
'',
'BASIC - LEVEL4',
'',
]
),
$view->render()
);
}

/**
* @test
*/
public function renderFirstAndLast(): void
{
$context = $this->get(RenderingContextFactory::class)->create([
'partialRootPaths' => [
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level1/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level2/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level3/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level4/',
]
]);

$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
$view = (new TemplateView($context));

self::assertSame(
implode(
PHP_EOL,
[
'',
'BASIC - LEVEL1',
'',
'BASIC - LEVEL4',
'',
]
),
$view->render()
);
}

/**
* @test
*/
public function renderNoParent(): void
{
$context = $this->get(RenderingContextFactory::class)->create([
'partialRootPaths' => [
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level1/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level2/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level3/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level4/',
]
]);

$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
$view = (new TemplateView($context));

self::assertSame(
implode(
PHP_EOL,
[
'',
'BASIC - LEVEL4',
'',
]
),
$view->render()
);
}

/**
* @test
*/
public function renderOnlyOnePartialPath(): void
{
$context = $this->get(RenderingContextFactory::class)->create([
'partialRootPaths' => [
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/OnlyOnePartialPath/Level1/',
]
]);
$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
$view = (new TemplateView($context));

self::assertSame(
implode(
PHP_EOL,
[
'',
'BASIC - LEVEL1',
'',
]
),
$view->render()
);
}

/**
* @test
*/
public function renderNoneExist(): void
{
$context = $this->get(RenderingContextFactory::class)->create([
'partialRootPaths' => [
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level1/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level2/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level3/',
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level4/',
]
]);

$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
$view = (new TemplateView($context));

$this->expectException(InvalidTemplateResourceException::class);
$view->render();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL3
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL4
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL4
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL4
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<bk2k:render.parent partial="Partial" />
BASIC - LEVEL1

0 comments on commit 8c56e8b

Please sign in to comment.