• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

FluidTYPO3 / vhs / 28590230059

02 Jul 2026 12:32PM UTC coverage: 70.857%. First build
28590230059

push

github

NamelessCoder
[TASK] Migrate View-operating code to predictable View type

18 of 24 new or added lines in 4 files covered. (75.0%)

4853 of 6849 relevant lines covered (70.86%)

4.46 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.63
/Classes/ViewHelpers/Render/TemplateViewHelper.php
1
<?php
2
namespace FluidTYPO3\Vhs\ViewHelpers\Render;
3

4
/*
5
 * This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.md file that was distributed with this source code.
9
 */
10

11
use FluidTYPO3\Vhs\Utility\RequestResolver;
12
use TYPO3\CMS\Core\Utility\GeneralUtility;
13

14
/**
15
 * ### Render: Template
16
 *
17
 * Render a template file (with arguments if desired).
18
 *
19
 * Supports passing variables and controlling the format,
20
 * paths can be overridden and uses the same format as TS
21
 * settings a' la plugin.tx_myext.view, which means that
22
 * this can be done (from any extension, not just "foo")
23
 *
24
 * ```
25
 * <v:render.template
26
 *  file="EXT:foo/Resources/Private/Templates/Action/Show.html"
27
 *  variables="{object: customLoadedObject}"
28
 *  paths="{v:variable.typoscript(path: 'plugin.tx_foo.view')}"
29
 *  format="xml" />
30
 * ```
31
 *
32
 * Which would render the "show" action's template from
33
 * EXT:foo using paths define in that extension's typoscript
34
 * but using a custom loaded object when rendering the template
35
 * rather than the object defined by the "Action" controller
36
 * of EXT:foo. The output would be in XML format and this
37
 * format would also be respected by Layouts and Partials
38
 * which are rendered from the Show.html template.
39
 *
40
 * As such this is very similar to Render/RequestViewHelper
41
 * with two major differences:
42
 *
43
 * 1. A true ControllerContext is not present when rendering which
44
 *    means that links generated in the template should be made
45
 *    always including all parameters from ExtensionName over
46
 *    PluginName through the usual action etc.
47
 * 2. The Controller from EXT:foo is not involved in any way,
48
 *    which means that any custom variables the particular
49
 *    template depends on must be added manually through
50
 *    the "variables" argument
51
 *
52
 * Consider using Render/InlineViewHelper if you are rendering
53
 * templates from the same plugin.
54
 *
55
 * Consider using Render/RequestViewHelper if you require a
56
 * completely isolated rendering identical to that which takes
57
 * place when rendering an Extbase plugin's content object.
58
 */
59
class TemplateViewHelper extends AbstractRenderViewHelper
60
{
61
    public function initializeArguments(): void
62
    {
63
        parent::initializeArguments();
2✔
64
        $this->registerArgument('file', 'string', 'Path to template file, EXT:myext/... paths supported');
2✔
65
        $this->registerArgument('variables', 'array', 'Optional array of template variables for rendering');
2✔
66
        $this->registerArgument('format', 'string', 'Optional format of the template(s) being rendered');
2✔
67
        $this->registerArgument(
2✔
68
            'paths',
2✔
69
            'array',
2✔
70
            'Optional array of arrays of layout and partial root paths, EXT:mypath/... paths supported'
2✔
71
        );
2✔
72
    }
73

74
    public function render(): string
75
    {
76
        /** @var string|null $file */
77
        $file = $this->arguments['file'];
2✔
78
        if (null === $file) {
2✔
79
            /** @var string|null $file */
80
            $file = $this->renderChildren();
2✔
81
        }
82

83
        $file = GeneralUtility::getFileAbsFileName((string) $file);
2✔
84
        $view = static::getPreparedView();
2✔
85
        if (method_exists($view, 'setRequest')) {
2✔
86
            $view->setRequest(RequestResolver::resolveRequestFromRenderingContext($this->renderingContext));
×
87
        }
88
        $view->getRenderingContext()->getTemplatePaths()->setTemplatePathAndFilename($file);
2✔
89
        if (is_array($this->arguments['variables'])) {
2✔
90
            $view->assignMultiple($this->arguments['variables']);
2✔
91
        }
92

93
        $templatePaths = $view->getRenderingContext()->getTemplatePaths();
2✔
94

95
        /** @var string|null $format */
96
        $format = $this->arguments['format'];
2✔
97
        if (null !== $format) {
2✔
NEW
98
            $templatePaths->setFormat($format);
×
99
        }
100

101
        /** @var array|null $paths */
102
        $paths = $this->arguments['paths'];
2✔
103
        $paths = (array) ($paths ?? []);
2✔
104

105
        $templatePaths->setLayoutRootPaths($this->processPathsArray($paths['layoutRootPaths'] ?? []));
2✔
106
        $templatePaths->setPartialRootPaths($this->processPathsArray($paths['partialRootPaths'] ?? []));
2✔
107

108
        return static::renderView($view, $this->arguments);
2✔
109
    }
110

111
    protected function processPathsArray(array $paths): array
112
    {
113
        $pathsArray = [];
2✔
114
        foreach ($paths as $key => $path) {
2✔
115
            $pathsArray[$key] = (0 === strpos($path, 'EXT:')) ? GeneralUtility::getFileAbsFileName($path) : $path;
×
116
        }
117

118
        return $pathsArray;
2✔
119
    }
120
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc