Skip to content

Commit 9119a77

Browse files
authored
Restore functionality for adding CSS/JavaScript using TypoScript. (#267)
This was removed when adding TYPO3 v14 compatibility: #262 Now it works again, but the prefix has changed from `typo3_encore:` to `PKG:typo3_encore:`. Example: ``` page.includeCSS { app = PKG:typo3_encore:app } page.includeJS { app = PKG:typo3_encore:app } ```
1 parent dd4d7b7 commit 9119a77

5 files changed

Lines changed: 162 additions & 3 deletions

File tree

Classes/Asset/TagRenderer.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ public function renderWebpackLinkTags(LinkTag $linkTag): void
168168
'excludeFromConcatenation' => true,
169169
'splitChar' => '|',
170170
'inline' => false,
171+
'tagAttributes' => [],
172+
'integrity' => '',
173+
'crossorigin' => '',
171174
], $parameters);
172175

173176
$attributes = array_values($attributes);
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the "typo3_encore" Extension for TYPO3 CMS.
7+
*
8+
* For the full copyright and license information, please read the
9+
* LICENSE.txt file that was distributed with this source code.
10+
*/
11+
12+
namespace Ssch\Typo3Encore\Integration;
13+
14+
use Ssch\Typo3Encore\Asset\EntrypointLookupInterface;
15+
use Ssch\Typo3Encore\Asset\TagRendererInterface;
16+
use Ssch\Typo3Encore\ValueObject\LinkTag;
17+
use Ssch\Typo3Encore\ValueObject\ScriptTag;
18+
use TYPO3\CMS\Core\Page\PageRenderer;
19+
use TYPO3\CMS\Core\Utility\GeneralUtility;
20+
21+
final class PageRendererHooks
22+
{
23+
/**
24+
* @var string
25+
*/
26+
private const ENCORE_PREFIX = 'PKG:ssch/typo3-encore:';
27+
28+
/**
29+
* @var int
30+
*/
31+
private const PART_FOOTER = 2;
32+
33+
public function __construct(
34+
private readonly TagRendererInterface $tagRenderer
35+
) {
36+
}
37+
38+
public function renderPreProcess(array $params, PageRenderer $pageRenderer): void
39+
{
40+
// At this point, TYPO3 provides all javascript includes in only 'Files' or 'Libs'
41+
foreach (TagRendererInterface::ALLOWED_JS_POSITIONS as $includeType) {
42+
if (! isset($params[$includeType])) {
43+
continue;
44+
}
45+
46+
// Is the include type 'jsLibs' and should be treated as a library
47+
$isLibrary = TagRendererInterface::POSITION_JS_LIBRARY === $includeType;
48+
49+
foreach ($params[$includeType] as $key => $jsFile) {
50+
if (! $this->isEncoreEntryName($jsFile['file'])) {
51+
continue;
52+
}
53+
54+
$buildAndEntryName = $this->createBuildAndEntryName($jsFile['file']);
55+
$buildName = EntrypointLookupInterface::DEFAULT_BUILD;
56+
57+
if (2 === count($buildAndEntryName)) {
58+
[$buildName, $entryName] = $buildAndEntryName;
59+
} else {
60+
$entryName = $buildAndEntryName[0];
61+
}
62+
63+
$position = ($jsFile['section'] ?? '') === self::PART_FOOTER ? TagRendererInterface::POSITION_FOOTER : '';
64+
65+
unset($params[$includeType][$key], $jsFile['file'], $jsFile['section'], $jsFile['integrity']);
66+
67+
$scriptTag = new ScriptTag($entryName, $position, $buildName, $pageRenderer, $jsFile, true, $isLibrary);
68+
69+
$this->tagRenderer->renderWebpackScriptTags($scriptTag);
70+
}
71+
}
72+
73+
// Add CSS-Files by entryNames
74+
foreach (TagRendererInterface::ALLOWED_CSS_POSITIONS as $includeType) {
75+
if (! isset($params[$includeType])) {
76+
continue;
77+
}
78+
79+
foreach ($params[$includeType] as $key => $cssFile) {
80+
if (! $this->isEncoreEntryName($cssFile['file'])) {
81+
continue;
82+
}
83+
$buildAndEntryName = $this->createBuildAndEntryName($cssFile['file']);
84+
$buildName = EntrypointLookupInterface::DEFAULT_BUILD;
85+
86+
if (2 === count($buildAndEntryName)) {
87+
[$buildName, $entryName] = $buildAndEntryName;
88+
} else {
89+
$entryName = $buildAndEntryName[0];
90+
}
91+
92+
unset($params[$includeType][$key], $cssFile['file'], $cssFile['rel']);
93+
94+
$linkTag = new LinkTag($entryName, 'all', $buildName, $pageRenderer, $cssFile);
95+
$this->tagRenderer->renderWebpackLinkTags($linkTag);
96+
}
97+
}
98+
}
99+
100+
private function isEncoreEntryName(string $file): bool
101+
{
102+
return \str_starts_with($file, self::ENCORE_PREFIX);
103+
}
104+
105+
private function removePrefix(string $file): string
106+
{
107+
return str_replace(self::ENCORE_PREFIX, '', $file);
108+
}
109+
110+
private function createBuildAndEntryName(string $file): array
111+
{
112+
return GeneralUtility::trimExplode(':', $this->removePrefix($file), true, 2);
113+
}
114+
}

