[IMP] web, website(_*): use web.layout for every web page

The web modules defines a "layout" template which is only used by the
login default page. Now the backend template "web.webclient_bootstrap"
and the frontend template "website.layout" both use the "web.layout"
template as base.

Some parameters can be passed to customize the default "web.layout"
template:
- "head": content will be placed at the end of the <head> tag of the
page
- "title": to set the title of the page (the <title> tag should not be
placed "by hand")
- "x_icon": the url for the page icon
- "html_data": dictionnary whose key-value pairs will be placed as
attribute-value for the <html> tag
- "body_classname": the classname to set on the <body> tag

Note: xpath expression on the website.layout template can now only find
the #wrapwrap element and its children. An expression "//body" will not
have any result. If something has to be added in the body element but
not in the #wrapwrap element, simply change the xpath
<xpath expr="//body" position="inside"> with
<xpath expr="//div[@​id='wrapwrap']" position="after">
This commit is contained in:
qsm-odoo
2016-08-30 13:57:32 +02:00
parent a7930e51ec
commit b4a159d261
4 changed files with 148 additions and 173 deletions
+66 -86
View File
@@ -189,12 +189,21 @@
</template>
<template id="web.layout" name="Web layout">&lt;!DOCTYPE html&gt;
<html style="height: 100%">
<html t-att="html_data or {}">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Odoo</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title t-esc="title or 'Odoo'"/>
<link type="image/x-icon" rel="shortcut icon" t-att-href="x_icon or '/web/static/src/img/favicon.ico'"/>
<script type="text/javascript">
var odoo = {
csrf_token: "<t t-esc="request.csrf_token(None)"/>",
};
</script>
<t t-raw="head or ''"/>
</head>
<body t-att-class="body_classname">
@@ -205,6 +214,7 @@
<template id="web.login_layout" name="Login Layout">
<t t-call="web.layout">
<t t-set="html_data" t-value="{'style': 'height: 100%;'}"/>
<t t-set="head">
<t t-call-assets="web.assets_common" t-js="false"/>
<t t-call-assets="web.assets_frontend" t-js="false"/>
@@ -212,6 +222,7 @@
<t t-call-assets="web.assets_frontend" t-css="false"/>
</t>
<t t-set="body_classname" t-value="'container'"/>
<div class="row">
<div class="col-md-6 col-md-offset-3 o_database_list">
<div class="text-center">
@@ -327,37 +338,33 @@
</a>
</template>
<template id="web.qunit_suite">
&lt;!DOCTYPE html&gt;
<html style="height: 100%">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Odoo Web Tests</title>
<template id="web.webclient_script">
<script type="text/javascript">
odoo.define('web.web_client', function (require) {
var WebClient = require('web.WebClient');
var web_client = new WebClient();
$(function() {
web_client.setElement($(document.body));
web_client.start();
});
return web_client;
});
</script>
</template>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="/web/static/lib/qunit/qunit-1.17.1.css"/>
<script src="/web/static/lib/qunit/qunit-1.17.1.js"></script>
<template id="web.qunit_suite">
<t t-call="web.layout">
<t t-set="html_data" t-value="{'style': 'height: 100%;'}"/>
<t t-set="title">Odoo Web Tests</t>
<t t-set="head">
<link type="text/css" rel="stylesheet" href="/web/static/lib/qunit/qunit-1.17.1.css"/>
<script type="text/javascript" src="/web/static/lib/qunit/qunit-1.17.1.js"></script>
<t t-call-assets="web.assets_common" t-css="false"/>
<t t-call-assets="web.assets_backend" t-css="false"/>
<script type="text/javascript">
$(function() {
odoo.define('web.web_client', function (require) {
var WebClient = require('web.WebClient');
var web_client = new WebClient();
web_client.setElement($(document.body));
web_client.start();
return web_client;
});
});
</script>
<t t-call="web.webclient_script"/>
<style>
body { overflow: auto !important; }
</style>
<script type="text/javascript" src="/web/static/test/testing.js"></script>
<script type="text/javascript" src="/web/static/test/registry.js"></script>
<script type="text/javascript" src="/web/static/test/rpc-misordered.js"></script>
<script type="text/javascript" src="/web/static/test/mutex.js"></script>
@@ -370,31 +377,18 @@
<script type="text/javascript" src="/web/static/test/list-utils.js"></script>
<script type="text/javascript" src="/web/static/test/list-editable.js"></script>
<script type="text/javascript" src="/web/static/test/search.js"></script>
</head>
</t>
<body id="oe" class="openerp">
<div id="qunit"></div>
<div id="qunit-fixture"></div>
</body>
</html>
<div id="qunit"/>
<div id="qunit-fixture"/>
</t>
</template>
<template id="web.webclient_bootstrap">
&lt;!DOCTYPE html&gt;
<html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Odoo</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
<t t-call="web.layout">
<t t-set="head_web">
<script type="text/javascript">
var odoo = {
session_info: <t t-raw="session_info"/>,
csrf_token: "<t t-esc="request.csrf_token(None)"/>",
};
odoo.session_info = <t t-raw="session_info"/>;
</script>
<t t-call-assets="web.assets_common" t-js="false"/>
@@ -408,43 +402,29 @@
<![endif]-->
]]>
<script type="text/javascript">
$(function() {
<t t-if="init">
<t t-raw="init"/>
</t>
<t t-if="not init">
odoo.define('web.web_client', function (require) {
var WebClient = require('web.WebClient');
var web_client = new WebClient();
web_client.setElement($(document.body));
web_client.start();
return web_client;
});
</t>
});
</script>
</head>
<body class="o_web_client">
<nav id="oe_main_menu_navbar" class="navbar navbar-inverse" groups="base.group_user,base.group_portal">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<t t-call="web.menu"/>
</div>
</nav>
<div class="o_main">
<div class="o_sub_menu" groups="base.group_user,base.group_portal">
<t t-call="web.menu_secondary"/>
</div>
<div class="o_main_content"/>
<t t-call="web.webclient_script"/>
</t>
<t t-set="head" t-value="head_web + (head or '')"/>
<t t-set="body_classname" t-value="'o_web_client'"/>
<nav id="oe_main_menu_navbar" class="navbar navbar-inverse" groups="base.group_user,base.group_portal">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
</body>
</html>
<div class="navbar-collapse collapse">
<t t-call="web.menu"/>
</div>
</nav>
<div class="o_main">
<div class="o_sub_menu" groups="base.group_user,base.group_portal">
<t t-call="web.menu_secondary"/>
</div>
<div class="o_main_content"/>
</div>
</t>
</template>
</odoo>
@@ -2,10 +2,10 @@
<odoo>
<!-- Front-end/Back-end integration -->
<template id="user_navbar" inherit_id="website.layout">
<xpath expr="//body" position="attributes">
<attribute name="t-att-class">'o_connected_user' if env['ir.ui.view'].user_has_groups('base.group_user') else None</attribute>
<xpath expr="//t[@t-set='html_data']" position="after">
<t t-set="body_classname" t-value="'o_connected_user' if env['ir.ui.view'].user_has_groups('base.group_user') else None"/>
</xpath>
<xpath expr="//body/div['id=wrawrap']" position="before">
<xpath expr="//div[@id='wrapwrap']" position="before">
<nav groups="base.group_user" t-if="website and menu_data" id="oe_main_menu_navbar" class="o_main_navbar">
<ul id="oe_applications">
<li class="dropdown active">
@@ -92,7 +92,7 @@
</xpath>
<!-- Add new page/content modal -->
<xpath expr="//body/div['id=wrawrap']" position="after">
<xpath expr="//div[@id='wrapwrap']" position="after">
<div groups="base.group_user" class="modal" id="o_website_add_page_modal">
<div class="modal-dialog modal-lg">
<ul>
+76 -81
View File
@@ -73,28 +73,31 @@
</li>
</template>
<template id="layout" name="Main layout">&lt;!DOCTYPE html&gt;
<html t-att-lang="lang and lang.replace('_', '-')"
t-att-data-website-id="website.id if (editable or translatable) and website else None"
t-att-data-editable="'1' if editable else None"
t-att-data-translatable="'1' if translatable else None"
t-att-data-edit_translations="'1' if edit_translations else None"
t-att-data-view-xmlid="xmlid if editable or translatable else None"
t-att-data-main-object="repr(main_object) if editable or translatable else None"
t-att-data-oe-company-name="res_company.name">
<head>
<meta charset="utf-8" />
<t t-if="main_object and 'website_meta_title' in main_object and not title">
<t t-set="title" t-value="main_object.website_meta_title"/>
</t>
<t t-if="main_object and 'name' in main_object and not title and not additional_title">
<template id="layout" name="Main layout">
<t t-call="web.layout">
<t t-set="html_data" t-value="{
'lang': lang and lang.replace('_', '-'),
'data-website-id': website.id if (editable or translatable) and website else None,
'data-editable': '1' if editable else None,
'data-translatable': '1' if translatable else None,
'data-edit_translations': '1' if edit_translations else None,
'data-view-xmlid': xmlid if editable or translatable else None,
'data-main-object': repr(main_object) if editable or translatable else None,
'data-oe-company-name': res_company.name
}"/>
<t t-if="not title">
<t t-if="not additional_title and main_object and 'name' in main_object">
<t t-set="additional_title" t-value="main_object.name"/>
</t>
<t t-if="not title">
<t t-if="main_object and 'website_meta_title' in main_object and main_object.website_meta_title">
<t t-set="title" t-value="main_object.website_meta_title"/>
</t>
<t t-else="">
<t t-set="title"><t t-if="additional_title"><t t-raw="additional_title"/> | </t><t t-esc="(website or res_company).name"/></t>
</t>
<meta name="viewport" content="initial-scale=1"/>
</t>
<t t-set="x_icon" t-value="'/web/image/website/%s/favicon/' % website.id"/>
<t t-set="head_website">
<meta name="description" t-att-content="main_object and 'website_meta_description' in main_object
and main_object.website_meta_description or website_meta_description"/>
<meta name="keywords" t-att-content="main_object and 'website_meta_keywords' in main_object
@@ -111,8 +114,6 @@
<meta property='og:url' t-att-content="request.httprequest.url_root+request.httprequest.path[1:end]"/>
</t>
<title><t t-esc="title"/></title>
<t t-set="languages" t-value="website.get_languages() if website else None"/>
<t t-if="request and request.website_multilang and website">
<t t-foreach="website.get_alternate_languages(request.httprequest)" t-as="lg">
@@ -121,12 +122,9 @@
</t>
<script type="text/javascript">
var odoo = {
csrf_token: "<t t-esc="request.csrf_token(None)"/>",
session_info: {
is_superuser: <t t-esc="json.dumps(request.env.user._is_superuser())"/>,
is_frontend: true,
},
odoo.session_info = {
is_superuser: <t t-esc="json.dumps(request.env.user._is_superuser())"/>,
is_frontend: true,
};
</script>
@@ -141,65 +139,62 @@
<t t-call-assets="web_editor.summernote" t-css="false" groups="base.group_website_designer"/>
<t t-call-assets="web_editor.assets_editor" t-css="false" groups="base.group_website_designer"/>
<t t-call-assets="website.assets_editor" t-css="false" groups="base.group_website_publisher"/>
</t>
<t t-set="head" t-value="head_website + (head or '')"/>
<t t-raw="head or ''" name='layout_head'/>
<link rel="shortcut icon" type="image/x-icon" t-attf-href="/web/image/website/{{website.id}}/favicon/"/>
</head>
<body>
<div id="wrapwrap" t-att-class="pageName or ''">
<header>
<div class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-top-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/" t-if="website" t-field="website.name">My Website</a>
</div>
<div class="collapse navbar-collapse navbar-top-collapse">
<ul class="nav navbar-nav navbar-right" id="top_menu">
<t t-foreach="website.menu_id.child_id" t-as="submenu">
<t t-call="website.submenu"/>
</t>
<li class="divider" t-ignore="true" t-if="website.user_id != user_id"/>
<li class="dropdown" t-ignore="true" t-if="website.user_id != user_id">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<b>
<span t-esc="(len(user_id.name)&gt;25) and (user_id.name[:23]+'...') or user_id.name"/>
<span class="caret"></span>
</b>
</a>
<ul class="dropdown-menu js_usermenu" role="menu">
<li id="o_logout"><a t-attf-href="/web/session/logout?redirect=/" role="menuitem">Logout</a></li>
</ul>
</li>
</ul>
</div>
<div id="wrapwrap" t-att-class="pageName or ''">
<header>
<div class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-top-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/" t-if="website" t-field="website.name">My Website</a>
</div>
<div class="collapse navbar-collapse navbar-top-collapse">
<ul class="nav navbar-nav navbar-right" id="top_menu">
<t t-foreach="website.menu_id.child_id" t-as="submenu">
<t t-call="website.submenu"/>
</t>
<li class="divider" t-ignore="true" t-if="website.user_id != user_id"/>
<li class="dropdown" t-ignore="true" t-if="website.user_id != user_id">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<b>
<span t-esc="(len(user_id.name)&gt;25) and (user_id.name[:23]+'...') or user_id.name"/>
<span class="caret"></span>
</b>
</a>
<ul class="dropdown-menu js_usermenu" role="menu">
<li id="o_logout"><a t-attf-href="/web/session/logout?redirect=/" role="menuitem">Logout</a></li>
</ul>
</li>
</ul>
</div>
</div>
</header>
<main>
<t t-raw="0"/>
</main>
<footer>
<div id="footer">
</div>
</footer>
</div>
<script id='tracking_code' t-if="website and website.google_analytics_key and not editable">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
</div>
</header>
<main>
<t t-raw="0"/>
</main>
<footer>
<div id="footer">
</div>
</footer>
</div>
<script id='tracking_code' t-if="website and website.google_analytics_key and not editable">
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', _.str.trim('<t t-esc="website.google_analytics_key"/>'), 'auto');
ga('send','pageview');
</script>
</body>
</html>
ga('create', _.str.trim('<t t-esc="website.google_analytics_key"/>'), 'auto');
ga('send','pageview');
</script>
</t>
</template>
<template id="layout_footer_copyright" inherit_id="website.layout" name="Footer Copyright">
@@ -18,9 +18,9 @@
</xpath>
</template>
<template id="loader" inherit_id="website.layout" name="Livechat : include loader on Website">
<xpath expr="//body" position="inside">
<xpath expr="//div[@id='wrapwrap']" position="after">
<t t-if="website and website.channel_id">
<script>
<script>
<t t-call="im_livechat.loader">
<t t-set="channel" t-value="website.channel_id.id"/>
</t>