资产

在 Odoo 中管理资产并不像在其他一些应用程序中那样简单。原因之一是我们面临着多种情况,需要部分资产,但不是全部资产。例如,网络客户端、销售点应用程序、网站甚至移动应用程序的需求都是不同的。此外,某些资产可能很大,但很少需要:在这种情况下,我们可能希望它们是 loaded lazily (on demand)

资产类型

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

代码

Odoo 支持 three different kinds of javascript files。然后处理所有这些文件(原生 JS 模块转换为 odoo 模块),然后缩小(如果不在 debug=assets mode 中)并连接。然后结果将保存为文件附件。这些文件附件通常通过页面 <head> 部分中的 <script> 标记加载(作为静态文件)。

风格

样式可以使用 cssscss 来完成。与 javascript 文件一样,这些文件会被处理(scss 文件被转换为 css),然后缩小(再次,如果不在 debug=assets mode 中)并连接。然后结果将保存为文件附件。然后,它们通常通过页面 <head> 部分中的 <link> 标记加载(作为静态文件)。

模板

模板(静态 xml 文件)以不同的方式处理:只需在需要时从文件系统中读取它们,然后将其连接起来。

每当浏览器加载 odoo 时,它都会调用 /web/webclient/qweb/ 控制器来获取 templates

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

捆绑包

Odoo 资产按*捆绑包*分组。每个包(特定类型的*文件路径列表*:xmljscssscss)都列在 module manifest 中。可以使用 glob 语法声明文件,这意味着您可以使用一行声明多个资源文件。

这些包在每个模块的 __manifest__.py 中定义,并具有包含字典的专用 assets 键。字典将包名称(键)映射到它们包含的文件列表(值)。它看起来像这样:

'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.assets_unit_tests': [
        'web/static/src/js/webclient.test.js',
    ],
},

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

  • web.assets_common:此捆绑包包含网络客户端、网站和销售点常见的大多数资产。这应该包含 odoo 框架的较低级别构建块。请注意,它包含 boot.js 文件,该文件定义了 odoo 模块系统。

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

  • web.assets_frontend:此捆绑包涉及公共网站的所有特定内容:电子商务、门户网站、论坛、博客……

  • web.assets_unit_tests:所有 javascript 单元测试代码(测试、帮助程序、模拟)

运营

通常,处理资源很简单:您只需将一些新文件添加到经常使用的包中,例如 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

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

before 相同,匹配文件附加在目标文件的*后面*。它是通过用 3 元素元组 ('after', <target>, <path>) 替换正常路径来声明的。

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

include

使用嵌套捆绑包。

include 指令是一种在其他捆绑包中使用捆绑包以最小化清单大小的方法。在 Odoo 中,我们使用子包(按照惯例以下划线为前缀)来批处理多个其他包中使用的文件。然后,您可以将子包指定为一对 ('include', <bundle>) ,如下所示:

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

remove

删除一个或多个文件。

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

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

replace

将资源文件替换为一个或多个文件。

假设某个资产不仅需要删除,而且您还希望在同一位置插入该资产的新版本。这可以通过 replace 指令,使用 3 元素元组 ('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 脚本之前加载 jquery.js 。一种解决方案是创建具有较低序列或“前置”指令的 ir.asset 记录,但还有另一种更简单的方法。

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

'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()) – 应加载的各种资产的描述

返回

承诺<无效>

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

钥匙

类型

描述

jsLibs

string[]

javascript 文件的 url 列表

cssLibs

string[]

css 文件的 url 列表

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

当组件需要在其 onWillStart 方法中加载某些资源时,此挂钩非常有用。它在内部调用 loadAssets

资产模型 (ir.asset)

在大多数情况下,清单中申报的资产基本上就足够了。然而,为了获得更大的灵活性,该框架还支持在数据库中声明的动态资产。

这是通过创建 ir.asset 记录来完成的。这些将被处理,就像它们在模块清单中找到一样,并且它们提供与清单对应项相同的表达能力。

name

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

bundle

将在其中应用资产的捆绑包。

directive`(默认= `append

该字段确定如何解释 path (和 target 如果需要)。以下是可用指令及其所需参数的列表:

  • 附加path

  • 前置path

  • 之前targetpath

  • 之后targetpath

  • 包括`path`(解释为**捆绑包名称**)

  • 删除`path`(解释为要删除的**目标资产**)

  • 替换targetpath

path

定义以下其中一项的字符串:

  • 插件文件系统中资源文件的**相对路径**;

  • 插件文件系统中一组资源文件的 glob 模式

  • 附件或外部资产文件的 URL

  • 使用 include 指令时的 捆绑包名称

target

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

active`(默认= `True

记录是否活跃

sequence`(默认= `16

资产记录的加载顺序(升序)。低于 16 的序列意味着资产将在清单中声明的​​资产“之前”进行处理。

其他资料

请注意,“ir.asset”用例主要用于与网站相关的应用程序,因为它允许条件资产(例如,当启用样式选项时)。

在这种情况下,在 XML 中定义记录时使用 <asset id="..."> syntax should be preferred over the <record id="..." model="ir.asset"> 语法。

请参阅 asset,尤其是关于“active”值。