Skip to content

Commit 82a837b

Browse files
committed
[FEATURE] Introduce render parent viewhelper
1 parent e11054b commit 82a837b

File tree

10 files changed

+260
-0
lines changed

10 files changed

+260
-0
lines changed
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of the package bk2k/bootstrap-package.
5+
*
6+
* For the full copyright and license information, please read the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace BK2K\BootstrapPackage\ViewHelpers\Render;
11+
12+
use TYPO3\CMS\Core\Information\Typo3Version;
13+
use TYPO3\CMS\Core\Utility\GeneralUtility;
14+
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
15+
use TYPO3\CMS\Fluid\View\StandaloneView;
16+
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
17+
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
18+
use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic;
19+
20+
class ParentViewHelper extends AbstractViewHelper
21+
{
22+
use CompileWithRenderStatic;
23+
24+
/**
25+
* @var bool
26+
*/
27+
protected $escapeOutput = false;
28+
29+
/**
30+
* @return void
31+
*/
32+
public function initializeArguments()
33+
{
34+
parent::initializeArguments();
35+
$this->registerArgument('partial', 'string', 'Partial to render');
36+
}
37+
38+
/**
39+
* @return string
40+
*/
41+
public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
42+
{
43+
$partial = $arguments['partial'] ?? null;
44+
if ($partial === null) {
45+
return '';
46+
}
47+
48+
$format = 'html';
49+
$variables = (array) $renderingContext->getVariableProvider()->getAll();
50+
$partialRootPaths = $variables['__unprocessedPartialRootPaths'] ?? $renderingContext->getTemplatePaths()->getPartialRootPaths();
51+
$partialRootPaths = array_filter($partialRootPaths, function ($path) use ($partial, $format) {
52+
return file_exists($path . $partial . '.' . $format);
53+
});
54+
if (count($partialRootPaths) === 1) {
55+
return '';
56+
}
57+
array_pop($partialRootPaths);
58+
$currentTemplate = end($partialRootPaths) . $partial . '.' . $format;
59+
60+
if ((new Typo3Version())->getMajorVersion() < 12) {
61+
$view = GeneralUtility::makeInstance(StandaloneView::class);
62+
} else {
63+
$context = GeneralUtility::makeInstance(RenderingContextFactory::class)->create();
64+
$context->setRequest($renderingContext->getRequest());
65+
$view = GeneralUtility::makeInstance(StandaloneView::class, $context);
66+
}
67+
$view->assignMultiple($variables);
68+
$view->assign('__unprocessedPartialRootPaths', $partialRootPaths);
69+
$view->setLayoutRootPaths($renderingContext->getTemplatePaths()->getLayoutRootPaths());
70+
$view->setPartialRootPaths($renderingContext->getTemplatePaths()->getPartialRootPaths());
71+
$view->setTemplateRootPaths($renderingContext->getTemplatePaths()->getTemplateRootPaths());
72+
$view->setTemplatePathAndFilename($currentTemplate);
73+
74+
return $view->render();
75+
}
76+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of the package bk2k/bootstrap-package.
5+
*
6+
* For the full copyright and license information, please read the
7+
* LICENSE file that was distributed with this source code.
8+
*/
9+
10+
namespace T3G\AgencyPack\Blog\Tests\Functional\ViewHelpers;
11+
12+
use TYPO3\CMS\Fluid\Core\Rendering\RenderingContextFactory;
13+
use TYPO3\CMS\Fluid\View\TemplateView;
14+
use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
15+
use TYPO3Fluid\Fluid\View\Exception\InvalidTemplateResourceException;
16+
17+
final class ParentViewHelperTest extends FunctionalTestCase
18+
{
19+
protected array $testExtensionsToLoad = [
20+
'typo3conf/ext/bootstrap_package',
21+
'typo3conf/ext/demo_package'
22+
];
23+
24+
/**
25+
* @test
26+
*/
27+
public function renderExistAll(): void
28+
{
29+
$context = $this->get(RenderingContextFactory::class)->create([
30+
'partialRootPaths' => [
31+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level1/',
32+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level2/',
33+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level3/',
34+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/ExistAll/Level4/',
35+
]
36+
]);
37+
38+
$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
39+
$view = (new TemplateView($context));
40+
41+
self::assertSame(
42+
implode(
43+
PHP_EOL,
44+
[
45+
'',
46+
'BASIC - LEVEL1',
47+
'',
48+
'BASIC - LEVEL2',
49+
'',
50+
'BASIC - LEVEL3',
51+
'',
52+
'BASIC - LEVEL4',
53+
'',
54+
]
55+
),
56+
$view->render()
57+
);
58+
}
59+
60+
/**
61+
* @test
62+
*/
63+
public function renderFirstAndLast(): void
64+
{
65+
$context = $this->get(RenderingContextFactory::class)->create([
66+
'partialRootPaths' => [
67+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level1/',
68+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level2/',
69+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level3/',
70+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/FirstAndLast/Level4/',
71+
]
72+
]);
73+
74+
$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
75+
$view = (new TemplateView($context));
76+
77+
self::assertSame(
78+
implode(
79+
PHP_EOL,
80+
[
81+
'',
82+
'BASIC - LEVEL1',
83+
'',
84+
'BASIC - LEVEL4',
85+
'',
86+
]
87+
),
88+
$view->render()
89+
);
90+
}
91+
92+
/**
93+
* @test
94+
*/
95+
public function renderNoParent(): void
96+
{
97+
$context = $this->get(RenderingContextFactory::class)->create([
98+
'partialRootPaths' => [
99+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level1/',
100+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level2/',
101+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level3/',
102+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoParent/Level4/',
103+
]
104+
]);
105+
106+
$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
107+
$view = (new TemplateView($context));
108+
109+
self::assertSame(
110+
implode(
111+
PHP_EOL,
112+
[
113+
'',
114+
'BASIC - LEVEL4',
115+
'',
116+
]
117+
),
118+
$view->render()
119+
);
120+
}
121+
122+
/**
123+
* @test
124+
*/
125+
public function renderOnlyOnePartialPath(): void
126+
{
127+
$context = $this->get(RenderingContextFactory::class)->create([
128+
'partialRootPaths' => [
129+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/OnlyOnePartialPath/Level1/',
130+
]
131+
]);
132+
$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
133+
$view = (new TemplateView($context));
134+
135+
self::assertSame(
136+
implode(
137+
PHP_EOL,
138+
[
139+
'',
140+
'BASIC - LEVEL1',
141+
'',
142+
]
143+
),
144+
$view->render()
145+
);
146+
}
147+
148+
/**
149+
* @test
150+
*/
151+
public function renderNoneExist(): void
152+
{
153+
$context = $this->get(RenderingContextFactory::class)->create([
154+
'partialRootPaths' => [
155+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level1/',
156+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level2/',
157+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level3/',
158+
'EXT:demo_package/Resources/Private/ParentViewHelperTest/Partials/NoneExist/Level4/',
159+
]
160+
]);
161+
162+
$context->getTemplatePaths()->setTemplateSource('<f:render partial="Partial" />');
163+
$view = (new TemplateView($context));
164+
165+
$this->expectException(InvalidTemplateResourceException::class);
166+
$view->render();
167+
}
168+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL2
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL3
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL4
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL1
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL4
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL4
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<bk2k:render.parent partial="Partial" />
2+
BASIC - LEVEL1

0 commit comments

Comments
 (0)