這裏說的動態網頁,是指頁面上的數據來自後臺。比如:某企業會在網站上發佈公告或企業新聞。在頁面上一般會創建最新公告或者最新動態的選項卡。這裏就拿最新公告來說,在最新公告的選項卡里,可能會顯示5條最新的公告,這些公告由後臺編輯發佈。每當用戶進入頁面,看到的永遠是最新的5條公告。
那麼,如何實現呢?
一是創建一個網頁頁面(website.page)記錄,這種方式在安裝所在的模塊時,會自動添加到導航欄中,在管理員的編輯模式下可以從導航欄取消,或者重新放置到導航欄。
二是創建一個 template ,去繼承已有的 template ,並重寫已有模板使用的controller,爲controller增加返回值,以便在新建template 中使用返回數據。
實際上,第一種方式是在創建一個頁面 ,在頁面中使用template 。第二種是 繼承已有頁面,重寫原有接口增加返回值。本文只對第一種情況舉例說明。
要實現數據的動態展示,一定離不開使用路由(也就是調用接口)。在進入頁面後,通過路由獲取數據,返回到template 進行數據渲染。下面舉例說明:
第一步,創建一條 website.page 的記錄,新建文件 /views/zerone_newest_books_pages.xml:
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="newest_books_page" model="website.page">
<field name="name">新上圖書</field>
<field name="website_published">True</field>
<field name="url">/newest_book</field>
<field name="type">qweb</field>
<field name="key">zerone_inherit.books_page</field>
<field name="arch" type="xml">
<t t-name="zerone_inherit.newest_books_page_template">
<t t-call="website.layout">
<div class="container">
<div id="wrap">
<div class="row">
<!-- 留位置渲染圖書卡片 -->
</div>
</div>
</div>
</t>
</t>
</field>
</record>
<record id="newest_books_page_link" model="website.menu">
<field name="name">Newest Books</field>
<field name="page_id" ref="newest_books_page"/>
<field name="parent_id" ref="website.main_menu"/>
<field name="sequence" type="int">99</field>
</record>
</odoo>
在manifest文件的data中引用上面的xml文件
第二步,創建接口,新建文件 /controllers/newest_books_controller.py
from odoo import http
class NewestBooksController(http.Controller):
@http.route('/newest_book', auth='public', website=True)
def newest_book(self):
book_obj = http.request.env['zerone.book'].sudo()
# 這裏的模板是 record: key = zerone_inherit.books_page
return http.request.render('zerone_inherit.books_page', {
'books': book_obj.search([], limit=5, order='id desc')
})
在controllers文件夾下引用上面的文件,並在根部錄下的init文件中,引用controllers。
安裝或升級,進入網站主頁可以看到,菜單欄上多出一個名爲Newest Books 的菜單,點擊進去啥也沒有,是因爲傳入的books參數還沒有拿去渲染。
第三步,創建渲染圖書卡片模板,新建文件 /static/src/xml/newest_books_templates.xml
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="book_card">
<t t-name="book_card_template">
<t t-foreach="books" t-as="book">
<div class="col-sm-12 col-md-4 col-lg-4">
<div class="zerone_panel panel-warning">
<h5>
<t t-esc="book.name"/>
</h5>
<span>
<t t-esc="book.author"/>
</span>
</div>
</div>
</t>
</t>
</template>
</odoo>
將上面的文件在 manifest 文件的 data 中引用,並在第一步的文件中,調用此模板:
<div class="row">
<!-- 留位置渲染圖書卡片 -->
<t t-call="zerone_inherit.book_card"/>
</div>
第四步,爲模板元素增加樣式,新建文件 /static/src/css/page_books.css
.zerone_panel {
min-height: 100px;
width: 100%;
padding: 24px !important;
margin: 6px 0;
color: #FFFFFF;
text-align: center;
font-size:14px;
cursor: pointer;
}
.zerone_panel:hover {
background: #666666;
color:#FFFFFF;
}
.panel-warning {
background: #da542e;
}
第五步,引用樣式表,新建文件 /views/assets.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_frontend" name="Page Books Assets" inherit_id="web.assets_frontend">
<xpath expr="." position="inside">
<link rel="stylesheet" href="/zerone_inherit/static/src/css/page_books.css"/>
</xpath>
</template>
</odoo>
再次安裝或升級,進入網站主頁,可以看到效果
第二種方式,實際上是對繼承的使用,這裏不做說明,需要看視圖繼承的請移步 odoo創建新模板及繼承已有模板
本文實現的情況是在一個單獨的頁面中,顯示最新的書籍信息,所以創建了一個page頁面,若要在已有頁面上顯示最新書籍信息,則需要繼承已有模板,而無需創建新的頁面。本文實現過程中,需要注意一下幾點:
在第一步中,需要注意
- 頁面存放的模型是website.page,可以看出頁面是依賴website的,故在manifest文件的depends中應依賴website模塊。
- 頁面的創建 website_published 表示是否在網站中發佈,爲True則發佈顯示,爲False則不發佈不顯示。
- 頁面的創建 view_type 是qweb
- 頁面的創建 url 既是打開頁面的地址,也是下面controller 的接口名
- 頁面的創建 key 是當前頁面模板的唯一標識,在controller接口返回時會用到,告訴系統渲染哪一個模板
- 頁面創建之後,需要創建一個菜單,其存放模型是 website.menu
- 菜單的創建 page_id 是爲菜單指定頁面
- 菜單的創建 parent_id 是爲菜單指定菜單位置
在第二步中,需要注意
- 路由上需要增加一個屬性 website = True ,會在請求對象上設置一些新變量,並允許在我們的模板中使用網站佈局
- 路由即爲第一步中的url
- 返回值中的第一個參數即爲第一步中的key,指明渲染模板
在第三步中,需要注意
- template 的 id 就是在第一步中,t-call 調用的模板標識,調用時記得格式:模塊名.template的id