
01
Odoo前端架构概述
Odoo的前端架构主要设计针对三种用户场景:
web client
私有 Web 应用, 用来查看与编辑 业务数据, 也就是通俗说的 中后台. 其属于 SPA 前端渲染 web 框架
website
Odoo 的 公有 Web 应用, 它可以运行 非注册用户 浏览, 购物 等等, 可以理解成 CMS. 也即是 传统的 网站. 它同时支持 后端和前端渲染, 前端渲染并非是 SPA.
point of sale
针对特定的 商业场景暂不讨论.
那么如果我们想基于 Odoo 的自定义业务模块来定制一个 CMS 网站,前后端 UI 框架就需要建立在webclient与website之上.

CMS 网站
Odoo website 有着Odoo独有的前端网站开发体系.
Website Designer (Builder)
Odoo 希望用户能通过 无代码/低代码 的方式建设一个网站, 它提供了设计器和丰富的静态区块模版, 例如走马灯, Cover, 广告, 图片, 文字, 视频, 图表等等.搭建一个静态网站只需要拖拉拽就能搞定.

Snippets
上面提到的 设计器 操作的目标就是 区块, 或者换句话说 被拖拽到页面上的内容, 就叫区块. 区块是组成页面的基本单元. 基于 Odoo 前端架构 我们能很轻松的创建一个自定义区块, 然后这些区块就和默认的区块一样可以被拖放到任何一个页面.
你很容易想到这就意味着每一个区块都是自治的.

CMS 业务模型管理中后台
webclient
除了网站之外中后台开发也涉及到前端开发. 一般而言, Odoo 后台的前端架构 主要是 基于三类定制化开发.
Views
视图可以说是 Odoo 前端架构里面最为复杂的部分, 默认的视图已经完全能满足大部分 业务模型的 渲染与交互需求. 但是 定制化一个自定义视图依然是可行的.
Field Widget
模型由字段组成, 如果说一个模型 所渲染的 UI 对应 一个 视图, 那么 一个模型字段 所渲染的 UI 则对应一个 Field Widget.
自定义 Widget 远远比 自定义视图 更常见.
Client Actions
客户动作定制化并不常见, 我们暂不讨论.

02
前端网站HTML/CSS架构
因为我们采用website 架构来进行研发, 这有别于传统网站开发, 其静态还原的工作, 不适合在Odoo网站中开发, 所以我们将其放在独立静态网站工程中进行研发. (因为最小研发单位不再是 网页 而是区块, 我们需要先开发好区块的静态部分 然后再 迁移到 Odoo 工程中调试 动态的部分)

parcel
我们选择parcel作为静态网站还原研发的构建工具. 它相对于webpack更为轻量级
proxy
代理服务器引入方便做Mock数据
bootstrap, jquery 与 keen2 或者 基于 bootstrap 的 定制主题
odoo 前端架构的两个核心依赖是bootstrap 4.x与jquery 3.x. 为了避免造轮子, 我们可以选择bootstrap主题 例如keen2的来研发前端网站. 但是这里需要仔细考虑架构上的设计冲突. odoo 与 keen2 自身都对bootstrap 4.x做了定制化,所以我们选择用keen2的定制化bootstrap覆盖odoo定制化bootstrap. 建议先考虑样式覆盖, 相对而言这样的冲突更好解决. 至于主题自定义组件及其依赖JS建议选择性引入 逐步消除冲突.
html/css 架构
区块是模块化的, 所以即便是静态还原, 我们也需要引入模块化设计思想, 避免重复的编码. 我们选择了主流的SMACSS+OOCSS +BEM的混合方案来作为静态还原的架构基础. 限于篇幅我们不做展开, 会在单独的主题中分享.
sass
静态还原的核心是 HTML 与 CSS, 传统的 CSS 并不是模块化的, 而我们目标区块是模块化的, 所以引入 CSS 架构以及对应的模块化工具显得尤为必要. 我们选择 主流的SASS来编写模块化的CSS.
live style guide
在线样式指南并非必须, 通过实践反馈, 严格避免在 Odoo 工程内修改样式, 对于代码的后期方便维护起决定性的作用.
这种最佳实践方式让还原开发与功能开发分别在 2 个工程中独立进行. 做到了静态还原和功能开发分离. 这个设计思想源自单一职责原则, 很容易想象如果直接在 Odoo 工程中编写 CSS 无论是开发效率还是开发质量都会降低.

03
前端网站JS架构
前端网站的架构 完全基于Odoo JS框架进行研发. 涉及到Odoo的资源管理, 模块系统, 类系统, Widgets, QWeb 模版, 事件系统, 注册系统, 服务调用, 通知系统, 网站会话等等.
在这些Odoo JS框架的基础之上 我们设计了一个小型的JS框架来实现前端网站的主要功能.

区块
区块的职责是获取业务模型数据以及渲染, 每个区块的开发人员只需要关注这两件事件的实现.
区块是 网站 核心单位, 每个区块都是自治的. 这样的设计建立在 Odoo 网站开发的Snippet基础之上, 但是区块的拆分依然和该网站灵活的权限控制密不可分, 换句话来说权限控制的需求决定了以区块作为一个个 研发单位. 而不是页面.
区块的基类
区块的权限控制 对于每个区块来说都是一致的, 除此之外, 数据获取, 数据标准化, XHR 请求的逻辑我们都放在 每个区块的 父类来处理, 避免代码的重复.
权限模块
权限模块负责根据当前登录用户获取权限配置信息.
控制区块的可见性以及是否能够发送请求获取数据.
数据处理
依据权限过滤数据通过过滤的字段来控制字段级别的权限.
针对 UI 的要求对数据进行格式化预处理.
数据获取模块
包装请求与数据处理的业务流程逻辑
XHR 请求
封装底层RESTFUL或者RPC风格的API请求
静态模版渲染
当模版是后端渲染, 统一来处理该类型区块的渲染
前端组件库
第三方组件库与自定义组件的使用不可避免, 以下列举两个典型案例
三方 报表与可视化组件
基于常见的数据可视化组件库,例如alig2或者g6组件进行二次开发
自定义表格
基于JQ Plugin标准模版开发 JQ 组件
基于bootgrid二次封装的自定义 Jquery组件
04
管理JS架构
参考上文中的 Odoo 前端架构.
Views
Field Widgets
这里我们展现一个典型自定义字段 Widget 的场景, 可以看到字段类型列在编辑状态下渲染了一个较为复杂的组件

Client Actions
05
总结
本文从High Level的角度概述了基于Odoo进行CMS网站开发涉及到的前端技术框架, 和我们采用的自定义架构方案.得益于Odoo本身website与 webclient架构的完整性, 我们能够快速打造一个高度自定义的网站.
参考文档:
[Odoo Javascript Reference]
https://www.odoo.com/documentation/14.0/developer/reference/javascript/javascript_reference.html
[Odoo Website Theme]
https://www.odoo.com/documentation/14.0/developer/howtos/themes.html
[Building a Website with Odoo]
https://www.odoo.com/documentation/14.0/developer/howtos/website.html
[Building a Backend Module with Odoo]
https://www.odoo.com/documentation/14.0/developer/howtos/backend.html




