Feature: #90899 - Introduce AssetRenderer pre-rendering events¶
See forge#90899
Description¶
AssetRenderer is amended by two events which allow post-processing of AssetCollector assets.
These new PSR-14 events are introduced:
\TYPO3\CMS\Core\Page\Event\BeforeJavaScriptsRenderingEvent
\TYPO3\CMS\Core\Page\Event\BeforeStylesheetsRenderingEvent
Both stem fom the abstract base class
\TYPO3\CMS\Core\Page\Event\AbstractBeforeAssetRenderingEvent
and provide
these public methods:
getAssetCollector(): AssetCollector
isInline(): bool
isPriority(): bool
inline
and priority
refer to how the asset was registered with
AssetCollector.
The events are fired exactly once for every combination of
inline
/priority
before the corresponding section of JS/CSS assets
is rendered by the AssetRenderer.
To make the events easier to use, the AssetCollector::get*()
methods
have gotten an optional parameter ?bool $priority = null
which when given a
boolean only returns assets of the given priority.
Note
post-processing functionality for assets registered via
TypoScript page.include...
or the PageRenderer::add*()
functions are still provided by these hooks:
$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler']
$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler']
$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler']
$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler']
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_pagerenderer.php']['render-preProcess']
Assets registered with the AssetCollector (and output through the AssetRenderer) are not included in those.
Example¶
As an example let's make sure jQuery is included in a specific version and from a CDN.
Register our listeners
Configuration/Services.yaml
services: MyVendor\MyExt\EventListener\AssetRenderer\LibraryVersion: tags: - name: event.listener identifier: 'myExt/LibraryVersion' event: TYPO3\CMS\Core\Page\Event\BeforeJavaScriptsRenderingEvent
Implement Listener to enforce a library version or CDN URI
namespace MyVendor\MyExt\EventListener\AssetRenderer; use TYPO3\CMS\Core\Page\Event\BeforeJavaScriptsRenderingEvent; /** * If a library has been registered, it is made sure that it is loaded * from the given URI */ class LibraryVersion { protected $libraries = [ 'jquery' => 'https://code.jquery.com/jquery-3.4.1.min.js', ]; public function __invoke(BeforeJavaScriptsRenderingEvent $event): void { if ($event->isInline()) { return; } foreach ($this->libraries as $library => $source) { $asset = $event->getAssetCollector()->getJavaScripts($event->isPriority()) // if it was already registered if ($asset[$library] ?? false) { // we set our authoritative version $event->getAssetCollector()->addJavaScript($library, $source); } } } }
Impact¶
Existing installations are not affected.
If using the AssetCollector API, these new events should be used for asset postprocessing.