likes
comments
collection
share

odoo二级导航加图标

作者站长头像
站长
· 阅读数 1

本人在odoo开发过程遇到了需要对菜单加图标的需求,有过开发经验的朋友应该都知道odoo仅支持对root级菜单加图标,通过在xml里配置web_icon即可实现图标的添加,但二级菜单及以下是不支持的,此次开发中通过对部分源码进行改造,实现了二级菜单加图标的需求。 odoo二级导航加图标

源码探究

首先我们得探究odoo自身是怎样实现图标添加的,打开F12可以看到图标是二进制形式 odoo二级导航加图标 我们再找到ir.ui.menu源码(菜单相关信息由此模型定义)及数据库对应的表,模型中有web_icon保存的是图标路径:模块名加目录的形式用逗号隔开,web_icon_data字段是关联的ir_attachment保存的二进制文件,通过debug(debug过程太冗长这里不作详细描述,前端调用的关键流程是调用了ir.ui.menu中的load_menus方法返回菜单相关信息)确定了这两个字段就是控制图标显示的核心,但我并不想用二进制形式读取显示,我打算直接通过web_icon的路径前端加入image显示 odoo二级导航加图标 debug发现web_client.js里load_menus调用的返回对象中包含web_icon,web_icon_datas字段,odoo获取web_icon_datas显示图标(仅限root级,二级及以下菜单即使在menu的xml里配置了这个字段,odoo在模块安装或升级时默认是不会读取存库的,二级菜单在返回给前端时这两个字段为false) odoo二级导航加图标 既然前端包含这两个字段,那我就可以直接拿到web_icon字段保存的图标路径在前端加入一个image标签就可以显示图标了,至于怎样保存图标的路径,后面再说,我们先验证初步想法,先手动在数据库里找到我想要加图标的菜单记录,将他们的web_icon字段设一个正确路径。 odoo二级导航加图标 odoo二级导航加图标

切入主题

现在的关键点就是要找到具体渲染页面的js在web里有个menu.js主要用于渲染菜单,menu继承至widget,在34行通过debug确定odoo用qweb传入了上下文menu_data包含菜单的各种信息,进行渲染odoo二级导航加图标

通过此线索再找到了Menu.sections模板,其中有个li包裹了‘<t t-esc="second_level_menu.name"/>’
<t t-foreach="first_level_menu.children" t-as="second_level_menu">

通过此行代码可以确定这里的数据就是for循环menu_data的子项,那在这里就可以搞事情了,思路是在这里判断是否包含web_icon字段有的话就加入img标签

<img t-if="second_level_menu.web_icon != false"  t-att-src="second_level_menu.web_icon" style="margin-right:8px" width="24" height="24"/>

现在升级下模块看看是否达到了想要的效果,果然方案是正确的!这里要说明一下本项目导航菜单之前由顶部改为了左侧,但不影响加图标,即使是顶部一样可以使用此方法 odoo二级导航加图标 经过验证,该方案可行那现在就要想办法让二级菜单保存web_icon路径,最初的想法是和root级菜单一样通过读xml里的web_icon属性拿到数据存库,那这样就需要对源码中处理二级菜单的解析加入提取web_icon的逻辑,又是经过一番debug发现,这部分改起来影响会很大,所以我改为了通过在“设置”里加入一项自定义设置,后台逻辑是找到对应的ir_ui_menu记录将web_icon字段设置为图标路径 odoo二级导航加图标 这里继承了res.config.settings并加入了三个字段,重写create方法获取这三个字段查到对应的ir_ui_menu记录并修改web_icon,至此大功告成 odoo二级导航加图标

结语

odoo框架既有他后台的灵活性优点也有前端ui约束性的缺点,只有通过耐心的debug了解其原理才能实现一些个性化的需求。