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

CPS-IT / handlebars / 13562517059

27 Feb 2025 08:57AM UTC coverage: 92.973% (-0.05%) from 93.023%
13562517059

push

github

web-flow
Merge pull request #416 from CPS-IT/fix/1.x/view-format

[BUGFIX] Respect template format passed to ExtbaseHandlebarsViewResolver

6 of 7 new or added lines in 1 file covered. (85.71%)

1204 of 1295 relevant lines covered (92.97%)

4.19 hits per line

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

98.04
/Classes/Extbase/View/ExtbaseHandlebarsViewResolver.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the TYPO3 CMS extension "handlebars".
7
 *
8
 * Copyright (C) 2025 Elias Häußler <e.haeussler@familie-redlich.de>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace Fr\Typo3Handlebars\Extbase\View;
25

26
use Psr\Container;
27
use Symfony\Component\DependencyInjection;
28
use TYPO3\CMS\Core;
29
use TYPO3\CMS\Extbase;
30
use TYPO3\CMS\Frontend;
31
use TYPO3Fluid\Fluid;
32

33
/**
34
 * ExtbaseHandlebarsViewResolver
35
 *
36
 * @author Elias Häußler <e.haeussler@familie-redlich.de>
37
 * @license GPL-2.0-or-later
38
 */
39
#[DependencyInjection\Attribute\AsAlias(Extbase\Mvc\View\ViewResolverInterface::class)]
40
final class ExtbaseHandlebarsViewResolver extends Extbase\Mvc\View\GenericViewResolver
41
{
42
    private readonly Frontend\ContentObject\ContentObjectRenderer $contentObjectRenderer;
43

44
    public function __construct(
4✔
45
        Container\ContainerInterface $container,
46
        private readonly Extbase\Configuration\ConfigurationManagerInterface $configurationManager,
47
        private readonly Core\TypoScript\TypoScriptService $typoScriptService,
48
    ) {
49
        parent::__construct($container);
4✔
50

51
        $this->contentObjectRenderer = $container->get(Frontend\ContentObject\ContentObjectRenderer::class);
4✔
52
    }
53

54
    public function resolve(
4✔
55
        string $controllerObjectName,
56
        string $actionName,
57
        string $format,
58
        bool $enableFallback = true,
59
    ): Fluid\View\ViewInterface {
60
        $handlebarsConfiguration = $this->resolveHandlebarsConfiguration($controllerObjectName, $actionName, $format);
4✔
61

62
        if ($handlebarsConfiguration !== null || !$enableFallback) {
4✔
63
            return new ExtbaseHandlebarsView(
3✔
64
                $this->contentObjectRenderer,
3✔
65
                $this->typoScriptService,
3✔
66
                $handlebarsConfiguration ?? [],
3✔
67
            );
3✔
68
        }
69

70
        return parent::resolve($controllerObjectName, $actionName, $format);
1✔
71
    }
72

73
    /**
74
     * @return array<string, mixed>|null
75
     */
76
    private function resolveHandlebarsConfiguration(
4✔
77
        string $controllerObjectName,
78
        string $actionName,
79
        string $format,
80
    ): ?array {
81
        $configuration = $this->configurationManager->getConfiguration(
4✔
82
            Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK,
4✔
83
        );
4✔
84
        $controllerAlias = $configuration['controllerConfiguration'][$controllerObjectName]['alias'] ?? null;
4✔
85

86
        // Early return if controller is not properly registered
87
        if (!is_string($controllerAlias)) {
4✔
88
            return null;
1✔
89
        }
90

91
        // Use hbs as default format, can be overridden with TypoScript
92
        if ($format === 'html') {
3✔
NEW
93
            $format = 'hbs';
×
94
        }
95

96
        $handlebarsConfiguration = $configuration['handlebars'] ?? null;
3✔
97
        $defaultConfiguration = [
3✔
98
            'templateName' => $controllerAlias . '/' . $actionName,
3✔
99
            'format' => $format,
3✔
100
        ];
3✔
101

102
        // Early return if no handlebars configuration is available
103
        if (!is_array($handlebarsConfiguration)) {
3✔
104
            return $defaultConfiguration;
1✔
105
        }
106

107
        // HANDLEBARSTEMPLATE content object requires TypoScript configuration, so let's convert early
108
        $typoScriptConfiguration = $this->typoScriptService->convertPlainArrayToTypoScriptArray($handlebarsConfiguration);
2✔
109

110
        // Resolve template name from controller action
111
        if (is_string($typoScriptConfiguration['templateName'] ?? null) &&
2✔
112
            is_array($typoScriptConfiguration['templateName.'] ?? null)
2✔
113
        ) {
114
            // Inject custom fields to be referenced in TypoScript when resolving the
115
            // template name, e.g. in combination with a CASE content object
116
            $this->contentObjectRenderer->data['controllerName'] = $controllerAlias;
2✔
117
            $this->contentObjectRenderer->data['controllerObjectName'] = $controllerObjectName;
2✔
118
            $this->contentObjectRenderer->data['controllerAction'] = $actionName;
2✔
119
            $this->contentObjectRenderer->data['controllerNameAndAction'] = $controllerAlias . '::' . $actionName;
2✔
120

121
            try {
122
                // Resolve template name based on the current controller action
123
                $typoScriptConfiguration['templateName'] = $this->contentObjectRenderer->cObjGetSingle(
2✔
124
                    $typoScriptConfiguration['templateName'],
2✔
125
                    $typoScriptConfiguration['templateName.'],
2✔
126
                );
2✔
127
            } finally {
128
                // Remove configuration which is solely responsible for template name resolving
129
                unset(
2✔
130
                    $typoScriptConfiguration['templateName.'],
2✔
131
                    $this->contentObjectRenderer->data['controllerName'],
2✔
132
                    $this->contentObjectRenderer->data['controllerObjectName'],
2✔
133
                    $this->contentObjectRenderer->data['controllerAction'],
2✔
134
                    $this->contentObjectRenderer->data['controllerNameAndAction'],
2✔
135
                );
2✔
136
            }
137
        }
138

139
        // Early return if no (valid) template name is given
140
        if (empty($typoScriptConfiguration['templateName'])) {
2✔
141
            return $defaultConfiguration;
1✔
142
        }
143

144
        // Add format
145
        if (!isset($typoScriptConfiguration['format'])) {
1✔
146
            $typoScriptConfiguration['format'] = $format;
1✔
147
        }
148

149
        return $typoScriptConfiguration;
1✔
150
    }
151
}
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