Feature: #90522 - Introduce AssetCollector
See forge#90522
Description
AssetCollector is a concept to allow custom CSS/JS code, inline or external, to be added multiple
times in e.g. a Fluid template (via <f:
or <f:
ViewHelpers) but only rendered once
in the output.
The priority
flag (default: false
) controls where the asset is included:
- JavaScript will be output inside
<head>
(priority=true
) or at the bottom of the<body>
tag (priority=false
) - CSS will always be output inside
<head>
, yet grouped bypriority
.
By including assets per-component, it can leverage the adoption of HTTP/2 multiplexing which removes the necessity of having all CSS/JavaScript concatenated into one file.
AssetCollector is implemented as singleton and should slowly replace the various existing options in TypoScript.
AssetCollector also collects information about "imagesOnPage", effectively taking off pressure from PageRenderer and TSFE to store common data in FE - as this is now handled in AssetCollector, which can be used in cached and non-cached components.
The new API
\TYPO3\
CMS\ Core\ Page\ Asset Collector:: add Java Script (string $identifier, string $source, array $attributes, array $options = []): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: add Inline Java Script (string $identifier, string $source, array $attributes, array $options = []): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: add Style Sheet (string $identifier, string $source, array $attributes, array $options = []): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: add Inline Style Sheet (string $identifier, string $source, array $attributes, array $options = []): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: add Media (string $file Name, array $additional Information): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: remove Java Script (string $identifier): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: remove Inline Java Script (string $identifier): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: remove Style Sheet (string $identifier): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: remove Inline Style Sheet (string $identifier): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: remove Media (string $identifier): self \TYPO3\
CMS\ Core\ Page\ Asset Collector:: get Java Scripts (?bool $priority = null): array \TYPO3\
CMS\ Core\ Page\ Asset Collector:: get Inline Java Scripts (?bool $priority = null): array \TYPO3\
CMS\ Core\ Page\ Asset Collector:: get Style Sheets (?bool $priority = null): array \TYPO3\
CMS\ Core\ Page\ Asset Collector:: get Inline Style Sheets (?bool $priority = null): array \TYPO3\
CMS\ Core\ Page\ Asset Collector:: get Media (): array
New ViewHelpers
There are also two new ViewHelpers, the <f:
and the - <f:
ViewHelper which use the AssetCollector API.
<f:asset.css identifier="identifier123" href="EXT:my_ext/Resources/Public/Css/foo.css" />
<f:asset.css identifier="identifier123">
.foo { color: black; }
</f:asset.css>
<f:asset.script identifier="identifier123" src="EXT:my_ext/Resources/Public/JavaScript/foo.js" />
<f:asset.script identifier="identifier123">
alert('hello world');
</f:asset.script>
Considerations
Currently, assets registered with the AssetCollector are not included in callbacks of these hooks:
$GLOBALS
['TYPO3_ CONF_ VARS'] [TYPO3_ MODE] ['css Compress Handler'] $GLOBALS
['TYPO3_ CONF_ VARS'] [TYPO3_ MODE] ['js Compress Handler'] $GLOBALS
['TYPO3_ CONF_ VARS'] [TYPO3_ MODE] ['css Concatenate Handler'] $GLOBALS
['TYPO3_ CONF_ VARS'] [TYPO3_ MODE] ['js Concatenate Handler']
New in version 10.4
Events for the new API have been introduced in Feature: #90899 - Introduce AssetRenderer pre-rendering events
Currently, CSS and JavaScript registered with the AssetCollector will be rendered after their PageRenderer counterparts. The order is:
<head>
page.
include JSLibs. force On Top page.
include JSLibs page.
include JS. force On Top page.
include JS Asset
with 'priority'Collector:: add Java Script () page.
js Inline Asset
with 'priority'Collector:: add Inline Java Script () </
head> page.
include JSFooterlibs. force On Top page.
include JSFooterlibs page.
include JSFooter. force On Top page.
include JSFooter Asset
Collector:: add Java Script () page.
js Footer Inline Asset
Collector:: add Inline Java Script ()
Currently, JavaScript registered with AssetCollector is not affected by
config.
.
Examples
Add a JavaScript file to the collector with script attribute data-foo="bar":
GeneralUtility::makeInstance(AssetCollector::class)
->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['data-foo' => 'bar']);
Add a JavaScript file to the collector with script attribute data-
and priority which means rendering before other script tags:
GeneralUtility::makeInstance(AssetCollector::class)
->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['data-foo' => 'bar'], ['priority' => true]);
Add a JavaScript file to the collector with type="module"
(by default, no type= is output for JavaScript):
GeneralUtility::makeInstance(AssetCollector::class)
->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['type' => 'module']);