[IMP] developer: rewrite the page on assets
closes odoo/documentation#1299 Signed-off-by: Géry Debongnie (ged) <ged@openerp.com>
This commit is contained in:
parent
11171da6b1
commit
8c79319011
@ -9,18 +9,22 @@ Managing assets in Odoo is not as straightforward as it is in some other apps.
|
|||||||
One of the reasons is that we have a variety of situations where some, but not all
|
One of the reasons is that we have a variety of situations where some, but not all
|
||||||
of the assets are required. For example, the needs of the web client, the point of
|
of the assets are required. For example, the needs of the web client, the point of
|
||||||
sale app, the website or even the mobile application are different. Also, some
|
sale app, the website or even the mobile application are different. Also, some
|
||||||
assets may be large, but are seldom needed. In that case, we sometimes want them
|
assets may be large, but are seldom needed: in that case we may want them
|
||||||
to be loaded lazily.
|
to be :ref:`loaded lazily (on demand) <frontend/assets/lazy_loading>`.
|
||||||
|
|
||||||
The main idea is that we define a set of **bundles** in the module manifest. A
|
Bundles
|
||||||
bundle is here defined as a **list of file paths** (xml, javascript, css, scss).
|
=======
|
||||||
Files are declared using `glob <https://en.wikipedia.org/wiki/Glob_(programming)>`_ syntax, meaning that you can declare several asset
|
|
||||||
files using a single line. Each matching file found will be appended to the
|
|
||||||
`<head>` of the page, at most once, in the order the glob patterns are given.
|
|
||||||
|
|
||||||
As mentioned, the bundles are declared in each module's :file:`__manifest__.py`, under
|
Odoo assets are grouped by *bundles*. Each bundle (a *list of file paths*
|
||||||
a dedicated `assets` key which contains a dictionary. The dictionary will map
|
of specific types: `xml`, `js`, `css` or `scss`) is listed in the
|
||||||
**bundles** (keys) to the list of **files** they contain (values). It looks like this:
|
:ref:`module manifest <reference/module/manifest>`. Files can be declared using
|
||||||
|
`glob <https://en.wikipedia.org/wiki/Glob_(programming)>`_ syntax, meaning that
|
||||||
|
you can declare several asset files using a single line.
|
||||||
|
|
||||||
|
The bundles are defined in each module's :file:`__manifest__.py`,
|
||||||
|
with a dedicated `assets` key which contains a dictionary. The dictionary maps
|
||||||
|
bundle names (keys) to the list of files they contain (values). It looks
|
||||||
|
like this:
|
||||||
|
|
||||||
.. code-block:: py
|
.. code-block:: py
|
||||||
|
|
||||||
@ -38,197 +42,217 @@ a dedicated `assets` key which contains a dictionary. The dictionary will map
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Here is a list of some important bundles that most odoo developers will need to
|
||||||
The files in a bundle can then be inserted into a template by using the `t-call-assets`
|
know:
|
||||||
directive:
|
|
||||||
|
|
||||||
.. code-block:: xml
|
|
||||||
|
|
||||||
<t t-call-assets="web.assets_common" t-js="false"/>
|
|
||||||
<t t-call-assets="web.assets_common" t-css="false"/>
|
|
||||||
|
|
||||||
Here is what happens when a template is rendered by the server with these directives:
|
|
||||||
|
|
||||||
- all the scss files described in the bundle are compiled into css files. A file
|
|
||||||
named :file:`file.scss` will be compiled in a file named :file:`file.scss.css`.
|
|
||||||
|
|
||||||
- if we are in `debug=assets` mode
|
|
||||||
|
|
||||||
- the `t-call-assets` directive with the `t-js` attribute set to false will
|
|
||||||
be replaced by a list of stylesheet tags pointing to the css files
|
|
||||||
|
|
||||||
- the `t-call-assets` directive with the `t-css` attribute set to false will
|
|
||||||
link to the non minified bundle file (which uses sourcemaps)
|
|
||||||
|
|
||||||
- if we are not in `debug=assets` mode
|
|
||||||
|
|
||||||
- the css files will be concatenated and minified, then a stylesheet tag is
|
|
||||||
generated
|
|
||||||
|
|
||||||
- the js files are concatenated and minified, then a script tag is generated
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
Assets files are cached, so in theory, a browser should only load them once.
|
|
||||||
|
|
||||||
Main bundles
|
|
||||||
------------
|
|
||||||
When the Odoo server is started, it checks the timestamp of each file in a bundle
|
|
||||||
and, if necessary, create/recreate the corresponding bundles.
|
|
||||||
|
|
||||||
Here are some important bundles that most developers will need to know:
|
|
||||||
|
|
||||||
- `web.assets_common`: this bundle contains most assets which are common to the
|
- `web.assets_common`: this bundle contains most assets which are common to the
|
||||||
web client, the website, and also the point of sale. This is supposed to contain
|
web client, the website and also the point of sale. This is supposed to contain
|
||||||
lower level building blocks for the odoo framework. Note that it contains the
|
lower level building blocks for the odoo framework. Note that it contains the
|
||||||
:file:`boot.js` file, which defines the odoo module system.
|
:file:`boot.js` file, which defines the odoo module system.
|
||||||
|
|
||||||
- `web.assets_backend`: this bundle contains the code specific to the web client
|
- `web.assets_backend`: this bundle contains the code specific to the web client
|
||||||
(notably the web client/action manager/views) and all static XML templates used
|
(notably the web client/action manager/views)
|
||||||
in the backend environment
|
|
||||||
|
|
||||||
- `web.assets_frontend`: this bundle is about all that is specific to the public
|
- `web.assets_frontend`: this bundle is about all that is specific to the public
|
||||||
website: ecommerce, forum, blog, event management, ...
|
website: ecommerce, portal, forum, blog, ...
|
||||||
|
|
||||||
|
- `web.assets_qweb`: all static XML templates used in the backend environment
|
||||||
|
and in the point of sale.
|
||||||
|
|
||||||
|
- `web.qunit_suite_tests`: all javascript qunit testing code (tests, helpers, mocks)
|
||||||
|
|
||||||
|
- `web.qunit_mobile_suite_tests`: mobile specific qunit testing code
|
||||||
|
|
||||||
|
Asset types
|
||||||
|
===========
|
||||||
|
|
||||||
|
There are three different asset types: code (`js` files), style (`css` or `scss`
|
||||||
|
files) and templates (`xml` files).
|
||||||
|
|
||||||
|
Code
|
||||||
|
Odoo supports :ref:`three different kinds of javascript files<frontend/js_modules>`.
|
||||||
|
All these files are then processed (native JS modules are transformed into odoo
|
||||||
|
modules), then minified (if not in `debug=assets` :ref:`mode <frontend/framework/assets_debug_mode>`)
|
||||||
|
and concatenated. The result is then saved as a file attachment. These file
|
||||||
|
attachments are usually loaded via a `<script>` tag in the `<head>` part of
|
||||||
|
the page (as a static file).
|
||||||
|
|
||||||
|
Style
|
||||||
|
Styling can be done with either `css` or `scss <https://sass-lang.com/>`_. Like
|
||||||
|
the javascript files, these files are processed (`scss` files are converted into
|
||||||
|
`css`), then minified (again, if not in `debug=assets` :ref:`mode <frontend/framework/assets_debug_mode>`)
|
||||||
|
and concatenated. The result is then saved as a file attachment. They are
|
||||||
|
then usually loaded via a `<link>` tag in the `<head>` part of the page (as
|
||||||
|
a static file).
|
||||||
|
|
||||||
|
Template
|
||||||
|
Templates (static `xml` files) are handled in a different way: they are simply
|
||||||
|
read from the file system whenever they are needed, and concatenated.
|
||||||
|
|
||||||
|
Whenever the browser loads odoo, it calls the `/web/webclient/qweb/` controller
|
||||||
|
to fetch the :ref:`templates <reference/qweb>`.
|
||||||
|
|
||||||
|
It is useful to know that in most cases, a browser only performs a request the
|
||||||
|
first time it loads a page. This is because each of these assets are
|
||||||
|
associated with a checksum, which is injected into the page source. The checksum
|
||||||
|
is then added to the url, which means that it is possible to safely set the cache
|
||||||
|
headers to a long period.
|
||||||
|
|
||||||
Operations on asset bundles
|
Operations on asset bundles
|
||||||
---------------------------
|
===========================
|
||||||
|
|
||||||
Typically, handling assets is quite trivial: you just need to add some new files
|
Typically, handling assets is simple: you just need to add some new files
|
||||||
to a frequently used bundle like 'common' or 'backend'. But there are other operations
|
to a frequently used bundle like `assets_common` or `assets_backend`. But there are other operations
|
||||||
available to cover use cases bringing additional constraints. Such cases can mostly
|
available to cover some more specific use cases.
|
||||||
be covered with the following operations.
|
|
||||||
|
|
||||||
- Add one or multiple file(s): `append`
|
Note that all directives targeting a certain asset file (i.e. `before`, `after`,
|
||||||
The proper way to add a file to a bundle in any addon is simple: it is just enough
|
`replace` and `remove`) need that file to be declared beforehand, either
|
||||||
to add a glob pattern to the bundle in the file :file:`__manifest__.py` like so:
|
in manifests higher up in the hierarchy or in ``ir.asset`` records with a lower
|
||||||
|
sequence.
|
||||||
|
|
||||||
.. code-block:: py
|
`append`
|
||||||
|
--------
|
||||||
|
|
||||||
|
This operation adds one or multiple file(s). Since it is the most common
|
||||||
|
operation, it can be done by simply using the file name:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
'my_addon/static/src/js/**/*',
|
'my_addon/static/src/js/**/*',
|
||||||
],
|
],
|
||||||
|
|
||||||
By default, adding a simple string to a bundle will append the files matching the
|
By default, adding a simple string to a bundle will append the files matching the
|
||||||
glob pattern at the end of the bundle. Obviously, the pattern may also be directly
|
glob pattern at the end of the bundle. Obviously, the pattern may also be directly
|
||||||
a single file path.
|
a single file path.
|
||||||
|
|
||||||
- Add one or multiple file(s) at the beginning of the list: `prepend`
|
`prepend`
|
||||||
Sometimes you need to put a certain file before the others in a bundle, when
|
---------
|
||||||
loading css file, for example. In this case, you can use the `prepend` directive
|
|
||||||
by replacing the path with a pair `('prepend', <path>)`,
|
|
||||||
like so:
|
|
||||||
|
|
||||||
.. code-block:: py
|
Add one or multiple file(s) at the beginning of the bundle.
|
||||||
|
|
||||||
|
Useful when you need to put a certain file before the others in a bundle (for
|
||||||
|
example with css files). The `prepend` operation is invoked with the following
|
||||||
|
syntax: `('prepend', <path>)`.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
('prepend', 'my_addon/static/src/css/bootstrap_overridden.scss'),
|
('prepend', 'my_addon/static/src/css/bootstrap_overridden.scss'),
|
||||||
],
|
],
|
||||||
|
|
||||||
- Add one or multiple file(s) before a specific file: `before`
|
`before`
|
||||||
Prepending a file at the beginning of a bundle might not be precise enough. The
|
--------
|
||||||
`before` directive can be used to add the given file(s) right *before* the target
|
|
||||||
file. It is declared by replacing the normal path with a 3-element tuple
|
|
||||||
`('before', <target>, <path>)`, like so:
|
|
||||||
|
|
||||||
.. code-block:: py
|
Add one or multiple file(s) before a specific file.
|
||||||
|
|
||||||
|
Prepending a file at the beginning of a bundle might not be precise enough. The
|
||||||
|
`before` directive can be used to add the given file(s) right *before* the target
|
||||||
|
file. It is declared by replacing the normal path with a 3-element tuple
|
||||||
|
`('before', <target>, <path>)`.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
('before', 'web/static/src/css/bootstrap_overridden.scss', 'my_addon/static/src/css/bootstrap_overridden.scss'),
|
('before', 'web/static/src/css/bootstrap_overridden.scss', 'my_addon/static/src/css/bootstrap_overridden.scss'),
|
||||||
],
|
],
|
||||||
|
|
||||||
- Add one or multiple file(s) after a specific file: `after`
|
`after`
|
||||||
Same as `before`, with the matching file(s) appended right *after* the target file.
|
-------
|
||||||
It is declared by replacing the normal path with a 3-element tuple
|
|
||||||
`('after', <target>, <path>)`, like so:
|
|
||||||
|
|
||||||
.. code-block:: py
|
Add one or multiple file(s) after a specific file.
|
||||||
|
|
||||||
|
Same as `before`, with the matching file(s) appended right *after* the target file.
|
||||||
|
It is declared by replacing the normal path with a 3-element tuple
|
||||||
|
`('after', <target>, <path>)`.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
('after', 'web/static/src/css/list_view.scss', 'my_addon/static/src/css/list_view.scss'),
|
('after', 'web/static/src/css/list_view.scss', 'my_addon/static/src/css/list_view.scss'),
|
||||||
],
|
],
|
||||||
|
|
||||||
- Use nested bundles: `include`
|
`include`
|
||||||
The `include` directive is a way to use a same bundle in other bundles to minimize
|
---------
|
||||||
the size of your manifest. In Odoo we use sub bundles (prefixed with an underscore
|
|
||||||
by convention) to batch files used in multiple other bundles. You can then
|
|
||||||
specify the sub bundle as a pair `('include', <bundle>)` like this:
|
|
||||||
|
|
||||||
.. code-block:: py
|
Use nested bundles.
|
||||||
|
|
||||||
|
The `include` directive is a way to use a bundle in other bundles to minimize
|
||||||
|
the size of your manifest. In Odoo we use sub bundles (prefixed with an underscore
|
||||||
|
by convention) to batch files used in multiple other bundles. You can then
|
||||||
|
specify the sub bundle as a pair `('include', <bundle>)` like this:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
('include', 'web._primary_variables'),
|
('include', 'web._primary_variables'),
|
||||||
],
|
],
|
||||||
|
|
||||||
- Remove one or multiple file(s): `remove`
|
`remove`
|
||||||
In some additional module you may want to get rid of the call of a certain asset
|
--------
|
||||||
in a bundle. Any file can be removed from an existing bundle using the `remove`
|
|
||||||
directive by specifying a pair `('remove', <target>)`:
|
|
||||||
|
|
||||||
.. code-block:: py
|
Remove one or multiple file(s).
|
||||||
|
|
||||||
|
In some cases, you may want to remove one or multiple files from a bundle. This
|
||||||
|
can be done using the `remove` directive by specifying a pair
|
||||||
|
`('remove', <target>)`:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
('remove', 'web/static/src/js/boot.js'),
|
('remove', 'web/static/src/js/boot.js'),
|
||||||
],
|
],
|
||||||
|
|
||||||
- Replace an asset file with one or multiple file(s): `replace`
|
`replace`
|
||||||
Let us now say that an asset need not only to be removed, but you also want to insert
|
---------
|
||||||
your new version of that asset at the same exact position. This can be done with
|
|
||||||
the `replace` directive, using a 3-element tuple `('replace', <target>, <path>)`:
|
|
||||||
|
|
||||||
.. code-block:: py
|
Replace an asset file with one or multiple file(s).
|
||||||
|
|
||||||
|
Let us say that an asset needs not only to be removed, but you also want to insert
|
||||||
|
your new version of that asset at the same exact position. This can be done with
|
||||||
|
the `replace` directive, using a 3-element tuple `('replace', <target>, <path>)`:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
('replace', 'web/static/src/js/boot.js', 'my_addon/static/src/js/boot.js'),
|
('replace', 'web/static/src/js/boot.js', 'my_addon/static/src/js/boot.js'),
|
||||||
],
|
],
|
||||||
|
|
||||||
Note that all directives targeting a certain asset file (i.e. `before`, `after`,
|
|
||||||
`replace` and `remove`) need that file to be declared beforehand, either
|
|
||||||
in manifests higher up in the hierarchy or in ``ir.asset`` records with a lower
|
|
||||||
sequence.
|
|
||||||
|
|
||||||
.. note::
|
Loading order
|
||||||
|
=============
|
||||||
Note that the files in a bundle are all loaded immediately when the user loads the
|
|
||||||
odoo web client. This means that the files are transferred through the network
|
|
||||||
every time (except when the browser cache is active). In some cases, it may be
|
|
||||||
better to lazyload some assets. For example, if a widget requires a large
|
|
||||||
library, and that widget is not a core part of the experience, then it may be
|
|
||||||
a good idea to only load the library when the widget is actually created. The
|
|
||||||
widget class has actually built-in support just for this use case. (see section
|
|
||||||
:ref:`reference/javascript_reference/qweb`)
|
|
||||||
|
|
||||||
Assets loading order
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
The order in which assets are loaded is sometimes critical and must be deterministic,
|
The order in which assets are loaded is sometimes critical and must be deterministic,
|
||||||
mostly for stylesheets priorities and setup scripts. Assets in Odoo are processed
|
mostly for stylesheets priorities and setup scripts. Assets in Odoo are processed
|
||||||
as follows.
|
as follows:
|
||||||
|
|
||||||
1. When an asset bundle is called (e.g. `t-call-assets="web.assets_common"`), an empty
|
#. When an asset bundle is called (e.g. `t-call-assets="web.assets_common"`), an empty
|
||||||
list of assets is generated
|
list of assets is generated
|
||||||
|
|
||||||
2. All records of type ``ir.asset`` matching the bundle will be fetched and sorted
|
#. All records of type `ir.asset` matching the bundle are fetched and sorted
|
||||||
by sequence number. Then all records with a sequence strictly less than 16 will
|
by sequence number. Then all records with a sequence strictly less than 16 are
|
||||||
be processed and applied to the current list of assets.
|
processed and applied to the current list of assets.
|
||||||
|
|
||||||
3. All modules declaring assets for said bundle in their manifest will apply their
|
#. All modules declaring assets for said bundle in their manifest apply their
|
||||||
assets operations to this list. This is done following the order of modules dependencies
|
assets operations to this list. This is done following the order of modules dependencies
|
||||||
(e.g. 'web' assets will be processed before 'website'). If a directive tries to add
|
(e.g. `web` assets is processed before 'website'). If a directive tries to add
|
||||||
a file already present in the list, nothing is done for that file. In other word,
|
a file already present in the list, nothing is done for that file. In other word,
|
||||||
only the first occurrence of a file is kept in the list.
|
only the first occurrence of a file is kept in the list.
|
||||||
|
|
||||||
4. The remaining ``ir.asset`` records (those with a sequence greater than or equal
|
#. The remaining `ir.asset` records (those with a sequence greater than or equal
|
||||||
to 16) are then processed and applied as well.
|
to 16) are then processed and applied as well.
|
||||||
|
|
||||||
Assets declared in the manifest may need to be loaded in a particular order, for
|
Assets declared in the manifest may need to be loaded in a particular order, for
|
||||||
example :file:`jquery.js` must be loaded before all other jquery scripts when loading the
|
example :file:`jquery.js` must be loaded before all other jquery scripts when loading the
|
||||||
lib folder. One solution would be to create an ``ir.asset`` record with a lower sequence
|
lib folder. One solution would be to create an :ref:`ir.asset <frontend/assets/ir_asset>`
|
||||||
or a 'prepend' directive, but there is another simpler way to do so.
|
record with a lower sequence or a 'prepend' directive, but there is another simpler
|
||||||
|
way to do so.
|
||||||
|
|
||||||
Since the unicity of each file path in the list of assets is guaranteed, you can
|
Since the unicity of each file path in the list of assets is guaranteed, you can
|
||||||
mention any specific file before a glob that includes it. That file will thus appear
|
mention any specific file before a glob that includes it. That file will thus appear
|
||||||
in the list before all the others included in the glob.
|
in the list before all the others included in the glob.
|
||||||
|
|
||||||
.. code-block:: py
|
.. code-block:: python
|
||||||
|
|
||||||
'web.assets_common': [
|
'web.assets_common': [
|
||||||
'my_addon/static/lib/jquery/jquery.js',
|
'my_addon/static/lib/jquery/jquery.js',
|
||||||
@ -241,13 +265,62 @@ in the list before all the others included in the glob.
|
|||||||
to depend on it. Trying to operate on assets that have yet to be declared will
|
to depend on it. Trying to operate on assets that have yet to be declared will
|
||||||
result in an error.
|
result in an error.
|
||||||
|
|
||||||
|
.. _frontend/assets/lazy_loading:
|
||||||
|
|
||||||
|
Lazy loading assets
|
||||||
|
===================
|
||||||
|
|
||||||
|
It is sometimes useful to load files and/or asset bundles dynamically, for
|
||||||
|
example to only load a library once it is needed. To do that, the Odoo framework
|
||||||
|
provides a few helper functions, located in :file:`@web/core/assets`.
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
await loadAssets({
|
||||||
|
jsLibs: ["/web/static/lib/stacktracejs/stacktrace.js"],
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
.. js:function:: loadAssets(assets)
|
||||||
|
|
||||||
|
:param Object assets: a description of various assets that should be loaded
|
||||||
|
:returns: Promise<void>
|
||||||
|
|
||||||
|
Load the assets described py the `assets` parameter. It is an object that
|
||||||
|
may contain the following keys:
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:widths: 20 20 60
|
||||||
|
:header-rows: 1
|
||||||
|
|
||||||
|
* - Key
|
||||||
|
- Type
|
||||||
|
- Description
|
||||||
|
* - `jsLibs`
|
||||||
|
- `string[]`
|
||||||
|
- a list of urls of javascript files
|
||||||
|
* - `cssLibs`
|
||||||
|
- `string[]`
|
||||||
|
- a list of urls of css files
|
||||||
|
|
||||||
|
|
||||||
|
.. js:function:: useAssets(assets)
|
||||||
|
|
||||||
|
:param Object assets: a description of various assets that should be loaded
|
||||||
|
|
||||||
|
This hook is useful when components need to load some assets in their
|
||||||
|
`onWillStart` method. It internally calls `loadAssets`.
|
||||||
|
|
||||||
|
.. _frontend/assets/ir_asset:
|
||||||
|
|
||||||
The asset model (`ir.asset`)
|
The asset model (`ir.asset`)
|
||||||
------------------------------
|
============================
|
||||||
|
|
||||||
In most cases the assets declared in the manifest will largely suffice. Yet for
|
In most cases the assets declared in the manifest will largely suffice. Yet for
|
||||||
more flexibility, the framework also supports dynamic assets declared in the
|
more flexibility, the framework also supports dynamic assets declared in the
|
||||||
database.
|
database.
|
||||||
This is done by creating ``ir.asset`` records. Those will be processed as if they
|
|
||||||
|
This is done by creating `ir.asset` records. Those will be processed as if they
|
||||||
were found in a module manifest, and they give the same expressive power as their
|
were found in a module manifest, and they give the same expressive power as their
|
||||||
manifest counterparts.
|
manifest counterparts.
|
||||||
|
|
||||||
|
@ -20,11 +20,29 @@ documents the list of hooks provided by the Odoo web framework.
|
|||||||
|
|
||||||
* - Name
|
* - Name
|
||||||
- Short Description
|
- Short Description
|
||||||
|
* - :ref:`useAssets <frontend/hooks/useassets>`
|
||||||
|
- load assets
|
||||||
* - :ref:`useBus <frontend/hooks/usebus>`
|
* - :ref:`useBus <frontend/hooks/usebus>`
|
||||||
- subscribe and unsubscribe to a bus
|
- subscribe and unsubscribe to a bus
|
||||||
* - :ref:`usePosition <frontend/hooks/useposition>`
|
* - :ref:`usePosition <frontend/hooks/useposition>`
|
||||||
- position an element relative to a target
|
- position an element relative to a target
|
||||||
|
|
||||||
|
.. _frontend/hooks/useassets:
|
||||||
|
|
||||||
|
useAssets
|
||||||
|
=========
|
||||||
|
|
||||||
|
Location
|
||||||
|
--------
|
||||||
|
|
||||||
|
`@web/core/assets`
|
||||||
|
|
||||||
|
Description
|
||||||
|
-----------
|
||||||
|
|
||||||
|
See the section on :ref:`lazy loading assets <frontend/assets/lazy_loading>` for
|
||||||
|
more details.
|
||||||
|
|
||||||
.. _frontend/hooks/usebus:
|
.. _frontend/hooks/usebus:
|
||||||
|
|
||||||
useBus
|
useBus
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
.. _frontend/js_modules:
|
||||||
|
|
||||||
==================
|
==================
|
||||||
Javascript Modules
|
Javascript Modules
|
||||||
==================
|
==================
|
||||||
|
Loading…
Reference in New Issue
Block a user