在 Odoo 中管理资源比其他一些平台要复杂一些。这种复杂性源于需要支持 Odoo 各种应用场景的不同需求,例如网页客户端、销售点(Point of Sale,POS)、网站和移动应用等。此外,一些资源体积较大但很少需要使用,Odoo 允许按需加载这些资源,这种方式被称为“懒加载(lazy loading)”。
资源的作用和使用场景
在 Odoo 中,资源是指应用程序运行所需的静态文件,包括 JavaScript、CSS、SCSS 和 XML 文件。管理这些资源的目的是确保应用程序在客户端的表现流畅,并满足不同模块的需求。资源的作用主要有以下几点:
- 提高用户体验:通过管理和优化 JavaScript 和 CSS 文件,Odoo 能够提升页面加载速度,使得用户界面的交互更加流畅和响应迅速。
- 模块化和可扩展性:Odoo 的资源系统使开发人员能够将资源按模块进行分组和管理,便于模块的扩展和维护。例如,不同的应用模块(如销售点系统、网页前端和后台)可以各自拥有独立的资源包,满足其特定的需求。
- 按需加载优化:Odoo 允许按需加载资源,例如当用户访问特定功能时再加载相关的 JavaScript 或 CSS 文件,从而减少不必要的资源消耗,提高整体性能。
- 灵活的资源控制:通过使用
ir.asset等动态资源配置方式,开发者可以根据业务需求灵活地调整资源的加载顺序和配置,减少重复加载,确保资源的唯一性。
使用场景
- 网页客户端(Backend) :例如在后台管理界面中,Odoo 使用特定的 JavaScript 和 CSS 来实现复杂的操作管理界面,包括表单、数据视图、报表等功能。
- 网站模块(Frontend) :网站模块中包含前端展示用的 JavaScript 和样式文件,用于实现如电子商务、博客、门户网站等功能的交互效果和样式。
- 销售点(POS) :POS 系统则有自己专属的资源包,确保销售点操作界面的快速响应和无缝使用。
- 测试环境:例如
web.qunit_suite_tests资源包包含 JavaScript 测试框架,用于 Odoo 的单元测试和功能测试,确保系统的稳定性和可靠性。
资源类型
Odoo 管理三种主要类型的资源:
- 代码资源(JavaScript 文件) :这些 JavaScript 文件会被转换为 Odoo 模块,随后进行压缩(如果不是在
debug=assets模式下)并合并为一个文件,以提高性能。最终文件通过 HTML<head>部分的<script>标签进行加载。 - 样式资源(CSS/SCSS 文件) :样式资源可以是 CSS 或 SCSS 文件。SCSS 文件会被编译成 CSS,然后在需要时进行压缩。最终结果被保存并通过 HTML 的
<link>标签引入。 - 模板资源(XML 文件) :XML 模板用于定义页面布局和组件,这些模板通过
/web/webclient/qweb/控制器动态加载。
资源包(Bundles)
在 Odoo 中,资源被分组为资源包(bundles) ,本质上是文件路径的列表。资源包在每个模块的 __manifest__.py 文件中声明,位于 assets 键下。资源包可以包含 JavaScript、CSS、SCSS 和 XML 文件。
以下是定义模块中资源包的示例:
'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',
],
}
常用资源包
web.assets_common:包含网站、销售点等模块共用的资源。这些资源包括 JavaScript 库,如boot.js。web.assets_backend:包含特定于网页客户端的代码,例如动作管理器和视图。web.assets_frontend:包含 Odoo 面向公众部分的资源,如电子商务、门户网站、博客等。web.qunit_suite_tests:用于运行测试的 JavaScript 资源。
资源包的操作
添加资源
- 追加(Append) :将文件添加到资源包末尾。
'web.assets_common': [
'my_addon/static/src/js/**/*',
]
默认情况下,添加文件会将其附加到资源包的末尾。
- 前置(Prepend) :将文件添加到资源包的开头。
'web.assets_common': [
('prepend', 'my_addon/static/src/css/bootstrap_overridden.scss'),
]
这在需要确保某些样式或脚本具有优先级时非常有用。
相对其他文件插入
- 之前(Before) :在资源包中的特定文件之前添加一个或多个文件。
'web.assets_common': [
('before', 'web/static/src/css/bootstrap_overridden.scss', 'my_addon/static/src/css/bootstrap_overridden.scss'),
]
- 之后(After) :在资源包中的特定文件之后添加一个或多个文件。
'web.assets_common': [
('after', 'web/static/src/css/list_view.scss', 'my_addon/static/src/css/list_view.scss'),
]
移除或替换资源
- 移除(Remove) :从资源包中移除特定文件。
'web.assets_common': [
('remove', 'web/static/src/js/boot.js'),
]
- 替换(Replace) :用新文件替换现有资源。
'web.assets_common': [
('replace', 'web/static/src/js/boot.js', 'my_addon/static/src/js/boot.js'),
]
包含嵌套资源包
- 包含(Include) :允许在另一个资源包中使用较小的资源包。
'web.assets_common': [
('include', 'web._primary_variables'),
]
资源加载顺序
资源的加载顺序对于保持行为的可预测性至关重要。以下是 Odoo 处理资源加载顺序的总结:
- 当调用一个资源包时(例如
t-call-assets="web.assets_common"),Odoo 从一个空的资源列表开始。 - 然后加载所有序号小于 16 的
ir.asset记录中定义的资源。 - Odoo 会应用模块清单中声明的资源,同时遵循模块之间的依赖关系。
- 最后,处理所有剩余的
ir.asset记录。
如果某个文件需要在其他被通配符匹配的文件之前加载,只需在清单中显式列出该文件即可:
'web.assets_common': [
'my_addon/static/lib/jquery/jquery.js',
'my_addon/static/lib/jquery/**/*',
]
这种方式确保 jquery.js 在同一目录中的其他 JavaScript 文件之前加载。
懒加载(Lazy Loading)
有时候,某些资源只在特定情况下才需要。Odoo 提供了懒加载机制,允许按需加载这些文件。可以使用 loadAssets 函数动态加载这些文件:
await loadAssets({
jsLibs: ["/web/static/lib/stacktracejs/stacktrace.js"],
});
使用 ir.asset 进行动态资源管理
对于更复杂的场景,Odoo 允许在数据库中动态定义资源,通过 ir.asset 记录来实现。这些记录与清单中定义的资源包具有相同的灵活性,支持如 append、prepend、replace 等操作。以下是一个示例,展示如何使用 ir.asset 定义和管理资源:
<record id="website.user_custom_rules_scss" model="ir.asset">
<field name="name">User custom rules SCSS</field>
<field name="bundle">web.assets_frontend</field>
<field name="path">website/static/src/scss/user_custom_rules.scss</field>
<field name="sequence" eval="99"/>
</record>
在上述代码中,我们定义了一个 ir.asset 记录,用于动态地将自定义 SCSS 文件添加到资源包中,并设置了加载顺序。
ir.asset 模型特别适用于不直接修改模块文件的情况下需要调整资源的场景。例如,你可能希望替换现有文件或根据运行时条件附加新的资源。
示例 ir.asset 字段
- name:资源记录的名称,用于标识。
- bundle:指定资源所属的资源包。
- directive:指定操作类型,例如
append或replace。 - path:指向资源文件的路径。
- target:在特定操作中定义资源包中的位置。
- sequence:确定资源记录的加载顺序,序号较小的优先处理。
结论
在 Odoo 中管理资源需要理解不同类型的资源,它们如何被分组到资源包中,以及如何使用各种操作来修改这些资源包。通过有效利用这些功能,你可以微调资源的加载顺序、资源包的组成,甚至根据需要动态地包含或排除资源。这为你提供了极大的灵活性和控制力,确保 Odoo 应用程序的性能和用户体验始终处于最佳状态。