在 Odoo 中添加自定義頁面

前些天羣裏的小夥伴問了些關於在 Odoo 管理後臺自定義頁面和 Widget 的問題,那我就來寫一篇簡短的內容,教你們如何建立自定義頁面並引用第三方庫。若是你們有看我以前寫的基礎教程的話,應該知道咱們從一開始就是用的是 Odoo11 吧,從今天開始,咱們的教程全都將基於 Odoo12 進行編寫,因此在開始前,請確保你如今使用的是 Odoo12,或者跟隨官方的安裝指南安裝好環境再開始今天的內容。javascript

建立模塊

話很少說,先用 scaffold 命令建立一個新的模塊 custom_page,結構以下:html

myaddons
└── custom_page
    ├── __init__.py
    ├── __manifest__.py
    ├── controllers
    ├── demo
    ├── models
    ├── security
    ├── static
    └── views

我將會經過使用 wired-elements 這個 Web Components 組件庫建立一個簡單的自定義頁面,從而演示如何引入並使用第三方庫。因此咱們先準備好相關庫,先下載好這個庫,而後將它放到 static 目錄下:java

static
└── lib
   └── wired-elements
      └── wired-elements.bundled.min.js

以上的目錄層級結構是約定俗成的,第三方 JS 庫推薦都放在 static/lib 下。git

建立頁面

接下來是建立自定義頁面,一樣的在 static 下建立:github

static
└── src
   └── xml
      └── base.xml

自定義的頁面、JS 和 CSS 等資源文件,都按約定放置在 static/src 下,下面是自定義頁面 base.xml 文件的內容:web

<?xml version="1.0" encoding="UTF-8"?>
    <templates id="template" xml:space="preserve">
    
        <t t-name="DemoPage">
            <div class="container-fluid py-2 o_web_settings_dashboard">
                <div class="form-row">
                    <div class="col-12 col-lg-6 o_web_settings_dashboard_col">
                        <wired-card elevation="3">
                            <div class="mt8">
                                <wired-input placeholder="Enter name"></wired-input>
                            </div>
                            <div>
                                <wired-radio-group selected="two">
                                    <wired-radio name="one" text="Radio One"></wired-radio>
                                    <wired-radio name="two" text="Radio Two"></wired-radio>
                                    <wired-radio name="three" text="Radio Three"></wired-radio>
                                </wired-radio-group>
                            </div>
                            <div class="mt8 mr8 mb8 text-right">
                                <wired-button>Cancel</wired-button>
                                <wired-button elevation="3" class="demo-submit">Submit</wired-button>
                            </div>
                        </wired-card>
                    </div>
                </div>
            </div>
        </t>
    
    </templates>

頁面中使用到了 wired-elements 的組件,具體使用方式請參考官方文檔。上面的定義中,咱們看到有一個屬性 t-name,這個是頁面的名稱,可在 JS 中調用,這裏暫不展開說明。json

定義動做

自定義頁面其實是一個 client action,也就是客戶端動做,經過對 AbstractAction 這個抽象類進行擴展,從而指定自定義頁面的模板和頁面的事件等,下面的代碼定義了一個最簡單的客戶端動做,它包含了一個點擊事件:運維

odoo.define('custom_page.demo', function (require) {
    "use strict";
    
    var AbstractAction = require('web.AbstractAction');
    var core = require('web.core');
    
    var CustomPageDemo = AbstractAction.extend({
        template: 'DemoPage',
        events: { 'click .demo-submit': '_onSubmitClick' },
    
        _onSubmitClick: function (e) {
            e.stopPropagation();
            alert('Submit clicked!');
        }
    });
    
    core.action_registry.add('custom_page.demo', CustomPageDemo);
    
    return CustomPageDemo;
    
    });

上面這段代碼的核心部分在 AbstractAction.extend(...) 中,其中 template 指定了自定義頁面的模板名稱,也就是咱們前面所說的 t-name 這個屬性,而 events 則定義了頁面的一些事件,如該例中,定義的是當點擊(click)帶有類 .demo-submit 的元素時執行 _onSubmitClick 這個方法。ui

須要注意的是,咱們須要經過 core.action_registry.add() 這個方法對動做進行註冊,第一個參數表示註冊的動做名(tag),第二個參數是要註冊的動做對象。spa

建立菜單

既然自定義的頁面是一個動做,那麼咱們就須要建立菜單和它進行關聯,在 views/views.xml 定義菜單:

<odoo>
        <data>
            <record id="action_custom_page" model="ir.actions.client">
                <field name="name">Custom Page</field>
                <field name="tag">custom_page.demo</field>
            </record>
    
            <menuitem
                    id="menu_root_custom_page"
                    name="Custom Page"
                    action="action_custom_page"
                    groups="base.group_user"
                    sequence="1"/>
        </data>
    </odoo>

加載資源

和普通頁面同樣,頁面中所引用的 JS 或者 CSS 等資源文件,都須要在頁面上引入才能使用,在 Odoo 中也不例外,不過有一點不一樣的是,Odoo 中有專門的集中引入資源文件的地方,這樣作是爲了將資源進行打包壓縮,以減小請求的包體大小。

通常狀況下都是在 views/templates.xml 中繼承 web.ssets_backend 後在其末尾添加相關資源路徑:

<?xml version="1.0" encoding="utf-8"?>
    <odoo>
        <data>
            <template id="assets_backend" name="custom page assets" inherit_id="web.assets_backend">
                <xpath expr="//script[last()]" position="after">
                    <script type="text/javascript" src="/custom_page/static/lib/wired-elements/wired-elements.bundled.min.js"></script>
                    <script type="text/javascript" src="/custom_page/static/src/js/demo.js"></script>
                </xpath>
            </template>
        </data>
    </odoo>

除了 JS 資源須要引入外,咱們編寫的頁面模板也許要引入,打開 __manifest__.py 並在底部添加咱們的自定義頁面文件:

'qweb': ["static/src/xml/base.xml"]

OK! 大功告成,一個最簡單的自定義頁面已經完成了,安裝模塊而後運行看看效果吧。

開發者模式

很不幸的是,打開以後好像只有幾個小點在頁面,而後並無什麼東西了。先不慌,咱們先打開設置頁面,而後在頁面最右側那一列的底部,能夠看到兩個連接,分別是『激活開發者模式』和『激活開發者模式 (帶 assets)』,咱們點一下第二個帶 assets 的連接,而後再次訪問咱們的自定義頁面,結果如何?

Custom Page

那兩個連接顧名思義,就是進入開發者模式,其中帶 assets 的開發者模式會跳過執行資源打包的動做,在打開這個模式前,咱們看到頁面上的組件擠成一團了,是由於資源打包後致使 wired-elements 的部分屬性沒法找到。

注:以上操做只是爲了演示說明相關功能,在生產環境中,強烈不建議任何非開發或運維人員進入開發模式進行操做。

源碼都在倉庫 Odoo-Tutorial-Demo 中,請先本身動手實操,遇到問題再下載源碼安裝查看,若是有其餘難題能夠提出來,我會抽空解答的~

相關文章
相關標籤/搜索