odoo 网站使用 ajax请求 通过自定义小部件显示第三方数据

起因:Odoo的网站或后台,是公司成员花费最多时间的地方,在 odoo 网站的首页,动态显示第三方接口中的数据。


实现思路:Odoo 网页请求都是由 Python 库 werkzeug 来进行处理的,但是还没有学会这个模块的使用方法,于是通过 ajax 折中的先实现这个效果。

Odoo 自带完整的内容管理系统,通过 拖拽 ,终端用户可以在几分钟内做出一个静态页面。本文的思路就是用它的这个 拖拽 的功能,将数据做好放在 拖拽 的模块中,在用户 拖拽 前,实际上数据已经全部加载完成了,拖拽 出来的就是一个已经把数据渲染出来的代码块,一个 html 结构。


文章中使用的环境是 Odoo 13 + Postgres 12 + Docker,文章中的代码都依赖 website 模块,通过一个自定义的 “小部件” 实现这个小功能。

如果有不会搭建这个环境的,请看这篇文章:Docker 搭建 Odoo 13 本地环境

 

拖拽 小部件结构:

文章中示意图的尺寸是: 100x80 px

用 PS 或 Sketch 把图做好,同官方提供的示意图类似就行,Odoo 网站后台的图形界面,都是由一块一块的 “小部件” 组成,全部是拖拽的方法直接使用的。

编写小部件结构示意图

在 views 中添加 snippets.xml,snippets 就是可以自定义的拖拽插件。在这个 xml 文件中,需要做以下3件事情:

  • 配置 拖拽 小部件的预览图以及小部件名称
  • 编写 小部件的 html 结构
  • 配置 小部件的 Options 选项

 

小部件的预览图:

// t-thumbnail 预览图片地址
    // t-snippet 小组件结构
    <template id="news" name="news" inherit_id="website.snippets">
        <xpath expr="//div[@id='snippet_structure']/div[hasclass('o_panel_body')]" position="inside">
            <t t-snippet="theme_a.s_news" t-thumbnail="/theme_anviz/static/src/img/news.jpg" />
        </xpath>
    </template>
theme_a.s_news  
theme_a  当前插件的名称是 a
s_news   当前小部件的结构 ID
 

小部件代码结构:

// 小部件的 名称与id 缺一不可
<template id="s_news" name="News"></template>
 

小部件 Options 配置:

Options 可以配置的很多,背景颜色,多栏,自定义的 style等。
 
小部件的资源要依赖 web_editor ,所以在配置它时,需要调用 web_editor 的小组件资源包
<t t-call="web_editor.snippet_options"/>
web_editor.assets_editor和web_editor.summernote:这个资源包包含与网站编辑小组件选项及拖拽功能(网站构造器)相关的代码,它仅在用户对网站具有编辑权限时才进行加载。 
 
       <!-- COLOR | .s_news  -->
        <div data-js="colorpicker"
            data-selector=".s_news .row"
            data-target=".card"
            data-palette-title="Box Color">
            <we-collapse-area>
                <we-toggler><i class="fa fa-fw fa-eyedropper"/> Color</we-toggler>
                <we-collapse/>
            </we-collapse-area>
        </div>

        <!--  V-ALIGN -->
        <div id="row_valign_snippet_option" data-selector=".s_news" data-target=".row">
            <we-collapse-area>
                <we-toggler><i class="fa fa-fw fa-arrows-v"/> Alignment</we-toggler>
                <we-collapse>
                    <we-button data-select-class="align-items-start">Top</we-button>
                    <we-button data-select-class="align-items-center">Middle</we-button>
                    <we-button data-select-class="align-items-end">Bottom</we-button>
                    <we-divider/>
                    <we-button data-select-class="align-items-stretch">Equal height</we-button>
                </we-collapse>
            </we-collapse-area>
        </div>

需要注意下面两点,分别对应小部件结构中的 class ,拖拽动作是通过这两个属性去触发

  • data-selector  
  • data-target
     

加载小部件 css/js 资源文件

 本文中的小部件资源,均加载在网站的所有资源末尾中 web.assets_frontend,与 theme 资源一起加载。

    <template id="assets_frontend" name="anviz assets" inherit_id="web.assets_frontend">
        <xpath expr="link[last()]" position="after">
            <link rel="stylesheet" type="text/scss" href="/theme_anviz/static/src/css/swiper.min.css"/>
            <link rel="stylesheet" type="text/scss" href="/theme_anviz/static/src/scss/cur.scss"/>
            <link rel="stylesheet" type="text/scss" href="/theme_anviz/static/src/css/font.css"/>
        </xpath>
        <xpath expr="//script[last()]" position="after">
            <script type="text/javascript" src="/theme_anviz/static/src/js/get_data.js"/>
        </xpath>
    </template>

小常识,odoo 资源包分类:

  • web.assets_common:包含所有应用的基本工具文件,如 jquery 等,此类资源用于网站、后台、销售等各类模块
  • web.assets_backend:odoo 后台使用,包含所有 Web 客户端、Views等管理器的各类模块
  • web_editor.assets_editor和web_editor.summernote:包含网站小部件拖拽功能的资源代码
  • web.assets_frontend:包含所有网站相关资源
  • web.report_assets_common: 报表资源

 


 

小部件功能涉及四个文件,全部代码如下:

  1. static 中的 css&js
  2. views 中的 assets.xml & snippets.xml

 

