I met the need to add ICONS to the menu in the oDOO development process, experienced friends should know that ODOO only supports the root level menu icon, through the CONFIGURATION of web_icon in XML icon can be added, but the secondary menu and the following is not supported, this development through part of the source code for transformation, Realized the two – level menu plus icon requirements.

The source code to explore

First we need to explore how odoo itself implements icon addition. Open F12 and you can see ICONS in binary formWe find ir.ui.menu source code (menu information is defined by this model) and the table corresponding to the database. The web_icon in the model saves the icon path: The module names and directories are separated by commas, and the web_icon_data field is the binary saved by the associated IR_attachment, Through the debug(the debug process is too long to be described in detail here, the key process of the front-end call is to call the load_MENUS method in ir.uI. menu to return the relevant menu information), I determined that these two fields are the core of the control icon display, but I did not want to read the display in binary form. I’m going to add the image display directly to the web_icon path frontLoad_menus returns the web_icon, web_icon_datas, and odoo retrieves the web_icon_datas ICONS. Even if this field is configured in the MENU XML, oDOO does not read the repository when the module is installed or upgraded by default. These two fields are false when the secondary menu is returned to the front end.)Since the front end contains these two fields, I can directly get the icon path saved by the web_icon field and add an image label to the front end to display the icon. As for how to save the icon path, I will talk about it later. We first verify the preliminary idea and manually find the menu record I want to add the icon in the database. Set their web_icon field to a correct path.

Cut into the topic

The key point now is to find the js of the specific rendered page. In the Web, there is a menu.js that is used to render the menu. Menu is inherited from widget

<t t-ESC ="second_level_menu.name"/> '<t t-ESC ="second_level_menu.name"/>Copy the code
<t t-foreach="first_level_menu.children" t-as="second_level_menu">
Copy the code

This line of code confirms that the data here is a child of menu_data in the for loop, so you can do something here. The idea here is to check if there is a web_icon field and then add the img tag

<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"/>Copy the code

Now upgrade the module to see if it has achieved the desired effect, sure enough, the scheme is correct! Here I would like to explain that the navigation menu of this project is changed from the top to the left, but it does not affect the icon, even the top can use this methodAfter verification, the scheme is feasible. Now we need to find a way to make the secondary menu save the web_icon path. The initial idea is to get the data store by reading the web_icon attribute in XML as the root level menu, so we need to add the logic of extracting web_icon to the parsing of the secondary menu in the source code. After some debugging, I found that this part would have a great influence when changing, so I changed it to add a custom setting in “Settings”, and the background logic was to find the corresponding IR_UI_menu record to set the web_icon field as the icon pathRes.config. Settings is inherited and three fields are added. Rewrite the create method to retrieve these three fields, check the corresponding ir_UI_menu record, and modify the web_icon

conclusion

The odoo framework has both the flexibility of its backend and the constraint of its front-end UI, and only through patient debugging can it achieve some personalized requirements.