diff options
Diffstat (limited to 'addons/website')
| -rw-r--r-- | addons/website/data/website_data.xml | 126 | ||||
| -rw-r--r-- | addons/website/models/res_config_settings.py | 1 | ||||
| -rw-r--r-- | addons/website/models/website.py | 21 | ||||
| -rw-r--r-- | addons/website/static/src/js/backend/res_config_settings.js | 41 | ||||
| -rw-r--r-- | addons/website/static/src/js/editor/snippets.options.js | 58 | ||||
| -rw-r--r-- | addons/website/static/src/snippets/s_popup/000.js | 8 | ||||
| -rw-r--r-- | addons/website/static/src/snippets/s_popup/000.scss | 3 | ||||
| -rw-r--r-- | addons/website/static/src/snippets/s_popup/options.js | 5 | ||||
| -rw-r--r-- | addons/website/static/src/xml/website.cookies_bar.xml | 75 | ||||
| -rw-r--r-- | addons/website/static/src/xml/website.res_config_settings.xml | 22 | ||||
| -rw-r--r-- | addons/website/views/res_config_settings_views.xml | 13 | ||||
| -rw-r--r-- | addons/website/views/snippets/s_popup.xml | 15 | ||||
| -rw-r--r-- | addons/website/views/snippets/snippets.xml | 9 | ||||
| -rw-r--r-- | addons/website/views/website_templates.xml | 25 |
14 files changed, 407 insertions, 15 deletions
diff --git a/addons/website/data/website_data.xml b/addons/website/data/website_data.xml index 2304a8b3a7e..d24e2683fde 100644 --- a/addons/website/data/website_data.xml +++ b/addons/website/data/website_data.xml @@ -107,6 +107,132 @@ </record> </data> + <template id="cookie_policy" name="Cookie Policy"> + <t t-call="website.layout"> + <div id="wrap" class="oe_structure"> + <section class="pt8 pb8"> + <div class="container"> + <h2 class="pt16">Cookie Policy</h2> + <p> + Cookies are small bits of text sent by our servers to your computer or device when you access our services. + They are stored in your browser and later sent back to our servers so that we can provide contextual content. + Without cookies, using the web would be a much more frustrating experience. + We use them to support your activities on our website. For example, your session (so you don't have to login again) or your shopping cart. + <br/> + Cookies are also used to help us understand your preferences based on previous or current activity on our website (the pages you have + visited), your language and country, which enables us to provide you with improved services. + We also use cookies to help us compile aggregate data about site traffic and site interaction so that we can offer + better site experiences and tools in the future. + </p> + <p> + Here is an overview of the cookies that may be stored on your device when you visit our website: + </p> + <div class="table-responsive"> + <table class="small table table-bordered text-center"> + <thead class="thead-light"> + <tr> + <th scope="col" style="width: 20%">Category of Cookie</th> + <th scope="col" style="width: 50%; min-width: 200px;">Purpose</th> + <th scope="col" style="width: 30%">Examples</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <p>Session & Security</p> + </td> + <td> + <p> + Authenticate users, protect user data and allow the website to deliver the services users expects, + such as maintaining the content of their cart, or allowing file uploads. + </p> + <p>The website will not work properly if you reject or discard those cookies.</p> + </td> + <td> + session_id (Odoo)<br/> + fileToken (Odoo) + </td> + </tr> + <tr> + <td> + <p>Preferences</p> + </td> + <td> + <p>Remember information about the preferred look or behavior of the website, such as your preferred language or region.</p> + <p>Your experience may be degraded if you discard those cookies, but the website will still work.</p> + </td> + <td> + frontend_lang (Odoo) + </td> + </tr> + <tr> + <td>Interaction History</td> + <td> + <p> + Users to collect information about your interactions with the website, the pages you've seen, + and any specific marketing campaign that brought you to the website. + </p> + <p>We may not be able to provide the best service to you if you reject those cookies, but the website will work.</p> + </td> + <td> + im_livechat_previous_operator_pid (Odoo)<br/> + utm_campaign (Odoo)<br/> + utm_source (Odoo)<br/> + utm_medium (Odoo) + </td> + </tr> + <tr> + <td> + <p>Advertising & Marketing</p> + </td> + <td> + <p> + Used to make advertising more engaging to users and more valuable to publishers and advertisers, + such as providing more relevant ads when you visit other websites that display ads or to improve reporting on ad campaign performance. + </p> + <p>Note that some third-party services may install additional cookies on your browser in order to identify you.</p> + <p> + You may opt-out of a third-party's use of cookies by visiting the <a href="https://optout.networkadvertising.org/?c=1" rel="nofollow">Network Advertising Initiative opt-out page</a>. + The website will still work if you reject or discard those cookies. + </p> + </td> + <td> + __gads (Google)<br/> + __gac (Google) + </td> + </tr> + <tr> + <td> + <p>Analytics</p> + </td> + <td> + <p> + Understand how visitors engage with our website, via Google Analytics. + Learn more about <a href="https://developers.google.com/analytics/resources/concepts/gaConceptsCookies?hl=en">Analytics cookies and privacy information.</a> + </p> + <p>The website will still work if you reject or discard those cookies.</p> + </td> + <td> + _ga (Google)<br/> + _gat (Google)<br/> + _gid (Google)<br/> + _gac_* (Google) + </td> + </tr> + </tbody> + </table> + </div> + <p> + You can choose to have your computer warn you each time a cookie is being sent, or you can choose to turn off all cookies. + Each browser is a little different, so look at your browser's Help menu to learn the correct way to modify your cookies. + </p> + <p>We do not currently support Do Not Track signals, as there is no industry standard for compliance.</p> + </div> + </section> + </div> + </t> + </template> + <data noupdate="1"> <record id="homepage_page" model="website.page"> <field name="is_published">True</field> diff --git a/addons/website/models/res_config_settings.py b/addons/website/models/res_config_settings.py index 85449fd23c2..054ec2d019c 100644 --- a/addons/website/models/res_config_settings.py +++ b/addons/website/models/res_config_settings.py @@ -28,6 +28,7 @@ class ResConfigSettings(models.TransientModel): website_default_lang_code = fields.Char('Default language code', related='website_id.default_lang_id.code', readonly=False) specific_user_account = fields.Boolean(related='website_id.specific_user_account', readonly=False, help='Are newly created user accounts website specific') + website_cookies_bar = fields.Boolean(related='website_id.cookies_bar', readonly=False) google_analytics_key = fields.Char('Google Analytics Key', related='website_id.google_analytics_key', readonly=False) google_management_client_id = fields.Char('Google Client ID', related='website_id.google_management_client_id', readonly=False) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index f9a6a9f4c77..6de22c8f241 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -59,6 +59,7 @@ class Website(models.Model): language_ids = fields.Many2many('res.lang', 'website_lang_rel', 'website_id', 'lang_id', 'Languages', default=_active_languages) default_lang_id = fields.Many2one('res.lang', string="Default Language", default=_default_language, required=True) auto_redirect_lang = fields.Boolean('Autoredirect Language', default=True, help="Should users be redirected to their browser's language") + cookies_bar = fields.Boolean('Cookies Bar', help="Display a customizable cookies bar on your website.") def _default_social_facebook(self): return self.env.ref('base.main_company').social_facebook @@ -168,6 +169,26 @@ class Website(models.Model): if 'cdn_activated' in values or 'cdn_url' in values or 'cdn_filters' in values: # invalidate the caches from static node at compile time self.env['ir.qweb'].clear_caches() + + if 'cookies_bar' in values: + if values['cookies_bar']: + cookies_view = self.env.ref('website.cookie_policy', raise_if_not_found=False) + if cookies_view: + cookies_view.with_context(website_id=self.id).write({'website_id': self.id}) + specific_cook_view = self.with_context(website_id=self.id).viewref('website.cookie_policy') + self.env['website.page'].create({ + 'is_published': True, + 'website_indexed': False, + 'url': '/cookie-policy', + 'website_id': self.id, + 'view_id': specific_cook_view.id, + }) + else: + self.env['website.page'].search([ + ('website_id', '=', self.id), + ('url', '=', '/cookie-policy'), + ]).unlink() + return result @api.model diff --git a/addons/website/static/src/js/backend/res_config_settings.js b/addons/website/static/src/js/backend/res_config_settings.js index 47a52579447..ad9373d26f1 100644 --- a/addons/website/static/src/js/backend/res_config_settings.js +++ b/addons/website/static/src/js/backend/res_config_settings.js @@ -1,7 +1,14 @@ odoo.define('website.settings', function (require) { -var BaseSettingController = require('base.settings').Controller; -var FormController = require('web.FormController'); +const BaseSettingController = require('base.settings').Controller; +const core = require('web.core'); +const Dialog = require('web.Dialog'); +const FieldBoolean = require('web.basic_fields').FieldBoolean; +const fieldRegistry = require('web.field_registry'); +const FormController = require('web.FormController'); + +const QWeb = core.qweb; +const _t = core._t; BaseSettingController.include({ @@ -33,4 +40,34 @@ BaseSettingController.include({ }, }); +const WebsiteCookiesbarField = FieldBoolean.extend({ + xmlDependencies: ['/website/static/src/xml/website.res_config_settings.xml'], + + _onChange: function () { + const checked = this.$input[0].checked; + if (!checked) { + return this._setValue(checked); + } + + const cancelCallback = () => this.$input[0].checked = !checked; + Dialog.confirm(this, null, { + title: _t("Please confirm"), + $content: QWeb.render('website.res_config_settings.cookies_modal_main'), + buttons: [{ + text: 'Do not activate', + classes: 'btn-primary', + close: true, + click: cancelCallback, + }, + { + text: 'Activate anyway', + close: true, + click: () => this._setValue(checked), + }], + cancel_callback: cancelCallback, + }); + }, +}); + +fieldRegistry.add('website_cookiesbar_field', WebsiteCookiesbarField); }); diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 9765bc57473..0ef07ccc12e 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -1,6 +1,7 @@ odoo.define('website.editor.snippets.options', function (require) { 'use strict'; +require('website.s_popup_options'); var core = require('web.core'); var Dialog = require('web.Dialog'); const wUtils = require('website.utils'); @@ -913,6 +914,63 @@ options.registry.anchor = options.Class.extend({ }, }); +options.registry.CookiesBar = options.registry.SnippetPopup.extend({ + xmlDependencies: (options.registry.SnippetPopup.prototype.xmlDependencies || []).concat( + ['/website/static/src/xml/website.cookies_bar.xml'] + ), + + //-------------------------------------------------------------------------- + // Options + //-------------------------------------------------------------------------- + + /** + * Change the cookies bar layout. + * + * @see this.selectClass for parameters + */ + selectLayout: function (previewMode, widgetValue, params) { + let websiteId; + this.trigger_up('context_get', { + callback: function (ctx) { + websiteId = ctx['website_id']; + }, + }); + + const $template = $(qweb.render(`website.cookies_bar.${widgetValue}`, { + websiteId: websiteId, + })); + + const $content = this.$target.find('.s_popup_content'); + const selectorsToKeep = [ + '.o_cookies_bar_text_button', + '.o_cookies_bar_text_policy', + '.o_cookies_bar_text_title', + '.o_cookies_bar_text_primary', + '.o_cookies_bar_text_secondary', + ]; + + if (this.$savedSelectors === undefined) { + this.$savedSelectors = []; + } + + for (const selector of selectorsToKeep) { + const $currentLayoutEls = $content.find(selector).contents(); + const $newLayoutEl = $template.find(selector); + if ($currentLayoutEls.length) { + // save value before change, eg 'title' is not inside 'discrete' template + // but we want to preserve it in case of select another layout later + this.$savedSelectors[selector] = $currentLayoutEls; + } + const $savedSelector = this.$savedSelectors[selector]; + if ($newLayoutEl.length && $savedSelector && $savedSelector.length) { + $newLayoutEl.empty().append($savedSelector); + } + } + + $content.empty().append($template); + }, +}); + /** * Allows edition of 'cover_properties' in website models which have such * fields (blogs, posts, events, ...). diff --git a/addons/website/static/src/snippets/s_popup/000.js b/addons/website/static/src/snippets/s_popup/000.js index 0e7983002f0..16820dcc988 100644 --- a/addons/website/static/src/snippets/s_popup/000.js +++ b/addons/website/static/src/snippets/s_popup/000.js @@ -8,14 +8,14 @@ const utils = require('web.utils'); const PopupWidget = publicWidget.Widget.extend({ selector: '.s_popup', events: { - 'click .s_popup_close': '_onCloseClick', + 'click .js_close_popup': '_onCloseClick', }, /** * @override */ start: function () { - if (!utils.get_cookie(this.$target.attr('id'))) { + if (!utils.get_cookie(this.$el.attr('id'))) { this._bindPopup(); } return this._super(...arguments); @@ -77,8 +77,8 @@ const PopupWidget = publicWidget.Widget.extend({ * @private */ _onCloseClick: function () { - const nbDays = this.$target.find('.s_popup_main').data('consentsDelay'); - utils.set_cookie(this.$target.attr('id'), true, nbDays * 24 * 60 * 60); + const nbDays = this.$el.find('.s_popup_main').data('consentsDuration'); + utils.set_cookie(this.$el.attr('id'), true, nbDays * 24 * 60 * 60); this._hidePopup(); }, }); diff --git a/addons/website/static/src/snippets/s_popup/000.scss b/addons/website/static/src/snippets/s_popup/000.scss index bb14c100322..71566512868 100644 --- a/addons/website/static/src/snippets/s_popup/000.scss +++ b/addons/website/static/src/snippets/s_popup/000.scss @@ -1,7 +1,8 @@ // s_popup .s_popup_main { .s_popup_content { - min-height: var(--o-we-toolbar-height); + // keep lower than <p> height (cookies bar) + min-height: $o-font-size-base * $o-line-height-base; box-shadow: $modal-content-box-shadow-sm-up; .container { // keep margin when fixed bottom diff --git a/addons/website/static/src/snippets/s_popup/options.js b/addons/website/static/src/snippets/s_popup/options.js index 4c43041c614..842cc284c83 100644 --- a/addons/website/static/src/snippets/s_popup/options.js +++ b/addons/website/static/src/snippets/s_popup/options.js @@ -8,7 +8,10 @@ options.registry.SnippetPopup = options.Class.extend({ * @override */ start: function () { - this.$target.find('.s_popup_close').on('click', () => { + // Note: the link are excluded here so that internal modal buttons do + // not close the popup as we want to allow edition of those buttons. + this.$target.find('.js_close_popup:not(a, .btn)').on('click', ev => { + ev.stopPropagation(); this.onTargetHide(); this.trigger_up('snippet_option_visibility_update', {show: false}); }); diff --git a/addons/website/static/src/xml/website.cookies_bar.xml b/addons/website/static/src/xml/website.cookies_bar.xml new file mode 100644 index 00000000000..8f43ccb3698 --- /dev/null +++ b/addons/website/static/src/xml/website.cookies_bar.xml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> + <t t-name="website.cookies_bar.text_title"> + <div class="o_cookies_bar_text_title"> + <p>Respecting your privacy is our priority.</p> + </div> + </t> + <t t-name="website.cookies_bar.text_primary"> + <div class="o_cookies_bar_text_primary"> + We use cookies to provide you a better user experience. + </div> + </t> + <t t-name="website.cookies_bar.text_secondary"> + <div class="o_cookies_bar_text_secondary"> + We use them to store info about your habits on our website. It will helps us to provide you the very best experience and customize what you see. + <br/> + By clicking on this banner, you give us permission to collect data. + </div> + </t> + + <t t-name="website.cookies_bar.discrete"> + <section class="pt4 pb4"> + <div class="container text-600 d-flex align-items-center"> + <div class="mb0"> + <t t-call="website.cookies_bar.text_primary"/> + </div> + <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link btn-sm text-nowrap ml-auto">Cookie Policy</a> + <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-sm text-nowrap">I agree</a> + </div> + </section> + </t> + <t t-name="website.cookies_bar.classic"> + <section class="pt24 pb24"> + <div class="container text-600 d-flex align-items-center"> + <div> + <div class="h3 text-900"> + <t t-call="website.cookies_bar.text_title"/> + </div> + <div class="small"> + <t t-call="website.cookies_bar.text_primary"/> + </div> + <div class="small"> + <t t-call="website.cookies_bar.text_secondary"/> + </div> + </div> + <div class="ml-auto"> + <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-block text-nowrap">I agree</a> + <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link btn-sm text-nowrap">Cookie Policy</a> + </div> + </div> + </section> + </t> + <t t-name="website.cookies_bar.popup"> + <section class="p-5"> + <div class="container text-800 text-center"> + <img t-attf-src="/web/image/website/#{websiteId}/logo/250x250" class="img img-fluid" alt="Website Logo"/> + <br/><br/> + <div class="h3"> + <t t-call="website.cookies_bar.text_title"/> + </div> + <br/> + <div class="mb0 text-left"> + <t t-call="website.cookies_bar.text_primary"/> + </div> + <div class="text-left"> + <t t-call="website.cookies_bar.text_secondary"/> + </div> + <br/> + <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-lg">Cookie Policy</a> + <br/> + <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link">I agree</a> + </div> + </section> + </t> +</templates> diff --git a/addons/website/static/src/xml/website.res_config_settings.xml b/addons/website/static/src/xml/website.res_config_settings.xml new file mode 100644 index 00000000000..6b6d48172bd --- /dev/null +++ b/addons/website/static/src/xml/website.res_config_settings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<templates id="template" xml:space="preserve"> +<t t-name="website.res_config_settings.cookies_modal_main"> + <main role="alert"> + <p> + <b>Cookie bars may significantly impair the experience</b> of + your visitors. We recommend you avoid them unless you have + verified with a legal advisor that you absolutely need cookie + consent in your country. + </p> + <p> + For session cookies, authentification and analytics*, + <b>you do not need to ask for the consent</b> (see e.g. Opinion + 04/2012 on Cookie Consent Exemption by the EU Art.29 WP). + </p> + <p> + * provided that your analytics is anonymized, which is not the + case by default with Google Analytics. + </p> + </main> +</t> +</templates> diff --git a/addons/website/views/res_config_settings_views.xml b/addons/website/views/res_config_settings_views.xml index 6a32d2b55a7..870eb8cd59e 100644 --- a/addons/website/views/res_config_settings_views.xml +++ b/addons/website/views/res_config_settings_views.xml @@ -127,7 +127,18 @@ </div> </div> </div> - + <div class="col-12 col-lg-6 o_setting_box" id="website_cookies_bar_setting"> + <div class="o_setting_left_pane"> + <field name="website_cookies_bar" widget="website_cookiesbar_field"/> + </div> + <div class="o_setting_right_pane"> + <label for="website_cookies_bar"/> + <span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/> + <div class="text-muted"> + Display a customizable cookies bar on your website. + </div> + </div> + </div> <div class="col-12 col-lg-6 o_setting_box" id="cdn_setting" title="A CDN helps you serve your website’s content with high availability and high performance to any visitor wherever they are located." groups="base.group_no_one"> <div class="o_setting_left_pane"> <field name="cdn_activated"/> diff --git a/addons/website/views/snippets/s_popup.xml b/addons/website/views/snippets/s_popup.xml index 3ca662e8ff6..ea0b13a1c14 100644 --- a/addons/website/views/snippets/s_popup.xml +++ b/addons/website/views/snippets/s_popup.xml @@ -4,10 +4,10 @@ <template id="s_popup" name="Popup"> <div class="s_popup o_snippet_invisible"> <div class='modal s_popup_main popup_backdrop s_popup_center o_one_page bg-black-25 ' - data-show-after="5000" data-display="afterDelay" data-consents-delay="7"> + data-show-after="5000" data-display="afterDelay" data-consents-duration="7"> <div class='modal-dialog modal-dialog-centered s_popup_frame modal-md'> <div class='oe_structure modal-content s_popup_content oe_img_bg oe_custom_bg' style="background-color: #FFFFFF"> - <div class='s_popup_close o_we_no_overlay o_not_editable'>&times;</div> + <div class='js_close_popup s_popup_close o_we_no_overlay o_not_editable'>&times;</div> <section class="s_banner parallax pt96 pb96"> <span class="s_parallax_bg oe_img_bg oe_custom_bg" style="background-image: url('/web/image/website.s_banner_default_image');"></span> <div class="container"> @@ -37,24 +37,27 @@ <div data-js="SnippetPopup" data-selector=".s_popup" data-target=".s_popup_main"> <we-select string="Position"> <we-button data-set-layout="modal" data-name="position_centered">Center</we-button> - <we-button data-set-layout="fixed">Bottom</we-button> + <we-button data-set-layout="fixed" data-name="position_bottom">Bottom</we-button> </we-select> <we-select string="Size" data-apply-to=".s_popup_frame"> <we-button data-select-class="modal-sm">Small</we-button> - <we-button data-select-class="modal-md">Medium</we-button> + <we-button data-select-class="modal-md" data-name="s_popup_size_md">Medium</we-button> <we-button data-select-class="modal-lg">Large</we-button> <we-button data-select-class="modal-xl">Big</we-button> - <we-button data-select-class="s_popup_full">Full</we-button> + <we-button data-select-class="s_popup_full" data-name="s_popup_size_full">Full</we-button> </we-select> <we-colorpicker string="Backdrop Color" data-select-style="true" data-css-property="background-color" data-color-prefix="bg-" data-dependencies="position_centered"/> + </div> + <div data-js="SnippetPopup" data-selector=".s_popup" data-exclude="#website_cookies_bar" data-target=".s_popup_main"> <we-colorpicker string="Text Color" data-select-style="true" data-css-property="color" data-color-prefix="text-"/> <we-select string="Display" data-attribute-name="display" data-attribute-default-value="always"> <we-button data-select-data-attribute="afterDelay" data-name="show_delay">Delay</we-button> <we-button data-select-data-attribute="mouseExit">On Exit</we-button> </we-select> <we-input string="Delay" data-select-data-attribute="" data-attribute-name="showAfter" data-unit="s" data-save-unit="ms" data-dependencies="show_delay"/> - <we-input string="Period between consents" data-select-data-attribute="7days" data-attribute-name="consentsDelay" data-unit="days"/> + <t t-set="unit_popup_duration">days</t> + <we-input string="Hide For" title="Once the user closes the popup, it won't be shown again for that period of time." t-attf-data-select-data-attribute="7#{unit_popup_duration}" data-attribute-name="consentsDuration" t-att-data-unit="unit_popup_duration"/> <we-select string="Show on" data-no-preview="true"> <we-button data-move-block="moveToBody">This page</we-button> <we-button data-move-block="moveToFooter">All pages</we-button> diff --git a/addons/website/views/snippets/snippets.xml b/addons/website/views/snippets/snippets.xml index 7838a0da9e5..3ef28a99e45 100644 --- a/addons/website/views/snippets/snippets.xml +++ b/addons/website/views/snippets/snippets.xml @@ -467,5 +467,14 @@ data-name="scroll_button_opt"/> </we-row> </div> + + <!-- Cookies Bar --> + <div data-selector="#website_cookies_bar" data-js="CookiesBar" data-target=".s_popup_main"> + <we-select string="Layout" class="o_we_inline"> + <we-button data-select-class="o_cookies_discrete" data-select-layout="discrete" data-trigger="position_bottom,s_popup_size_full">Discrete</we-button> + <we-button data-select-class="o_cookies_classic" data-select-layout="classic" data-trigger="position_bottom,s_popup_size_full">Classic</we-button> + <we-button data-select-class="o_cookies_popup" data-select-layout="popup" data-trigger="position_centered,s_popup_size_md">Popup</we-button> + </we-select> + </div> </template> </odoo> diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index b40c459e081..dd6092435dc 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -271,6 +271,31 @@ </xpath> </template> +<template id="cookies_bar" inherit_id="website.footer_custom" name="Cookies Bar"> + <xpath expr="//div[@id='footer']" position="before"> + <div id="website_cookies_bar" t-if="website.cookies_bar" class="s_popup o_snippet_invisible" data-name="Cookies Bar"> + <div class='s_popup_main s_popup_fixed popup_backdrop d-none o_cookies_discrete' + data-show-after="500" data-display="afterDelay" data-consents-duration="999"> + <div class='s_popup_frame s_popup_full'> + <div class='oe_structure s_popup_content bg-white'> + <section class="pt4 pb4"> + <div class="container text-600 d-flex align-items-center"> + <div class="mb0"> + <div class="o_cookies_bar_text_primary"> + We use cookies to provide you a better user experience. + </div> + </div> + <a href="/cookie-policy" class="o_cookies_bar_text_policy btn btn-link btn-sm text-nowrap ml-auto">Cookie Policy</a> + <a href="#" role="button" class="js_close_popup o_cookies_bar_text_button btn btn-primary btn-sm text-nowrap">I agree</a> + </div> + </section> + </div> + </div> + </div> + </div> + </xpath> +</template> + <template id="language_selector" name="Language Selector"> <ul class="js_language_selector mb0 list-inline" t-if="(request and request.is_frontend_multilang and len(languages) > 1) or (website and (editable or translatable))"> <li class="list-inline-item"> |