odoo模块系统通过在全局odoo对象上定义函数define来工作,odoo.define() 会默认自动执行,同 $(funciton(){...}) 一样的

odoo.define( moduleName, dependencies, function( require, factory ){ ... }) 有三个参数

moduleName 是必须的唯一的字符串,习惯写法:addons 中的插件名称 . js 名称 : theme_a.get_data.js

dependencies 是可选的,是 js 模块的依赖项

最后一个是返回函数

odoo.define('theme_a.get_news_data.js', function(require, factory) {
    'use strict';

    $.ajax({
        url: 'https://www.xxx.com/news/index/json',
        type: "GET",
        crossDomain: true,
        datatype: 'application/json',
        success: function(data){
            console.log(data)
            var list = data.data.DATA;

            for(var i = 0; i < list.length; i++){
                var n = list[i];
                var newDate = n.public_time;
                var newTitle = n.title;
                var newUrl = n.url;
                var newDes = n.description;
                var newPic = n.thumb;

                var newsList = $('#wrap').find('.s_news .list');
                var itemCard = $(`<div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 pt16 pb16"><div class="card"></div></div>`);
                var itemCardBody = 
                    $(`<div class="card-body">
                        <div class="card-text">${newDate}</div>
                        <h3 class="card-title">${newTitle}</h3>
                        <p class="card-text">${newDes}</p>
                        <a href="${newUrl}" class="news-learn-more anviz-btn anviz-primary-btn">Learn More</a>
                    </div>`);
                var itemImg = $(`<img class="card-img-top" src="${newPic}" />`);
                itemCard.append(itemImg)
                itemCard.append(itemCardBody)
                newsList.append(itemCard);
            }
        },
        error:function(err){
            console.log(err)
        }
    });    
});
//assets.xml

<?xml version='1.0' encoding='utf-8'?>
<odoo>
    <template id="assets_frontend" name="anviz assets" inherit_id="web.assets_frontend">
        <xpath expr="link[last()]" position="after">
            <link rel="stylesheet" type="text/scss" href="/theme_anviz/static/src/css/swiper.min.css"/>
            <link rel="stylesheet" type="text/scss" href="/theme_anviz/static/src/scss/cur.scss"/>
            <link rel="stylesheet" type="text/scss" href="/theme_anviz/static/src/css/font.css"/>
        </xpath>
        <xpath expr="//script[last()]" position="after">
            <script type="text/javascript" src="/theme_anviz/static/src/js/get_data.js"/>
        </xpath>
    </template>
</odoo>
//snippets.xml

<?xml version='1.0' encoding='utf-8'?>
<odoo>
    <template id="news" name="news" inherit_id="website.snippets">
        <xpath expr="//div[@id='snippet_structure']/div[hasclass('o_panel_body')]" position="inside">
            <t t-snippet="theme_anviz.s_news" t-thumbnail="/theme_anviz/static/src/img/news.jpg" />
        </xpath>
    </template>

    <template id="s_news" name="News">
        <section class="s_news bg-200 pt100 pb32">
            <div class="container">
                <div class="list row">
                    <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12 pt16 pb16">
                        <div class="card">
                            <img class="card-img-top" src="" />
                            <div class="card-body">
                                <div class="card-text"></div>
                                <h3 class="card-title"></h3>
                                <p class="card-text"></p>
                                <a href="" class="news-learn-more anviz-btn anviz-primary-btn" target="_blank">Learn More</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </template>
    <template id="snippet_options">
        <t t-call="web_editor.snippet_options"/>

        <!-- COLOR | .s_news  -->
        <div data-js="colorpicker"
            data-selector=".s_news .row"
            data-target=".card"
            data-palette-title="Box Color">
            <we-collapse-area>
                <we-toggler><i class="fa fa-fw fa-eyedropper"/> Color</we-toggler>
                <we-collapse/>
            </we-collapse-area>
        </div>

        <!--  V-ALIGN -->
        <div id="row_valign_snippet_option" data-selector=".s_news" data-target=".row">
            <we-collapse-area>
                <we-toggler><i class="fa fa-fw fa-arrows-v"/> Alignment</we-toggler>
                <we-collapse>
                    <we-button data-select-class="align-items-start">Top</we-button>
                    <we-button data-select-class="align-items-center">Middle</we-button>
                    <we-button data-select-class="align-items-end">Bottom</we-button>
                    <we-divider/>
                    <we-button data-select-class="align-items-stretch">Equal height</we-button>
                </we-collapse>
            </we-collapse-area>
        </div>

        <!-- Accordion -->
        <div data-js="collapse"
            data-selector='.s_news > .card'
            data-drop-in='.accordion:has(> .card)'/>

        <div data-js="layout_column"
        data-selector="section"
        data-target="> * > .row:not(.s_nb_column_fixed)">
        <we-collapse-area>
            <we-toggler><i class="fa fa-fw fa-columns"/> Number of columns</we-toggler>
            <we-collapse data-no-preview="true">
                <we-button data-select-count="1">1</we-button>
                <we-button data-select-count="2">2</we-button>
                <we-button data-select-count="3">3</we-button>
                <we-button data-select-count="4">4</we-button>
                <we-button data-select-count="5">5</we-button>
                <we-button data-select-count="6">6</we-button>
            </we-collapse>
        </we-collapse-area>
    </div>
    </template>
</odoo>

用作记录。

posted @ 2023-01-31 16:28  礼拜16  阅读(224)  评论(0编辑  收藏  举报