布局¶
在本章中,您将学习如何:
创建一个自定义页眉。
创建自定义页脚。
修改一个标准模板。
添加版权信息部分。
优化您的网站响应性。
默认¶
一个 Odoo 页面结合了跨页面元素和唯一元素。跨页面元素在每一页上都是相同的,而唯一元素仅与特定页面相关。默认情况下,一个页面包含两个跨页面元素,即页眉和页脚,以及一个唯一的主元素,该元素包含该页面的特定内容。
<div id="wrapwrap">
<header/>
<main>
<div id="wrap" class="oe_structure">
<!-- Page Content -->
</div>
</main>
<footer/>
</div>
任何 Odoo XML 文件都以编码规范开头。之后,您必须将代码写在 <odoo>
标签内。
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
...
</odoo>
注解
使用精确的文件名对于通过所有模块快速查找信息非常重要。文件名只能包含小写字母数字和下划线。
始终在文件末尾添加一个空行。这可以通过配置您的 IDE 自动完成。
XPath¶
XPath(XML 路径语言)是一种表达式语言,它使您能够轻松地在 XML 文档中导航元素和属性。XPath 用于扩展标准 Odoo 模板。
视图的编码方式如下。
<template id="..." inherit_id="..." name="...">
<!-- Content -->
</template>
属性 |
描述 |
---|---|
id |
修改后的视图的 ID |
继承的ID |
标准视图的 ID |
名称 |
可读的修改后视图名称 |
对于每个 XPath,你需要修改两个属性:表达式 和 位置。
Example
/website_airproof/views/website_templates.xml
¶<template id="layout" inherit_id="website.layout" name="Welcome Message">
<xpath expr="//header" position="before">
<!-- Content -->
</xpath>
</template>
这个 XPath 在页面内容之前添加了一个欢迎消息。
警告
在替换默认元素属性时请格外小心。由于你的主题继承自默认主题,你的更改将优先于任何未来的 Odoo 更新。
注解
您应该在每次创建新模板或记录时更新您的模块。
XML ID 的继承视图应使用与原始记录相同的 ID。这有助于一目了然地找到所有继承关系。由于最终的 XML ID 会以创建它们的模块名称作为前缀,因此不会出现重复。
表达式¶
XPath 使用路径表达式在 XML 文档中选择节点。选择器用于表达式中以定位正确的元素。下面列出了最常用的一些选择器。
后代选择器 |
描述 |
---|---|
/ |
从根节点中选择。 |
// |
从当前节点开始,选择文档中所有匹配选择条件的节点,无论它们位于何处。 |
属性选择器 |
描述 |
---|---|
* |
选择任何 XML 标签。如果需要更精确的选取, |
*[@id=”id”] |
选择一个特定的 ID。 |
*[hasclass(“class”)] |
选择一个特定的类。 |
*[@name=”名称”] |
选择具有特定名称的标签。 |
*[@t-call=”t-call”] |
选择一个特定的电话。 |
位置¶
位置定义了代码在模板中的放置位置。可能的值如下所示:
位置 |
描述 |
---|---|
replace |
用 XPath 内容替换目标节点。 |
内部 |
在目标节点内部添加 XPath 内容。 |
before |
在目标节点之前添加 XPath 内容。 |
after |
在目标节点之后添加 XPath 内容。 |
属性 |
在属性中添加 XPath 内容。 |
Example
此 XPath 在 <header>
的直接子元素 <nav>
之前添加一个 <div>
。
<xpath expr="//header/nav" position="before">
<div>Some content before the header</div>
</xpath>
此 XPath 在页眉的 class
属性中添加了 x_airproof_header
。您还需要定义一个 separator
属性,以在您要添加的类之前添加一个空格。
<xpath expr="//header" position="attributes">
<attribute name="class" add="x_airproof_header" separator=" "/>
</xpath>
此 XPath 会从标题的 x_airproof_header
类属性中移除。在这种情况下,您不需要使用 separator
属性。
<xpath expr="//header" position="attributes">
<attribute name="class" remove="x_airproof_header" />
</xpath>
此 XPath 会移除第一个具有 .breadcrumb
类的元素。
<xpath expr="//*[hasclass('breadcrumb')]" position="replace"/>
此 XPath 在 <ul>
元素的最后一个子元素之后添加一个额外的 <li>
元素。
<xpath expr="//ul" position="inside">
<li>Last element of the list</li>
</xpath>
另请参见
你可以在这一份 速查表 中找到更多关于 XPath 的信息。
QWeb¶
QWeb 是 Odoo 主要使用的模板引擎。它是一种 XML 模板引擎,主要用于生成 HTML 片段和页面。
另请参见
背景¶
你可以将颜色或图片定义为网站的背景。
颜色
/website_airproof/static/src/scss/primary_variables.scss
¶$o-color-palettes: map-merge($o-color-palettes,
(
'airproof': (
'o-cc1-bg': 'o-color-5',
'o-cc5-bg': 'o-color-1',
),
)
);
图片/图案
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
'body-image': '/website_airproof/static/src/img/background-lines.svg',
'body-image-type': 'image' or 'pattern'
)
);
页眉¶
默认情况下,页眉包含一个响应式导航菜单和公司的logo。您可以轻松添加新元素或创建自己的模板。
标准¶
启用其中一个默认页眉模板。
重要
不要忘记,您可能需要先禁用激活的页眉模板。
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
'header-template': 'Contact',
),
);
/网站防尘/数据/预设.xml
¶<record id="website.template_header_contact" model="ir.ui.view">
<field name="active" eval="True"/>
</record>
自定义¶
创建您自己的模板并将其添加到列表中。
重要
不要忘记,您可能需要先禁用激活的页眉模板。
选项
在网站构建器中为你的新自定义标题添加选项,请使用以下代码。
/网站防尘/数据/预设.xml
¶<template id="template_header_opt" inherit_id="website.snippet_options" name="Header Template - Option">
<xpath expr="//we-select[@data-variable='header-template']" position="inside">
<we-button title="airproof"
data-customize-website-views="website_airproof.header"
data-customize-website-variable="'airproof'" data-img="/website_airproof/static/src/img/wbuilder/template_header_opt.svg"/>
</xpath>
</template>
属性 |
描述 |
---|---|
data-自定义-网站-视图 |
启用模板 |
data-customize-website-variable |
变量的名称 |
data-img |
网站构建器中模板选择界面显示的自定义模板缩略图 |
现在您必须显式地定义您希望在 Odoo SASS 变量中使用您的自定义模板。
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
'header-template': 'airproof',
),
);
布局
/website_airproof/views/website_templates.xml
¶<record id="header" model="ir.ui.view">
<field name="name">Airproof Header</field>
<field name="type">qweb</field>
<field name="key">website_airproof.header</field>
<field name="inherit_id" ref="website.layout"/>
<field name="mode">extension</field>
<field name="arch" type="xml">
<xpath expr="//header//nav" position="replace">
<!-- Static Content -->
<!-- Components -->
<!-- Editable areas -->
</xpath>
</field>
</record>
组件¶
在你的自定义页眉中,你可以使用 QWeb 中的 t-call
指令调用多个子模板:
Logo¶
<t t-call="website.placeholder_header_brand">
<t t-set="_link_class" t-valuef="..."/>
</t>
不要忘记在数据库中记录您网站的标志。
/website_airproof/data/images.xml
¶<record id="website.default_website" model="website">
<field name="logo" type="base64" file="website_airproof/static/src/img/content/logo.png"/>
</record>
登录¶
<t t-call="portal.placeholder_user_sign_in">
<t t-set="_item_class" t-valuef="nav-item"/>
<t t-set="_link_class" t-valuef="nav-link"/>
</t>
用户下拉菜单¶
<t t-call="portal.user_dropdown">
<t t-set="_user_name" t-value="true"/>
<t t-set="_icon" t-value="false"/>
<t t-set="_avatar" t-value="false"/>
<t t-set="_item_class" t-valuef="nav-item dropdown"/>
<t t-set="_link_class" t-valuef="nav-link"/>
<t t-set="_dropdown_menu_class" t-valuef="..."/>
</t>
语言选择器¶
<t t-call="website.placeholder_header_language_selector">
<t t-set="_div_classes" t-valuef="..."/>
</t>
行动号召¶
<t t-call="website.placeholder_header_call_to_action">
<t t-set="_div_classes" t-valuef="..."/>
</t>
标准¶
启用其中一个默认页脚模板。请记住,您可能需要先禁用当前激活的页脚模板。
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
'header-template': 'Contact',
),
);
/网站防尘/数据/预设.xml
¶<record id="website.template_header_contact" model="ir.ui.view">
<field name="active" eval="True"/>
</record>
自定义¶
创建您自己的模板并将其添加到列表中。请记住,您可能需要先禁用激活的页脚模板。
选项
/网站防尘/数据/预设.xml
¶<template id="template_header_opt" inherit_id="website.snippet_options" name="Footer Template - Option">
<xpath expr="//we-select[@data-variable='footer-template']" position="inside">
<we-button title="airproof"
data-customize-website-views="website_airproof.footer"
data-customize-website-variable="'airproof'"
data-img="/website_airproof/static/src/img/wbuilder/template_header_opt.svg"/>
</xpath>
</template>
声明
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
'footer-template': 'airproof',
),
);
布局
/website_airproof/views/website_templates.xml
¶<record id="footer" model="ir.ui.view">
<field name="name">Airproof Footer</field>
<field name="type">qweb</field>
<field name="key">website_airproof.footer</field>
<field name="inherit_id" ref="website.layout"/>
<field name="mode">extension</field>
<field name="arch" type="xml">
<xpath expr="//div[@id='footer']" position="replace">
<div id="footer" class="oe_structure oe_structure_solo" t-ignore="true" t-if="not no_footer">
<!-- Content -->
</div>
</xpath>
</field>
</record>
版权¶
目前只有一个用于版权栏的模板可用。
要替换内容或修改其结构,您可以将自定义代码添加到以下 XPath 表达式中。
/website_airproof/views/website_templates.xml
¶<template id="copyright" inherit_id="website.layout">
<xpath expr="//div[hasclass('o_footer_copyright')]" position="replace">
<div class="o_footer_copyright" data-name="Copyright">
<!-- Content -->
</div>
</xpath>
</template>
拖放区域¶
与其定义页面的完整布局,您可以创建可复用的模块(片段),并让用户自行选择将它们拖放到何处,从而自定义页面布局。我们称这种设计方式为 模块化设计。
您可以定义一个空区域,用户可以在其中填充片段。
<div id="oe_structure_layout_01" class="oe_structure"/>
类 |
描述 |
---|---|
oe_structure |
为用户提供一个拖放区域。 |
oe_structure_solo |
此区域只能放置一个代码片段。 |
你可以将现有下拉区域用你的内容进行填充。
<template id="oe_structure_layout_01" inherit_id="..." name="...">
<xpath expr="//*[@id='oe_structure_layout_01']" position="replace">
<div id="oe_structure_layout_01" class="oe_structure oe_structure_solo">
<!-- Content -->
</div>
</xpath>
</template>
响应式¶
你可以根据以下提示,使你的网站更具响应性。
Bootstrap¶
字体大小
从 v4.3.0 版本开始,Bootstrap 提供了启用响应式字体大小的选项,使文本能够更自然地在不同设备和视口尺寸上进行缩放。通过将 Sass 变量 $enable-responsive-font-sizes
设置为 true 来启用此功能。
另请参见
网站构建器¶
在移动设备上隐藏特定的 <section>
。
<section class="d-none d-md-block">
<!-- Content -->
</section>
在移动设备上隐藏 <col>
。
<section>
<div class="container">
<div class="row d-flex align-items-stretch">
<div class="col-lg-4 d-none d-md-block">
<!-- Content -->
</div>
</div>
</div>
</section>