Feature-90522-IntroduceAssetCollector.rst 5.77 KB
Newer Older
1
2
.. include:: ../../Includes.txt

3
4
.. _changelog-Feature-90522-IntroduceAssetCollector:

5
6
7
8
9
10
11
12
13
14
==========================================
Feature: #90522 - Introduce AssetCollector
==========================================

See :issue:`90522`

Description
===========

AssetCollector is a concept to allow custom CSS/JS code, inline or external, to be added multiple
15
times in e.g. a Fluid template (via :html:`<f:asset.script>` or :html:`<f:asset.css>` ViewHelpers) but only rendered once
16
17
in the output.

18
The :php:`priority` flag (default: :php:`false`) controls where the asset is included:
19

20
21
* JavaScript will be output inside :html:`<head>` (:php:`priority=true`) or at the bottom of the :html:`<body>` tag (:php:`priority=false`)
* CSS will always be output inside :html:`<head>`, yet grouped by :javascript:`priority`.
22
23
24

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.
25
26
27
28

AssetCollector is implemented as singleton and should slowly replace the various existing options
in TypoScript.

29
AssetCollector also collects information about "imagesOnPage", effectively taking off pressure from
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
-----------

- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addJavaScript(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addInlineJavaScript(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addStyleSheet(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addInlineStyleSheet(string $identifier, string $source, array $attributes, array $options = []): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::addMedia(string $fileName, array $additionalInformation): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeJavaScript(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeInlineJavaScript(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeStyleSheet(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeInlineStyleSheet(string $identifier): self`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::removeMedia(string $identifier): self`
46
47
48
49
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getJavaScripts(?bool $priority = null): array`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getInlineJavaScripts(?bool $priority = null): array`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getStyleSheets(?bool $priority = null): array`
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getInlineStyleSheets(?bool $priority = null): array`
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
- :php:`\TYPO3\CMS\Core\Page\AssetCollector::getMedia(): array`

New ViewHelpers
---------------

There are also two new ViewHelpers, the :html:`<f:asset.css>` and the - :html:`<f:asset.script>` ViewHelper which use the AssetCollector API.

.. code-block:: html

   <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>

69
70
71
72
73
74
75
76
77
78
Considerations
--------------

Currently, assets registered with the AssetCollector are not included in callbacks of these hooks:

- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssCompressHandler']`
- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsCompressHandler']`
- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['cssConcatenateHandler']`
- :php:`$GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['jsConcatenateHandler']`

79
80
81
82
83
84
.. versionadded:: 10.4

   Events for the new API have been introduced in
   :ref:`changelog-Feature-90899-IntroduceAssetPreRenderingEvents`

Currently, CSS and JavaScript registered with the AssetCollector will be rendered after their
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
PageRenderer counterparts. The order is:

- :html:`<head>`
- :ts:`page.includeJSLibs.forceOnTop`
- :ts:`page.includeJSLibs`
- :ts:`page.includeJS.forceOnTop`
- :ts:`page.includeJS`
- :php:`AssetCollector::addJavaScript()` with 'priority'
- :ts:`page.jsInline`
- :php:`AssetCollector::addInlineJavaScript()` with 'priority'
- :html:`</head>`

- :ts:`page.includeJSFooterlibs.forceOnTop`
- :ts:`page.includeJSFooterlibs`
- :ts:`page.includeJSFooter.forceOnTop`
- :ts:`page.includeJSFooter`
- :php:`AssetCollector::addJavaScript()`
- :ts:`page.jsFooterInline`
- :php:`AssetCollector::addInlineJavaScript()`

Currently, JavaScript registered with AssetCollector is not affected by
:ts:`config.moveJsFromHeaderToFooter`.
107
108
109
110

Examples
--------

111
Add a JavaScript file to the collector with script attribute data-foo="bar":
112
113
114

.. code-block:: php

115
    GeneralUtility::makeInstance(AssetCollector::class)
116
       ->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['data-foo' => 'bar']);
117

118
Add a JavaScript file to the collector with script attribute :html:`data-foo="bar"` and priority which means rendering before other script tags:
119
120
121

.. code-block:: php

122
    GeneralUtility::makeInstance(AssetCollector::class)
123
124
125
126
127
128
129
130
       ->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 :html:`type="module"` (by default, no type= is output for JavaScript):

.. code-block:: php

    GeneralUtility::makeInstance(AssetCollector::class)
       ->addJavaScript('my_ext_foo', 'EXT:my_ext/Resources/Public/JavaScript/foo.js', ['type' => 'module']);
131
132

.. index:: Backend, Frontend, PHP-API, ext:core