[IMP] website_mass_mailing: add template selection to newsletter block snippet
PURPOSE This commit adds a template selection to the newsletter block snippet to allow one to switch between email, mobile (added with a new module) or form template. LINKS Task-2672194 Part-of: odoo/odoo#79582
This commit is contained in:
@@ -24,6 +24,7 @@ On a simple click, your visitors can subscribe to mailing lists managed in the E
|
||||
'website.assets_wysiwyg': [
|
||||
'website_mass_mailing/static/src/js/website_mass_mailing.editor.js',
|
||||
'website_mass_mailing/static/src/scss/website_mass_mailing_edit_mode.scss',
|
||||
'website_mass_mailing/static/src/snippets/s_popup/options.js',
|
||||
],
|
||||
'web.assets_tests': [
|
||||
'website_mass_mailing/static/tests/**/*',
|
||||
|
||||
@@ -8,43 +8,58 @@ from odoo.addons.mass_mailing.controllers import main
|
||||
|
||||
class MassMailController(main.MassMailController):
|
||||
|
||||
@route('/website_mass_mailing/is_subscriber', type='json', website=True, auth="public")
|
||||
def is_subscriber(self, list_id, **post):
|
||||
email = None
|
||||
if not request.env.user._is_public():
|
||||
email = request.env.user.email
|
||||
elif request.session.get('mass_mailing_email'):
|
||||
email = request.session['mass_mailing_email']
|
||||
|
||||
@route('/website_mass_mailing/is_subscriber', type='json', website=True, auth='public')
|
||||
def is_subscriber(self, list_id, subscription_type, **post):
|
||||
value = self._get_value(subscription_type)
|
||||
fname = self._get_fname(subscription_type)
|
||||
is_subscriber = False
|
||||
if email:
|
||||
contacts_count = request.env['mailing.contact.subscription'].sudo().search_count([('list_id', 'in', [int(list_id)]), ('contact_id.email', '=', email), ('opt_out', '=', False)])
|
||||
if value and fname:
|
||||
contacts_count = request.env['mailing.contact.subscription'].sudo().search_count(
|
||||
[('list_id', 'in', [int(list_id)]), (f'contact_id.{fname}', '=', value), ('opt_out', '=', False)])
|
||||
is_subscriber = contacts_count > 0
|
||||
|
||||
return {'is_subscriber': is_subscriber, 'email': email}
|
||||
return {'is_subscriber': is_subscriber, 'value': value}
|
||||
|
||||
@route('/website_mass_mailing/subscribe', type='json', website=True, auth="public")
|
||||
def subscribe(self, list_id, email, **post):
|
||||
def _get_value(self, subscription_type):
|
||||
value = None
|
||||
if subscription_type == 'email':
|
||||
if not request.env.user._is_public():
|
||||
value = request.env.user.email
|
||||
elif request.session.get('mass_mailing_email'):
|
||||
value = request.session['mass_mailing_email']
|
||||
return value
|
||||
|
||||
def _get_fname(self, subscription_type):
|
||||
return 'email' if subscription_type == 'email' else ''
|
||||
|
||||
@route('/website_mass_mailing/subscribe', type='json', website=True, auth='public')
|
||||
def subscribe(self, list_id, value, subscription_type, **post):
|
||||
if not request.env['ir.http']._verify_request_recaptcha_token('website_mass_mailing_subscribe'):
|
||||
return {
|
||||
'toast_type': 'danger',
|
||||
'toast_content': _("Suspicious activity detected by Google reCaptcha."),
|
||||
}
|
||||
|
||||
ContactSubscription = request.env['mailing.contact.subscription'].sudo()
|
||||
Contacts = request.env['mailing.contact'].sudo()
|
||||
name, email = Contacts.get_name_email(email)
|
||||
if subscription_type == 'email':
|
||||
name, value = Contacts.get_name_email(value)
|
||||
elif subscription_type == 'mobile':
|
||||
name = value
|
||||
|
||||
subscription = ContactSubscription.search([('list_id', '=', int(list_id)), ('contact_id.email', '=', email)], limit=1)
|
||||
fname = self._get_fname(subscription_type)
|
||||
subscription = ContactSubscription.search(
|
||||
[('list_id', '=', int(list_id)), (f'contact_id.{fname}', '=', value)], limit=1)
|
||||
if not subscription:
|
||||
# inline add_to_list as we've already called half of it
|
||||
contact_id = Contacts.search([('email', '=', email)], limit=1)
|
||||
contact_id = Contacts.search([(fname, '=', value)], limit=1)
|
||||
if not contact_id:
|
||||
contact_id = Contacts.create({'name': name, 'email': email})
|
||||
contact_id = Contacts.create({'name': name, fname: value})
|
||||
ContactSubscription.create({'contact_id': contact_id.id, 'list_id': int(list_id)})
|
||||
elif subscription.opt_out:
|
||||
subscription.opt_out = False
|
||||
# add email to session
|
||||
request.session['mass_mailing_email'] = email
|
||||
request.session[f'mass_mailing_{fname}'] = value
|
||||
return {
|
||||
'toast_type': 'success',
|
||||
'toast_content': _("Thanks for subscribing!"),
|
||||
|
||||
@@ -40,8 +40,10 @@ options.registry.mailing_list_subscribe = options.Class.extend({
|
||||
*/
|
||||
cleanForSave() {
|
||||
const previewClasses = ['o_disable_preview', 'o_enable_preview'];
|
||||
this.$target[0].querySelector('.js_subscribe_btn').classList.remove(...previewClasses);
|
||||
this.$target[0].querySelector('.js_subscribed_btn').classList.remove(...previewClasses);
|
||||
const subscribeBtn = this.$target[0].querySelector('.js_subscribe_btn');
|
||||
subscribeBtn && subscribeBtn.classList.remove(...previewClasses);
|
||||
const subscribedBtn = this.$target[0].querySelector('.js_subscribed_btn');
|
||||
subscribedBtn && subscribedBtn.classList.remove(...previewClasses);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -40,10 +40,12 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
return def;
|
||||
}
|
||||
const always = this._updateView.bind(this);
|
||||
const inputName = this.$target[0].querySelector('input').name;
|
||||
return Promise.all([def, this._rpc({
|
||||
route: '/website_mass_mailing/is_subscriber',
|
||||
params: {
|
||||
'list_id': this.$target.data('list-id'),
|
||||
'list_id': this._getListId(),
|
||||
'subscription_type': inputName,
|
||||
},
|
||||
}).then(always).guardedCatch(always)]);
|
||||
},
|
||||
@@ -68,11 +70,11 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
const isSubscriber = data.is_subscriber;
|
||||
const subscribeBtnEl = this.$target[0].querySelector('.js_subscribe_btn');
|
||||
const thanksBtnEl = this.$target[0].querySelector('.js_subscribed_btn');
|
||||
const emailInputEl = this.$target[0].querySelector('input.js_subscribe_email');
|
||||
const valueInputEl = this.$target[0].querySelector('input.js_subscribe_value');
|
||||
|
||||
subscribeBtnEl.disabled = isSubscriber;
|
||||
emailInputEl.value = data.email || '';
|
||||
emailInputEl.disabled = isSubscriber;
|
||||
valueInputEl.value = data.value || '';
|
||||
valueInputEl.disabled = isSubscriber;
|
||||
// Compat: remove d-none for DBs that have the button saved with it.
|
||||
this.$target[0].classList.remove('d-none');
|
||||
|
||||
@@ -80,6 +82,10 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
thanksBtnEl.classList.toggle('d-none', !isSubscriber);
|
||||
},
|
||||
|
||||
_getListId: function () {
|
||||
return this.$target.closest('[data-snippet=s_newsletter_block').data('list-id') || this.$target.data('list-id');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -89,9 +95,9 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
*/
|
||||
_onSubscribeClick: async function () {
|
||||
var self = this;
|
||||
var $email = this.$(".js_subscribe_email:visible");
|
||||
|
||||
if ($email.length && !$email.val().match(/.+@.+/)) {
|
||||
const inputName = this.$('input').attr('name');
|
||||
const $input = this.$(".js_subscribe_value:visible");
|
||||
if (inputName === 'email' && $input.length && !$input.val().match(/.+@.+/)) {
|
||||
this.$target.addClass('o_has_error').find('.form-control').addClass('is-invalid');
|
||||
return false;
|
||||
}
|
||||
@@ -109,8 +115,9 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
this._rpc({
|
||||
route: '/website_mass_mailing/subscribe',
|
||||
params: {
|
||||
'list_id': this.$target.data('list-id'),
|
||||
'email': $email.length ? $email.val() : false,
|
||||
'list_id': this._getListId(),
|
||||
'value': $input.length ? $input.val() : false,
|
||||
'subscription_type': inputName,
|
||||
recaptcha_token_response: tokenObj.token,
|
||||
},
|
||||
}).then(function (result) {
|
||||
@@ -118,7 +125,7 @@ publicWidget.registry.subscribe = publicWidget.Widget.extend({
|
||||
if (toastType === 'success') {
|
||||
self.$(".js_subscribe_btn").addClass('d-none');
|
||||
self.$(".js_subscribed_btn").removeClass('d-none');
|
||||
self.$('input.js_subscribe_email').prop('disabled', !!result);
|
||||
self.$('input.js_subscribe_value').prop('disabled', !!result);
|
||||
const $popup = self.$target.closest('.o_newsletter_modal');
|
||||
if ($popup.length) {
|
||||
$popup.modal('hide');
|
||||
|
||||
@@ -16,7 +16,7 @@ PopupWidget.include({
|
||||
_canShowPopup() {
|
||||
if (
|
||||
this.$el.is('.o_newsletter_popup') &&
|
||||
this.$el.find('input.js_subscribe_email').prop('disabled')
|
||||
this.$el.find('input.js_subscribe_value').prop('disabled')
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import options from 'web_editor.snippets.options';
|
||||
|
||||
options.registry.NewsletterLayout = options.registry.SelectTemplate.extend({
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
init() {
|
||||
this._super(...arguments);
|
||||
this.containerSelector = '> .container, > .container-fluid, > .o_container_small';
|
||||
this.selectTemplateWidgetName = 'newsletter_template_opt';
|
||||
},
|
||||
});
|
||||
@@ -14,7 +14,7 @@ wTourUtils.registerEditionTour('newsletter_block_edition', {
|
||||
}),
|
||||
{
|
||||
content: 'Wait for the list id to be set.',
|
||||
trigger: 'iframe .s_newsletter_subscribe_form[data-list-id]:not([data-list-id="0"])',
|
||||
trigger: 'iframe .s_newsletter_block[data-list-id]:not([data-list-id="0"]) .s_newsletter_subscribe_form',
|
||||
run: () => null, // it's a check
|
||||
},
|
||||
...wTourUtils.clickOnSave(),
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
</template>
|
||||
|
||||
<template id="s_newsletter_subscribe_form" name="Newsletter">
|
||||
<div class="s_newsletter_subscribe_form js_subscribe" data-vxml="001" data-list-id="0" data-name="Newsletter Form">
|
||||
<div class="s_newsletter_subscribe_form s_newsletter_list js_subscribe" data-vxml="001" data-list-id="0" data-name="Newsletter Form">
|
||||
<div class="input-group">
|
||||
<input type="email" name="email" class="js_subscribe_email form-control" placeholder="your email..."/>
|
||||
<input type="email" name="email" class="js_subscribe_value form-control" placeholder="your email..."/>
|
||||
<a role="button" href="#" class="btn btn-primary js_subscribe_btn o_submit">Subscribe</a>
|
||||
<a role="button" href="#" class="btn btn-success js_subscribed_btn d-none o_submit" disabled="disabled">Thanks</a>
|
||||
</div>
|
||||
@@ -35,13 +35,110 @@
|
||||
</template>
|
||||
|
||||
<template id="s_newsletter_block" name="Newsletter block">
|
||||
<section class="s_newsletter_block bg-200 pt32 pb32">
|
||||
<section class="s_newsletter_block s_newsletter_list pt32 pb32" data-list-id="0">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 offset-lg-2 pt24 pb24">
|
||||
<h2>Always First.</h2>
|
||||
<p>Be the first to find out all the latest news, products, and trends.</p>
|
||||
<t t-snippet-call="website_mass_mailing.s_newsletter_subscribe_form"/>
|
||||
<t t-call="website_mass_mailing.s_newsletter_block_default_template"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<template id="s_newsletter_block_default_template" groups="base.group_user">
|
||||
<div class="row">
|
||||
<div class="col-lg-8 offset-lg-2 pt24 pb24">
|
||||
<h2>Always First.</h2>
|
||||
<p>Be the first to find out all the latest news, products, and trends.</p>
|
||||
<t t-snippet-call="website_mass_mailing.s_newsletter_subscribe_form"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="s_newsletter_block_form_template" groups="base.group_user">
|
||||
<section class="s_website_form" data-vcss="001" data-snippet="s_website_form" data-name="Form">
|
||||
<div class="container">
|
||||
<form id="newsletter_form" action="/website/form/" method="post" enctype="multipart/form-data" class="o_mark_required"
|
||||
data-mark="*" data-model_name="mailing.contact" data-success-mode="message" hide-change-model="true">
|
||||
<div class="s_website_form_rows row s_col_no_bgcolor">
|
||||
<div class="mb-3 col-12 s_website_form_field s_website_form_model_required" data-type="char" data-name="Field">
|
||||
<div class="row s_col_no_resize s_col_no_bgcolor">
|
||||
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 250px" for="mailing_sub1">
|
||||
<span class="s_website_form_label_content">Your Name</span>
|
||||
<span class="s_website_form_mark"> *</span>
|
||||
</label>
|
||||
<div class="col-sm">
|
||||
<input id="mailing_sub1" type="text" class="form-control s_website_form_input" name="name" required="1"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 col-12 s_website_form_field s_website_form_model_required" data-type="email" data-name="Field">
|
||||
<div class="row s_col_no_resize s_col_no_bgcolor">
|
||||
<label class="col-form-label col-sm-auto s_website_form_label" style="width: 250px" for="mailing_sub2">
|
||||
<span class="s_website_form_label_content">Your Email</span>
|
||||
<span class="s_website_form_mark"> *</span>
|
||||
</label>
|
||||
<div class="col-sm">
|
||||
<input id="mailing_sub2" type='email' class='form-control s_website_form_input' name="email"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 col-12 s_website_form_field s_website_form_model_required" data-type="many2many" data-name="Field">
|
||||
<div class="row s_col_no_resize s_col_no_bgcolor">
|
||||
<label class="col-sm-auto s_website_form_label" style="width: 250px" for="mailing_list_">
|
||||
<span class="s_website_form_label_content">Subscribe to</span>
|
||||
<span class="s_website_form_mark"> *</span>
|
||||
</label>
|
||||
<div class="col-sm">
|
||||
<div class="row s_col_no_resize s_col_no_bgcolor s_website_form_multiple" data-name="list_ids" data-display="horizontal">
|
||||
<t t-foreach="request.env['mailing.list'].search([('is_public', '=', True)])" t-as="record">
|
||||
<div class="checkbox col-12 col-lg-4 col-md-6">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="s_website_form_input form-check-input" name="list_ids"
|
||||
t-attf-id="mailing_list_#{record.id}" t-att-value="record.id" required="1"/>
|
||||
<label class="form-check-label s_website_form_check_label" t-attf-for="mailing_list_#{record.id}">
|
||||
<t t-esc="record.display_name"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 col-12 s_website_form_field s_website_form_custom s_website_form_required" data-type="boolean" data-name="Field">
|
||||
<div class="row s_col_no_resize s_col_no_bgcolor">
|
||||
<label class="col-sm-auto s_website_form_label" style="width: 250px;" for="mailing_sub3">
|
||||
<span class="s_website_form_label_content">I agree to receive updates</span>
|
||||
<span class="s_website_form_mark"> *</span>
|
||||
</label>
|
||||
<div class="col-sm">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" value="Yes" class="s_website_form_input" name="I want to be kept updated"
|
||||
id="mailing_sub3" required="1"/>
|
||||
</div>
|
||||
<div class="s_website_form_field_description small form-text text-muted">
|
||||
We send one weekly newsletter per list and always try to keep it interesting. You can unsubscribe at any time.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3 col-12 s_website_form_submit" data-name="Submit Button">
|
||||
<div style="width: 250px;" class="s_website_form_label"/>
|
||||
<a href="#" role="button" class="btn btn-primary btn-lg s_website_form_send">Subscribe</a>
|
||||
<span id="s_website_form_result"></span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="s_website_form_end_message d-none">
|
||||
<div class="oe_structure">
|
||||
<section class="s_text_block pt64 pb64 o_colored_level o_cc o_cc2" data-snippet="s_text_block">
|
||||
<div class="container">
|
||||
<h2 class="text-center"><span class="fa fa-check-circle"></span>
|
||||
Thank you for subscribing !
|
||||
</h2>
|
||||
<p class="text-center">
|
||||
You will now be informed about the latest news.<br/>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -81,7 +178,20 @@
|
||||
|
||||
<template id="newsletter_subscribe_options" name="Newsletter Subscribe Options" inherit_id="website.snippet_options">
|
||||
<xpath expr="//*[@t-set='so_snippet_addition_selector']" position="inside">, .o_newsletter_popup</xpath>
|
||||
<xpath expr="//div[last()]" position="after">
|
||||
<xpath expr="//div[1]" position="before">
|
||||
<div data-js="NewsletterLayout" data-selector=".s_newsletter_block">
|
||||
<we-select string="Template"
|
||||
data-name="newsletter_template_opt"
|
||||
data-attribute-name="newsletterTemplate"
|
||||
data-attribute-default-value="email">
|
||||
<we-button title="Email Subscription" string="Email Subscription"
|
||||
data-select-template="website_mass_mailing.s_newsletter_block_default_template"
|
||||
data-select-data-attribute="email" data-name="email_opt"/>
|
||||
<we-button title="Form Subscription" string="Form Subscription"
|
||||
data-select-template="website_mass_mailing.s_newsletter_block_form_template"
|
||||
data-select-data-attribute="form" data-name="form_opt"/>
|
||||
</we-select>
|
||||
</div>
|
||||
<t t-call="website_mass_mailing.newsletter_subscribe_options_common">
|
||||
<t t-set="_selector">.o_newsletter_popup</t>
|
||||
<t t-set="_target">.s_newsletter_list</t>
|
||||
@@ -99,7 +209,7 @@
|
||||
t-att-data-selector="_selector"
|
||||
t-att-data-exclude="_exclude"
|
||||
t-att-data-target="_target">
|
||||
<we-select string="Newsletter" data-attribute-name="listId"></we-select>
|
||||
<we-select string="Newsletter" data-attribute-name="listId" data-dependencies="!form_opt"></we-select>
|
||||
</div>
|
||||
<div data-js="recaptchaSubscribe"
|
||||
t-att-data-selector="_selector"
|
||||
|
||||
Reference in New Issue
Block a user