资产

在Odoo中管理资产并不像其他一些应用程序那样直接。其中一个原因是我们有各种情况,在某些情况下需要一些资产,但不需要全部。例如,Web客户端、销售点应用程序、网站甚至移动应用程序的需求是不同的。此外,有些资产可能很大,但很少需要使用:在这种情况下,我们可能希望它们是 按需加载(懒加载)

资产类型

有三种不同的资产类型:代码(js 文件),样式(cssscss 文件)和模板(xml 文件)。

代码

Odoo 支持 三种不同类型的 javascript 文件。所有这些文件都会被处理(原生 JS 模块会被转换为 odoo 模块),然后进行缩小(如果不在 debug=assets 模式 标签在页面的 <head> 部分加载(作为静态文件)。

样式

Styling can be done with either css or scss. Like the javascript files, these files are processed (scss files are converted into css), then minified (again, if not in debug=assets 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).

模板

模板(静态的 xml 文件)的处理方式不同:它们只是在需要时从文件系统中读取并连接。

每当浏览器加载Odoo时,它会调用 /web/webclient/qweb/ 控制器来获取 模板

了解在大多数情况下,浏览器只在第一次加载页面时执行请求是很有用的。这是因为每个资源都与校验和相关联,该校验和被注入到页面源代码中。然后将校验和添加到URL中,这意味着可以安全地将缓存头设置为长时间。

捆绑包

Odoo 资源被分组为 bundles 。每个 bundle(一个特定类型的文件路径的 列表xmljscssscss )在 module manifest 中列出。文件可以使用 glob <https://en.wikipedia.org/wiki/Glob_(programming)> _ 语法声明,这意味着您可以使用一行声明多个资源文件。

bundles are defined in each module’s __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:

'assets': {
    'web.assets_backend': [
        'web/static/src/xml/**/*',
    ],
    'web.assets_common': [
        'web/static/lib/bootstrap/**/*',
        'web/static/src/js/boot.js',
        'web/static/src/js/webclient.js',
        'web/static/src/xml/webclient.xml',
    ],
    'web.qunit_suite_tests': [
        'web/static/src/js/webclient_tests.js',
    ],
},

以下是大多数Odoo开发人员需要了解的一些重要的捆绑包列表:

  • 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 lower level building blocks for the odoo framework. Note that it contains the boot.js file, which defines the odoo module system.

  • web.assets_backend:此捆绑包包含特定于Web客户端的代码(尤其是Web客户端/操作管理器/视图/静态XML模板)

  • web.assets_frontend: this bundle is about all that is specific to the public website: ecommerce, portal, forum, blog, …

  • web.qunit_suite_tests: all javascript qunit testing code (tests, helpers, mocks)

  • web.qunit_mobile_suite_tests: mobile specific qunit testing code

操作

通常,处理资源很简单:您只需要将一些新文件添加到常用的捆绑包中,如 assets_commonassets_backend。但是,还有其他操作可用于处理一些更具体的用例。

注意,所有指令都针对特定的资产文件(即 beforeafterreplaceremove ),需要在之前声明该文件,可以是在层次结构中更高的清单中,也可以是具有较低序列的 ir.asset 记录。

append

此操作添加一个或多个文件。由于这是最常见的操作,因此可以通过简单地使用文件名来完成:

'web.assets_common': [
    'my_addon/static/src/js/**/*',
],

默认情况下,将简单字符串添加到包中将在包的末尾添加与 glob 模式匹配的文件。显然,该模式也可以直接是单个文件路径。

prepend

在捆绑包的开头添加一个或多个文件。

在需要将某个文件放在捆绑文件中的其他文件之前时非常有用(例如,对于css文件)。 prepend 操作的调用语法如下: ('prepend', <path>)

'web.assets_common': [
    ('prepend', 'my_addon/static/src/css/bootstrap_overridden.scss'),
],

before

在特定文件之前添加一个或多个文件。

在捆绑包的开头添加文件可能不够精确。 before 指令可以用于在目标文件的 前面 添加给定的文件。它通过用一个3元组 ('before', <target>, <path>) 替换正常路径来声明。

'web.assets_common': [
    ('before', 'web/static/src/css/bootstrap_overridden.scss', 'my_addon/static/src/css/bootstrap_overridden.scss'),
],

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

'web.assets_common': [
    ('after', 'web/static/src/css/list_view.scss', 'my_addon/static/src/css/list_view.scss'),
],

include

使用嵌套包。

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:

'web.assets_common': [
    ('include', 'web._primary_variables'),
],

remove

删除一个或多个文件。

在某些情况下,您可能希望从捆绑包中删除一个或多个文件。这可以通过使用 remove 指令并指定一对 ('remove', <target>) 来完成:

'web.assets_common': [
    ('remove', 'web/static/src/js/boot.js'),
],

replace

用一个或多个文件替换资产文件。

假设一个资产不仅需要被移除,而且您还想在完全相同的位置插入新版本的该资产。这可以通过使用 replace 指令来完成,使用一个三元组 ('replace', <target>, <path>)

'web.assets_common': [
    ('replace', 'web/static/src/js/boot.js', 'my_addon/static/src/js/boot.js'),
],

加载顺序

资产加载的顺序有时非常关键,必须是确定性的,主要是为了样式表优先级和设置脚本。Odoo中的资产处理如下:

  1. 当调用资源包时(例如 t-call-assets="web.assets_common"),生成一个空的资源列表

  2. 所有与该捆绑包匹配的 ir.asset 类型的记录都会被获取并按序列号排序。然后,所有序列号严格小于16的记录都会被处理并应用于当前资产列表。

  3. 所有在其清单中声明了该捆绑包的资产的模块都将其资产操作应用于此列表。这是按照模块依赖的顺序进行的(例如, web 资产在 website 之前处理)。如果指令尝试添加已经存在于列表中的文件,则不会对该文件进行任何操作。换句话说,列表中只保留文件的第一次出现。

  4. 剩余的 ir.asset 记录(序列大于或等于16的记录)也将被处理并应用。

在清单中声明的资源可能需要按特定顺序加载,例如在加载 lib 文件夹时, jquery.js 必须在所有其他 jquery 脚本之前加载。一种解决方案是创建一个 ir.asset 记录,其序列较低或具有 ‘prepend’ 指令,但还有另一种更简单的方法。

由于资产列表中每个文件路径的唯一性是有保证的,因此您可以在包含它的通配符之前提到任何特定文件。因此,该文件将出现在所有包含在通配符中的其他文件之前。

'web.assets_common': [
    'my_addon/static/lib/jquery/jquery.js',
    'my_addon/static/lib/jquery/**/*',
],

注解

一个模块 b 移除/替换模块 a 中声明的资源将必须依赖于它。尝试操作尚未声明的资源将导致错误。

延迟加载

有时候动态加载文件和/或资源包是很有用的,例如只在需要时加载库。为此,Odoo框架提供了一些辅助函数,位于: @web/core/assets

await loadAssets({
    jsLibs: ["/web/static/lib/stacktracejs/stacktrace.js"],
});
loadAssets(assets)
参数
  • assets (Object()) – 描述应该加载的各种资源

返回

Promise<void>

加载由 assets 参数描述的资源。它是一个对象,可能包含以下键:

类型

描述

jsLibs

string[]

JavaScript文件的URL列表

cssLibs

string[]

CSS文件的URL列表

useAssets(assets)
参数
  • assets (Object()) – 描述应该加载的各种资源

这个钩子在组件需要在它们的 onWillStart 方法中加载一些资源时非常有用。它内部调用了 loadAssets

资产模型 (ir.asset)

在大多数情况下,清单中声明的资产将基本足够。但是为了更灵活,框架还支持在数据库中声明的动态资产。

这可以通过创建 ir.asset 记录来完成。这些记录将被处理,就像它们在模块清单中被发现一样,并且它们具有与其清单对应项相同的表现力。

class odoo.addons.base.models.ir_asset.IrAsset(env: api.Environment, ids: tuple[IdType, ...], prefetch_ids: Reversible[IdType])[源代码]

This model contributes to two things:

1. It provides a function returning a list of all file paths declared in a given list of addons (see _get_addon_paths);

2. It allows to create ‘ir.asset’ records to add additional directives to certain bundles.

name

资产记录的名称(用于识别目的)。

bundle

应用该资产的捆绑包。

directive (default= append)

此字段确定如何解释 path (如果需要,还包括 target )。以下是可用指令的列表以及它们所需的参数:

  • append: path

  • prepend: path

  • before: target, path

  • after: target, path

  • include: path (被解释为 bundle name)

  • remove: path (interpreted as a target asset to remove)

  • replace: target, path

path

一个定义以下内容之一的字符串:

  • 一个 相对路径,指向附加文件系统中的资源文件;

  • 一个 glob 模式,用于在插件文件系统中设置一组资源文件;

  • 一个指向附件或外部资产文件的 URL

  • 使用 include 指令时的 bundle 名称

target

目标文件,用于指定捆绑包中的位置。只能与指令 replacebeforeafter 一起使用。

active (default= True)

记录是否激活

sequence (default= 16)

Loading order of the asset records (ascending). A sequence lower than 16 means that the asset will be processed before the ones declared in the manifest.