README.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,31 @@ If you have defined multiple entries you can define the desired entryName in the
6161
</html>
6262
```
6363

64-
Note the prefix typo3_encore: This is important in order to render the files correctly.
64+
65+
Alternatively you can also include the files via TypoScript
66+
67+
```php
68+
page.includeCSS {
69+
# Pattern PKG:typo3_encore:entryName
70+
app = PKG:typo3_encore:app
71+
# If you want to ensure that this file is loaded first uncomment the next line
72+
# app.forceOnTop = 1
73+
}
74+
75+
page.includeJS {
76+
# Pattern PKG:typo3_encore:entryName
77+
app = PKG:typo3_encore:app
78+
# If you want to ensure that this file is loaded first uncomment the next line
79+
# app.forceOnTop = 1
80+
}
81+
82+
page.includeJSFooter {
83+
# Pattern PKG:typo3_encore:entryName
84+
app = PKG:typo3_encore:app
85+
}
86+
```
87+
88+
Note the prefix PKG:typo3_encore: This is important in order to render the files correctly.
6589
You can then use all other known settings to include your files.
6690

6791
You don´t have to care about including it only once. This will not happen during one request cycle unless you want to.
@@ -143,6 +167,15 @@ This way of using the AssetViewHelper is similar to the `asset` function used in
143167
}
144168
```
145169

170+
Finally, you can specify which build to use:
171+
172+
```php
173+
page.includeCSS {
174+
# Pattern PKG:typo3_encore:buildName:entryName
175+
app = PKG:typo3_encore:firstBuild:app
176+
}
177+
```
178+
146179
```html
147180
<html
148181
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"

Tests/Unit/Asset/TagRendererTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,10 @@ public function testRenderWebpackLinkTagsWithDefaultBuild(): void
151151
'',
152152
true,
153153
'|',
154-
false
154+
false,
155+
[],
156+
'',
157+
''
155158
)->shouldBeCalledOnce();
156159

157160
$this->assetRegistry->registerFile(Argument::any())->shouldBeCalledOnce();
@@ -180,7 +183,10 @@ public function testRenderWebpackLinkTagsWithDefaultBuildWithoutAssetRegistratio
180183
'',
181184
true,
182185
'|',
183-
false
186+
false,
187+
[],
188+
'',
189+
''
184190
)->shouldBeCalledOnce();
185191

186192
$this->assetRegistry->registerFile(Argument::any())->shouldNotBeCalled();

ext_localconf.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?php
22

3+
// Enable for Frontend and Backend at the same time
4+
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess']['typo3_encore'] = \Ssch\Typo3Encore\Integration\PageRendererHooks::class . '->renderPreProcess';
5+
36
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['formDataGroup']['tcaDatabaseRecord'][\Ssch\Typo3Encore\Form\FormDataProvider\RichtextEncoreConfiguration::class] = [
47
'depends' => [\TYPO3\CMS\Backend\Form\FormDataProvider\TcaText::class],
58
];

0 commit comments

Comments
 (0)