mirror of
https://github.com/odoo/documentation.git
synced 2026-03-26 13:59:55 +07:00
[IMP] howtos/website_theming: Adapts "Layout" chapter
closes odoo/documentation#16589 Signed-off-by: Brandon Mercier (bram) <bram@odoo.com>
This commit is contained in:
@@ -207,7 +207,7 @@ below:
|
||||
.. code-block:: xml
|
||||
|
||||
<xpath expr="//header" position="attributes">
|
||||
<attribute name="class" add="x_airproof_header" separator=" "/>
|
||||
<attribute name="class" add="x_airproof_header" separator=" " />
|
||||
</xpath>
|
||||
|
||||
This XPath moves the element with `.o_footer_scrolltop_wrapper` class before the element with the
|
||||
@@ -255,6 +255,42 @@ QWeb
|
||||
QWeb is the primary templating engine used by Odoo. It is an XML templating engine mainly used to
|
||||
generate HTML fragments and pages.
|
||||
|
||||
`t-call` directives can receive parameters:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<!-- Old way -->
|
||||
<t t-call="portal.user_dropdown">
|
||||
<t t-set="_icon" t-value="True" />
|
||||
<t t-set="_item_class" t-valuef="dropdown" />
|
||||
</t>
|
||||
|
||||
<t t-call="website.layout">
|
||||
<t t-set="additional_title">My page title</t>
|
||||
</t>
|
||||
|
||||
<!-- New way (Parametric) -->
|
||||
<t t-call="portal.user_dropdown"
|
||||
_icon="true"
|
||||
_item_class.f="dropdown" />
|
||||
|
||||
<t t-call="website.layout"
|
||||
additional_title.translate="My page title" />
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
:widths: 20 80
|
||||
|
||||
* - Attribute (examples)
|
||||
- Description
|
||||
* - `_icon="true"`
|
||||
- Pass the raw value (here a boolean set to `true`)
|
||||
* - `_item_class.f="dropdown"`
|
||||
- Pass value as a string
|
||||
* - `additional_title.translate="My page title"`
|
||||
- Pass value as a string
|
||||
|
||||
.. seealso::
|
||||
:doc:`QWeb templates documentation <../../reference/frontend/qweb>`.
|
||||
|
||||
@@ -281,7 +317,7 @@ First, create a record to declare the field. This field has to be linked to an e
|
||||
<field name="ttype">html</field>
|
||||
<field name="state">manual</field>
|
||||
<field name="index">0</field>
|
||||
<field name="model_id" ref="website_blog.model_blog_post"/>
|
||||
<field name="model_id" ref="website_blog.model_blog_post" />
|
||||
</record>
|
||||
|
||||
.. note:: Fields creation is also possible (and recommended) through `a model using Python </developer/tutorials/backend>`_.
|
||||
@@ -300,10 +336,10 @@ interface and fill it afterwards.
|
||||
<record id="view_blog_post_form_category" model="ir.ui.view">
|
||||
<field name="name">view_blog_post_form_category</field>
|
||||
<field name="model">blog.post</field>
|
||||
<field name="inherit_id" ref="website_blog.view_blog_post_form"/>
|
||||
<field name="inherit_id" ref="website_blog.view_blog_post_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='blog_id']" position="before">
|
||||
<field name="x_post_category" string="..." placeholder="..."/>
|
||||
<field name="x_post_category" string="..." placeholder="..." />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
@@ -318,7 +354,7 @@ The field value can be shown somewhere in a page by calling `model_name.field_na
|
||||
.. code-block:: xml
|
||||
:caption: ``/website_airproof/views/website_blog_templates.xml``
|
||||
|
||||
<h1 t-field="blog_post.x_post_category"/>
|
||||
<h1 t-field="blog_post.x_post_category" />
|
||||
|
||||
.. _website_themes/layout/background :
|
||||
|
||||
@@ -393,7 +429,7 @@ Enable one of the header default templates.
|
||||
:caption: ``/website_aiproof/data/presets.xml``
|
||||
|
||||
<record id="website.template_header_default" model="ir.ui.view">
|
||||
<field name="active" eval="False"/>
|
||||
<field name="active" eval="False" />
|
||||
</record>
|
||||
|
||||
Explicitly set the desired template in the `primary_variables.scss` file.
|
||||
@@ -403,15 +439,15 @@ Explicitly set the desired template in the `primary_variables.scss` file.
|
||||
|
||||
$o-website-values-palettes: (
|
||||
(
|
||||
'header-template': 'Contact',
|
||||
'header-template': 'stretch',
|
||||
),
|
||||
);
|
||||
|
||||
.. code-block:: xml
|
||||
:caption: ``/website_airproof/data/presets.xml``
|
||||
|
||||
<record id="website.template_header_contact" model="ir.ui.view">
|
||||
<field name="active" eval="True"/>
|
||||
<record id="website.template_header_stretch" model="ir.ui.view">
|
||||
<field name="active" eval="True" />
|
||||
</record>
|
||||
|
||||
.. _website_themes/layout/header/standard/mobile :
|
||||
@@ -423,7 +459,7 @@ Each header template comes with the `template_header_mobile` template ensuring a
|
||||
experience accross every devices.
|
||||
|
||||
.. seealso::
|
||||
`Mobile header template on Odoo's Git repository <https://github.com/odoo/odoo/blob/43b20e6e52526c415e28c21810cd7023f6feef1e/addons/website/views/website_templates.xml#L354>`_
|
||||
`Mobile header template on Odoo's Git repository <https://github.com/odoo/odoo/blob/e9c9f0ca0a54b9ca966451d12b7eecc6b9a7d6e0/addons/website/views/website_templates.xml#L383>`_
|
||||
|
||||
|
||||
.. _website_themes/layout/header/custom :
|
||||
@@ -442,9 +478,9 @@ Create your own template and add it to the list.
|
||||
Use the following code to add an option for your new custom header on the Website Builder.
|
||||
|
||||
.. code-block:: xml
|
||||
:caption: ``/website_airproof/static/src/website_builder/header_option.xml``
|
||||
:caption: ``/website_airproof/static/src/website_builder/header_template_option.xml``
|
||||
|
||||
<t t-inherit="website.HeaderTemplateOption" t-inherit-mode="extension">
|
||||
<t t-name="website_airproof.HeaderTemplateOption" t-inherit="website.HeaderTemplateOption" t-inherit-mode="extension">
|
||||
<xpath expr="//BuilderRow[@label.translate='Template']//BuilderSelect" position="inside">
|
||||
<BuilderSelectItem
|
||||
id="'header_airproof_opt'"
|
||||
@@ -453,16 +489,16 @@ Use the following code to add an option for your new custom header on the Websit
|
||||
{
|
||||
action: 'websiteConfig',
|
||||
actionParam: {
|
||||
views: ['website_airproof.header'],
|
||||
vars: { 'header-template': 'airproof' },
|
||||
checkVars: false,
|
||||
}
|
||||
}
|
||||
views: ['website_airproof.header'],
|
||||
vars: { 'header-template': 'airproof' },
|
||||
checkVars: false,
|
||||
},
|
||||
},
|
||||
]">
|
||||
<Img attrs="{ style: 'width: calc(100% - 0.5rem);' }" src="'/website_airproof/static/src/img/wbuilder/template_header_opt.svg'"/>
|
||||
<Img src="'/website_airproof/static/src/img/wbuilder/template-header-opt.svg'" attrs="{ style: 'width: calc(100% - 0.5rem);' }" />
|
||||
</BuilderSelectItem>
|
||||
</xpath>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
@@ -472,10 +508,12 @@ Use the following code to add an option for your new custom header on the Websit
|
||||
* - Attribute
|
||||
- Description
|
||||
* - views
|
||||
- The template to enable
|
||||
- The template(s) to enable
|
||||
* - vars
|
||||
- The name given to the variable
|
||||
* - <Img> src
|
||||
- The name given to the variable (same as used into `primary_variables.scss`)
|
||||
* - checkVars
|
||||
- Determine if `vars` are compared to set the option status.
|
||||
* - src (in `Img`)
|
||||
- The thumbnail of the custom template shown in the templates selection on the Website Builder
|
||||
|
||||
Now you have to explicitly define that you want to use your custom template in the Odoo SASS
|
||||
@@ -527,9 +565,8 @@ Logo
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<t t-call="website.placeholder_header_brand">
|
||||
<t t-set="_link_class" t-valuef="..."/>
|
||||
</t>
|
||||
<t t-call="website.placeholder_header_brand"
|
||||
_link_class.f="..." />
|
||||
|
||||
.. important::
|
||||
|
||||
@@ -544,10 +581,9 @@ Menu
|
||||
.. code-block:: xml
|
||||
|
||||
<t t-foreach="website.menu_id.child_id" t-as="submenu">
|
||||
<t t-call="website.submenu">
|
||||
<t t-set="item_class" t-valuef="nav-item"/>
|
||||
<t t-set="link_class" t-valuef="nav-link"/>
|
||||
</t>
|
||||
<t t-call="website.submenu"
|
||||
item_class.f="nav-item"
|
||||
link_class.f="nav-link" />
|
||||
</t>
|
||||
|
||||
.. _website_themes/layout/header/components/signin :
|
||||
@@ -557,10 +593,9 @@ Sign in
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<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.placeholder_user_sign_in"
|
||||
_item_class.f="nav-item"
|
||||
_link_class.f="nav-link" />
|
||||
|
||||
.. _website_themes/layout/header/components/user_dropdown :
|
||||
|
||||
@@ -569,14 +604,13 @@ User dropdown
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<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="portal.user_dropdown"
|
||||
_user_name="true"
|
||||
_icon="false"
|
||||
_avatar="false"
|
||||
_item_class.f="nav-item dropdown"
|
||||
_link_class.f="nav-link"
|
||||
_dropdown_menu_class.f="..." />
|
||||
|
||||
.. _website_themes/layout/header/components/language_selector :
|
||||
|
||||
@@ -585,9 +619,8 @@ Language selector
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<t t-call="website.placeholder_header_language_selector">
|
||||
<t t-set="_div_classes" t-valuef="..."/>
|
||||
</t>
|
||||
<t t-call="website.placeholder_header_language_selector"
|
||||
_div_classes.f="..." />
|
||||
|
||||
.. _website_themes/layout/header/components/cta :
|
||||
|
||||
@@ -596,9 +629,8 @@ Call to action
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<t t-call="website.placeholder_header_call_to_action">
|
||||
<t t-set="_div_classes" t-valuef="..."/>
|
||||
</t>
|
||||
<t t-call="website.placeholder_header_call_to_action"
|
||||
_div_classes.f="..." />
|
||||
|
||||
.. _website_themes/layout/header/components/navbar_toggler :
|
||||
|
||||
@@ -607,13 +639,12 @@ Navbar toggler
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<t t-call="website.navbar_toggler">
|
||||
<t t-set="_toggler_class" t-valuef="..."/>
|
||||
</t>
|
||||
<t t-call="website.navbar_toggler"
|
||||
_toggler_class.f="..." />
|
||||
|
||||
.. seealso::
|
||||
You can add a :ref:`header overlay <website_themes/pages/theme_pages/header_overlay>` to position your header over the content of
|
||||
your page. It has to be done on each page individually.
|
||||
You can add a :ref:`header overlay <website_themes/pages/theme_pages/header_overlay>` to position
|
||||
your header over the content of your page. It has to be done on each page individually.
|
||||
|
||||
.. _website_themes/layout/footer :
|
||||
|
||||
@@ -640,7 +671,7 @@ footer template first.
|
||||
:caption: ``/website_aiproof/data/presets.xml``
|
||||
|
||||
<record id="website.footer_custom" model="ir.ui.view">
|
||||
<field name="active" eval="False"/>
|
||||
<field name="active" eval="False" />
|
||||
</record>
|
||||
|
||||
.. code-block:: scss
|
||||
@@ -656,7 +687,7 @@ footer template first.
|
||||
:caption: ``/website_airproof/data/presets.xml``
|
||||
|
||||
<record id="website.template_footer_links" model="ir.ui.view">
|
||||
<field name="active" eval="True"/>
|
||||
<field name="active" eval="True" />
|
||||
</record>
|
||||
|
||||
.. _website_themes/layout/footer/custom :
|
||||
@@ -670,15 +701,15 @@ active footer template first.
|
||||
**Option**
|
||||
|
||||
.. code-block:: js
|
||||
:caption: ``/website_airproof/static/src/website_builder/airproof_footer_plugin.js``
|
||||
:caption: ``/website_airproof/static/src/website_builder/footer_option_plugin.js``
|
||||
|
||||
import { Plugin } from "@html_editor/plugin";
|
||||
import { registry } from "@web/core/registry";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
import { FooterTemplateChoice } from "@website/builder/plugins/options/footer_template_option";
|
||||
|
||||
export class AirproofFooterPlugin extends Plugin {
|
||||
static id = "airproofFooter";
|
||||
export class AirproofFooterOptionPlugin extends Plugin {
|
||||
static id = "airproofFooterOption";
|
||||
resources = {
|
||||
footer_templates_providers: () => [
|
||||
{
|
||||
@@ -688,15 +719,30 @@ active footer template first.
|
||||
title: _t("Airproof"),
|
||||
view: "website_airproof.footer",
|
||||
varName: "airproof",
|
||||
imgSrc: "/website_airproof/static/src/img/wbuilder/template_footer_opt.svg",
|
||||
imgSrc: "/website_airproof/static/src/img/wbuilder/template-footer-opt.svg",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
registry.category("website-plugins").add(AirproofFooterPlugin.id, AirproofFooterPlugin);
|
||||
registry.category("website-plugins").add(AirproofFooterOptionPlugin.id, AirproofFooterOptionPlugin);
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
:stub-columns: 1
|
||||
:widths: 20 80
|
||||
|
||||
* - Property
|
||||
- Description
|
||||
* - title
|
||||
- Display title of the template
|
||||
* - view
|
||||
- Template that is enabled.
|
||||
* - varName
|
||||
- Value used in `primary_variables.scss` under `footer-template`.
|
||||
* - imgSrc
|
||||
- The thumbnail of the custom template shown in the templates selection on the Website Builder
|
||||
|
||||
**Declaration**
|
||||
|
||||
@@ -712,7 +758,7 @@ active footer template first.
|
||||
**Template**
|
||||
|
||||
.. code-block:: xml
|
||||
:caption: ``/website_airproof/views/website_templates.xml``
|
||||
:caption: ``/website_airproof/views/website_templates.xml``
|
||||
|
||||
<template id="footer" inherit_id="website.layout" name="Airproof - Footer" active="True">
|
||||
<xpath expr="//div[@id='footer']" position="replace">
|
||||
@@ -732,15 +778,15 @@ There is only one template available at the moment for the copyright bar.
|
||||
To replace the content or modify its structure, you can add your own code to the following XPath.
|
||||
|
||||
.. code-block:: xml
|
||||
:caption: ``/website_airproof/views/website_templates.xml``
|
||||
:caption: ``/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>
|
||||
<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>
|
||||
|
||||
.. _website_themes/layout/dropzone :
|
||||
|
||||
@@ -755,7 +801,7 @@ You can define an empty area that the user can fill with snippets.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<div id="oe_structure_layout_01" class="oe_structure"/>
|
||||
<div id="oe_structure_layout_01" class="oe_structure" />
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
@@ -776,13 +822,13 @@ You can also populate an existing drop zone with your content.
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
.. _website_themes/layout/responsive :
|
||||
|
||||
@@ -844,15 +890,21 @@ Hide a section on desktop:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<section class="s_text_block o_cc o_cc1 o_colored_level pt16 pb16 d-lg-none o_snippet_desktop_invisible" data-snippet="s_text_block" name="Text">
|
||||
<!-- Content -->
|
||||
<section
|
||||
class="s_text_block o_cc o_cc1 o_colored_level pt16 pb16 d-lg-none o_snippet_desktop_invisible"
|
||||
data-snippet="s_text_block"
|
||||
data-name="Text">
|
||||
<!-- Content -->
|
||||
</section>
|
||||
|
||||
Hide a column on mobile:
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<section class="s_text_block o_cc o_cc1 o_colored_level pt16 pb16" data-snippet="s_text_block" name="Text">
|
||||
<section
|
||||
class="s_text_block o_cc o_cc1 o_colored_level pt16 pb16"
|
||||
data-snippet="s_text_block"
|
||||
data-name="Text">
|
||||
<div class="container s_allow_columns">
|
||||
<div class="row">
|
||||
<div class="col-12 col-lg-6 d-none d-lg-block o_snippet_mobile_invisible">
|
||||
|
||||
Reference in New Issue
Block a user