[IMP] website: propose a new social media snippet

This commit introduces a new social_media snippet that allows social
networks to be displayed. This snippet shares the same options as the
share snippet, but also provides a list to edit the URLs of the social
networks in the company data (social_facebook, ...). This list also
allows to manage links to custom social networks (which are not stored
in the DB).

Headers and footers now use this new social_media snippet instead of the
share snippet and in the settings, the urls to the DB social networks
are editable/visible only in developer mode.

task-2687447

closes odoo/odoo#80217

Signed-off-by: Romain Derie (rde) <rde@odoo.com>
Co-authored-by: Guillaume (gdi) <gdi@odoo.com>
Co-authored-by: Romain Derie <rde@odoo.com>
This commit is contained in:
Guillaume (gdi)
2022-01-16 23:36:46 +00:00
committed by Romain Derie
co-authored by Romain Derie
parent 3dde03308d
commit 8f7c6997e8
11 changed files with 590 additions and 85 deletions
+1 -1
View File
@@ -380,7 +380,7 @@
<!-- Replace a media -->
<!-- TODO probably review this system once the new editor is merged to not duplicate the selector, etc -->
<div data-js="ReplaceMedia" data-selector="img, .media_iframe_video, span.fa, i.fa">
<div data-js="ReplaceMedia" data-selector="img, .media_iframe_video, span.fa, i.fa" data-exclude="a[href^='/website/social/'] > i.fa">
<we-row string="Media">
<we-button class="o_we_bg_brand_primary" data-replace-media="true" data-no-preview="true">Replace</we-button>
</we-row>
+2
View File
@@ -50,6 +50,7 @@
'views/snippets/s_alert.xml',
'views/snippets/s_card.xml',
'views/snippets/s_share.xml',
'views/snippets/s_social_media.xml',
'views/snippets/s_rating.xml',
'views/snippets/s_hr.xml',
'views/snippets/s_facebook_page.xml',
@@ -205,6 +206,7 @@
'website/static/src/snippets/s_embed_code/options.js',
'website/static/src/snippets/s_website_form/options.js',
'website/static/src/snippets/s_searchbar/options.js',
'website/static/src/snippets/s_social_media/options.js',
'website/static/src/snippets/s_process_steps/options.js',
'website/static/src/js/editor/wysiwyg.js',
'website/static/src/js/editor/widget_link.js',
@@ -0,0 +1,65 @@
.s_social_media {
> * {
display: inline-block;
vertical-align: middle;
}
.s_social_media_title {
margin: 0 .4rem 0 0;
}
a {
i.fa {
display: flex;
justify-content: center;
align-items: center;
}
margin: .2rem;
}
&:not(.no_icon_color) {
.s_social_media_facebook {
&, &:hover, &:focus {
@extend .text-facebook;
}
}
.s_social_media_twitter {
&, &:hover, &:focus {
@extend .text-twitter;
}
}
.s_social_media_linkedin {
&, &:hover, &:focus {
@extend .text-linkedin;
}
}
.s_social_media_google {
&, &:hover, &:focus {
@extend .text-google-plus;
}
}
.s_social_media_whatsapp {
&, &:hover, &:focus {
@extend .text-whatsapp;
}
}
.s_social_media_pinterest {
&, &:hover, &:focus {
@extend .text-pinterest;
}
}
.s_social_media_github {
&, &:hover, &:focus {
@extend .text-github;
}
}
.s_social_media_instagram {
&, &:hover, &:focus {
@extend .text-instagram;
}
}
.s_social_media_youtube {
&, &:hover, &:focus {
@extend .text-youtube;
}
}
}
}
@@ -0,0 +1,192 @@
/** @odoo-module **/
import fonts from 'wysiwyg.fonts';
import {generateHTMLId} from 'web_editor.utils';
import options from 'web_editor.snippets.options';
options.registry.SocialMedia = options.Class.extend({
/**
* @override
*/
async willStart() {
this.$target[0].querySelectorAll(':scope > a').forEach(el => el.setAttribute('id', generateHTMLId(30)));
await this._super(...arguments);
let websiteId;
this.trigger_up('context_get', {
callback: function (ctx) {
websiteId = ctx['website_id'];
},
});
// Fetch URLs for db links.
[this.dbSocialValues] = await this._rpc({
model: 'website',
method: 'read',
args: [websiteId, ['social_facebook', 'social_twitter', 'social_youtube',
'social_instagram', 'social_linkedin', 'social_github']],
});
delete this.dbSocialValues.id;
},
/**
* @override
*/
async cleanForSave() {
this.$target[0].querySelectorAll(':scope > a').forEach(el => el.removeAttribute('id'));
// Update the DB links.
let websiteId;
this.trigger_up('context_get', {
callback: function (ctx) {
websiteId = ctx['website_id'];
},
});
this._rpc({
model: 'website',
method: 'write',
args: [[websiteId], this.dbSocialValues],
});
},
//--------------------------------------------------------------------------
// Options
//--------------------------------------------------------------------------
/**
* Applies the we-list on the target and rebuilds the social links.
*
* @see this.selectClass for parameters
*/
async renderListItems(previewMode, widgetValue, params) {
const entries = JSON.parse(widgetValue);
// Handle element deletation.
const entriesIds = entries.map(entry => entry.id);
const anchorsEls = this.$target[0].querySelectorAll(':scope > a');
const deletedEl = Array.from(anchorsEls).find(aEl => !entriesIds.includes(aEl.id));
if (deletedEl) {
deletedEl.remove();
}
for (const entry of entries) {
let anchorEl = this.$target[0].querySelector(`#${entry.id}`);
if (!anchorEl) {
// It's a new social media.
anchorEl = this.$target[0].querySelector(':scope > a').cloneNode(true);
anchorEl.href = '#';
anchorEl.setAttribute('id', entry.id);
}
// Handle visibility of the link
anchorEl.classList.toggle('d-none', !entry.selected);
const dbField = anchorEl.href.split('/website/social/')[1];
if (dbField) {
// Handle URL change for DB links.
this.dbSocialValues['social_' + dbField] = entry.display_name;
} else {
// Handle URL change for custom links.
const href = anchorEl.getAttribute('href');
if (href !== entry.display_name) {
if (this._isValidURL(entry.display_name)) {
// Propose an icon only for valid URLs (no mailto).
const socialMedia = this._findRelevantSocialMedia(entry.display_name);
// Remove social media social media classes
let regx = new RegExp('\\b' + "s_social_media_" + '[^1-9][^ ]*[ ]?\\b', 'g');
anchorEl.className = anchorEl.className.replace(regx, '');
// Remove every fa classes except fa-x sizes
const iEl = anchorEl.querySelector('i');
regx = new RegExp('\\b' + "fa-" + '[^1-9][^ ]*[ ]?\\b', 'g');
iEl.className = iEl.className.replace(regx, '');
if (socialMedia) {
anchorEl.classList.add(`s_social_media_${socialMedia}`);
iEl.classList.add(`fa-${socialMedia}`);
} else {
iEl.classList.add(`fa-pencil`);
}
}
anchorEl.setAttribute('href', entry.display_name);
}
}
// Place the link at the correct position
this.$target[0].appendChild(anchorEl);
}
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @override
*/
_computeWidgetState: function (methodName, params) {
if (methodName !== 'renderListItems') {
return this._super(methodName, params);
}
const listEntries = [];
for (const anchorEl of this.$target[0].querySelectorAll(':scope > a')) {
const dbField = anchorEl.href.split('/website/social/')[1];
const entry = {
id: anchorEl.id,
selected: !anchorEl.classList.contains('d-none'),
display_name: dbField ? this.dbSocialValues['social_' + dbField] : anchorEl.getAttribute('href'),
undeletable: Boolean(dbField),
placeholder: `https://${dbField || 'example'}.com/yourPage`,
};
listEntries.push(entry);
}
return JSON.stringify(listEntries);
},
/**
* Finds the social network for the given url.
*
* @param {String} url
* @return {String} The social network to which the url leads to.
*/
_findRelevantSocialMedia(url) {
const supportedSocialMedia = [
['facebook', /^(https?:\/\/)(www\.)?(facebook|fb|m\.facebook)\.(com|me)\/.+$/gm],
['twitter', /^(https?:\/\/)((www\.)?twitter\.com)\/.+$/gm],
['youtube', /^(https?:\/\/)(www\.)?(youtube.com|youtu.be)\/.+$/gm],
['instagram', /^(https?:\/\/)(www\.)?(instagram.com|instagr.am|instagr.com)\/.+$/gm],
['linkedin', /^(https?:\/\/)((www\.)?linkedin\.com)\/.+$/gm],
['github', /^(https?:\/\/)((www\.)?github\.com)\/.+$/gm],
];
for (const [socialMedia, regex] of supportedSocialMedia) {
if (regex.test(url)) {
return socialMedia;
}
}
// Check if an icon matches the URL domain
try {
const domain = new URL(url).hostname.split('.').slice(-2)[0];
fonts.computeFonts();
return fonts.fontIcons[0].alias.find(el => el.includes(domain)).split('fa-').pop();
} catch (error) {
return false;
}
},
/**
* @param {String} str
* @returns {boolean} is the string a valid URL.
*/
_isValidURL(str) {
try {
new URL(str);
} catch (error) {
return false;
}
return true;
},
/**
* @override
*/
_renderCustomXML(uiFragment) {
const anchorEls = this.$target[0].querySelectorAll(':scope > a:not(.d-none)');
uiFragment.querySelector('we-list').dataset.defaults = JSON.stringify(
Array.from(anchorEls).map(el => el.id)
);
}
});
export default {
SocialMedia: options.registry.SocialMedia,
};
@@ -0,0 +1,113 @@
/** @odoo-module */
import tour from 'web_tour.tour';
import wTourUtils from 'website.tour_utils';
tour.register('snippet_social_media', {
test: true,
url: '/?enable_editor=1',
}, [
wTourUtils.dragNDrop({id: 's_social_media', name: 'Social Media'}),
wTourUtils.clickOnSnippet({id: 's_social_media', name: 'Social Media'}),
{
content: 'Click on Add New Social Network',
trigger: 'we-list we-button.o_we_list_add_optional',
},
{
content: 'Change added Option label',
trigger: 'we-list table input:eq(6)',
run: 'text https://www.youtu.be/y7TlnAv6cto',
},
{
content: 'Click on the toggle to hide Facebook',
trigger: 'we-list table we-button.o_we_user_value_widget',
run: 'click',
},
{
content: 'Drag the facebook link at the end of the list',
trigger: 'we-list table we-button.o_we_drag_handle',
position: 'bottom',
run: "drag_and_drop we-list table tr:last-child",
},
// Create a Link for which we don't have an icon to propose.
{
content: 'Click on Add New Social Network',
trigger: 'we-list we-button.o_we_list_add_optional',
},
{
content: 'Change added Option label (2)',
trigger: 'we-list table input:eq(7)',
run: 'text https://whatever.it/1EdSw9X',
},
// Create a custom instagram link.
{
content: 'Click on Add New Social Network',
trigger: 'we-list we-button.o_we_list_add_optional',
},
{
content: 'Change added Option label (3)',
trigger: 'we-list table input:eq(8)',
run: 'text https://instagr.am/odoo.official/',
},
{
content: "Check if the result is correct before removing",
trigger: ".s_social_media" +
":has(a:eq(0)[href='/website/social/twitter'])" +
":has(a:eq(1)[href='/website/social/linkedin'])" +
":has(a:eq(2)[href='/website/social/youtube'])" +
":has(a:eq(3)[href='/website/social/instagram'])" +
":has(a:eq(4)[href='/website/social/github'])" +
":has(a:eq(5)[href='https://www.youtu.be/y7TlnAv6cto']:has(i.fa-youtube))" +
":has(a:eq(6)[href='/website/social/facebook'].d-none)" +
":has(a:eq(7)[href='https://whatever.it/1EdSw9X']:has(i.fa-pencil))" +
":has(a:eq(8)[href='https://instagr.am/odoo.official/']:has(i.fa-instagram))",
},
// Create a custom link, not officially supported, ensure icon is found.
{
content: 'Change custom social to unsupported link',
trigger: 'we-list table input:eq(5)',
run: 'text https://www.paypal.com/abc',
},
{
content: "Ensure paypal icon is found",
trigger: ".s_social_media" +
":has(a:eq(5)[href='https://www.paypal.com/abc']:has(i.fa-paypal))",
},
{
content: 'Delete the custom link',
trigger: 'we-list we-button.o_we_select_remove_option',
run: 'click',
},
{
content: 'Click on the toggle to show Facebook',
trigger: 'we-list table we-button.o_we_user_value_widget:not(.active)',
run: 'click',
},
{
content: "Check if the result is correct after removing",
trigger: ".s_social_media" +
":has(a:eq(0)[href='/website/social/twitter'])" +
":has(a:eq(1)[href='/website/social/linkedin'])" +
":has(a:eq(2)[href='/website/social/youtube'])" +
":has(a:eq(3)[href='/website/social/instagram'])" +
":has(a:eq(4)[href='/website/social/github'])" +
":has(a:eq(5)[href='/website/social/facebook'])" +
":has(a:eq(6)[href='https://whatever.it/1EdSw9X']:has(i.fa-pencil))" +
":has(a:eq(7)[href='https://instagr.am/odoo.official/']:has(i.fa-instagram))",
},
{
content: 'Change url of the DB instagram link',
trigger: 'we-list table input:eq(3)',
run: 'text https://instagram.com/odoo.official/',
},
{
content: 'Save',
trigger: 'button[data-action=save]',
run: 'click',
},
{
content: "Wait until save's calls are finished",
trigger: "body:not(.editor_enable)",
run: function () {}, // it's a check
}
]);
+8
View File
@@ -30,3 +30,11 @@ class TestSnippets(HttpCase):
def test_04_countdown_preview(self):
self.start_tour("/?enable_editor=1", "snippet_countdown", login='admin')
def test_05_social_media(self):
self.start_tour("/?enable_editor=1", 'snippet_social_media', login="admin")
self.assertEqual(
self.env['website'].browse(1).social_instagram,
'https://instagram.com/odoo.official/',
'Social media should have been updated'
)
@@ -165,7 +165,7 @@
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="social_media_settings">
<div class="col-12 col-lg-6 o_setting_box" id="social_media_settings" groups="base.group_no_one">
<div class="o_setting_left_pane">
<field name="has_social_network"/>
</div>
+3 -2
View File
@@ -27,8 +27,9 @@
<template id="s_share_options" inherit_id="website.snippet_options">
<xpath expr="." position="inside">
<div data-selector=".s_share">
<we-select string="Title Position" data-apply-to=".s_share_title">
<!-- TODO: Now that it is shared with social media, move elsewhere? -->
<div data-selector=".s_share, .s_social_media">
<we-select string="Title Position" data-apply-to=".s_share_title, .s_social_media_title">
<we-button data-select-class="d-block">Top</we-button>
<we-button data-select-class="">Left</we-button>
<we-button data-select-class="d-none">None</we-button>
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_social_media" name="Social Media">
<div class="s_social_media text-left o_not_editable" contenteditable="false">
<h4 class="s_social_media_title d-none" contenteditable="true">Social Media</h4>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook rounded shadow-sm"/>
</a>
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter rounded shadow-sm"/>
</a>
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin rounded shadow-sm"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube" target="_blank">
<i class="fa fa-youtube rounded shadow-sm"/>
</a>
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram rounded shadow-sm"/>
</a>
<a href="/website/social/github" class="s_social_media_github" target="_blank">
<i class="fa fa-github rounded shadow-sm"/>
</a>
</div>
</template>
<template id="s_social_media_options" inherit_id="website.snippet_options">
<xpath expr="." position="inside">
<div data-js="SocialMedia" data-selector=".s_social_media">
<we-list string="Social Networks" data-add-item-title="Add New Social Network"
data-render-list-items="" data-has-default="multiple"
data-default-value="https://www.example.com" data-id-mode="name"
data-generate-id-for-new-items= "true" data-new-elements-toggled="true"/>
</div>
</xpath>
</template>
<record id="website.s_social_media_000_scss" model="ir.asset">
<field name="name">SocialMedia 000 SCSS</field>
<field name="bundle">web.assets_frontend</field>
<field name="path">website/static/src/snippets/s_social_media/000.scss</field>
</record>
</odoo>
+3 -2
View File
@@ -139,6 +139,7 @@
</t>
<t t-snippet="website.s_card" t-thumbnail="/website/static/src/img/snippets_thumbs/s_card.svg"/>
<t t-snippet="website.s_share" t-thumbnail="/website/static/src/img/snippets_thumbs/s_share.svg"/>
<t t-snippet="website.s_social_media" t-thumbnail="/website/static/src/img/snippets_thumbs/s_facebook_page.svg"/> <!-- TODO replace by new thumbnail-->
<t t-snippet="website.s_searchbar_input" t-thumbnail="/website/static/src/img/snippets_thumbs/s_searchbar_inline.svg"/>
<t id="mass_mailing_newsletter_hook"/>
<t t-snippet="website.s_text_highlight" t-thumbnail="/website/static/src/img/snippets_thumbs/s_text_highlight.svg"/>
@@ -354,7 +355,7 @@
</div>
<!-- H-ALIGN -->
<div id="so_text_align" data-selector=".s_share, .s_text_highlight">
<div id="so_text_align" data-selector=".s_share, .s_text_highlight, .s_social_media">
<we-button-group string="Alignment">
<we-button class="fa fa-fw fa-align-left" title="Left" data-select-class="text-left"/>
<we-button class="fa fa-fw fa-align-center" title="Center" data-select-class="text-center"/>
@@ -530,7 +531,7 @@
<!-- /!\ drop-in here is partly duplicated for s_popup (see dedicated options) -->
<!-- TODO should be improved -->
<t t-set="so_content_addition_selector" t-translation="off">blockquote, .s_card:not(.s_timeline_card), .s_alert, .o_facebook_page, .s_share, .s_rating, .s_hr, .s_google_map, .s_map, .s_countdown, .s_chart, .s_text_highlight, .s_progress_bar, .s_badge, .s_embed_code, .s_donation</t>
<t t-set="so_content_addition_selector" t-translation="off">blockquote, .s_card:not(.s_timeline_card), .s_alert, .o_facebook_page, .s_share, .s_social_media, .s_rating, .s_hr, .s_google_map, .s_map, .s_countdown, .s_chart, .s_text_highlight, .s_progress_bar, .s_badge, .s_embed_code, .s_donation</t>
<div id="so_content_addition"
t-att-data-selector="so_content_addition_selector"
t-attf-data-drop-near="p, h1, h2, h3, ul, ol, .row > div > img, #{so_content_addition_selector}"
+157 -79
View File
@@ -393,20 +393,26 @@
</div>
<!-- Social -->
<div class="col-lg-6 pb16">
<div class="s_share text-left no_icon_color" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Follow us</h5>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media text-left no_icon_color" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow us</h5>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook m-1"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter m-1"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram m-1"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-youtube m-1"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-github m-1"/>
</a>
</div>
</div>
<!-- Contact -->
@@ -515,20 +521,26 @@
<div class="oe_structure oe_structure_solo" id="oe_structure_header_vertical_1">
<section class="s_text_block" data-snippet="s_text_block" data-name="Text">
<div class="container">
<div class="s_share no_icon_color" data-snippet="s_share" data-name="Social Media">
<h6 class="s_share_title d-none">Follow us</h6>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media no_icon_color" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h6 class="s_social_media_title d-none" contenteditable="true">Follow us</h6>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook m-1"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter m-1"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram m-1"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-youtube m-1"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-github m-1"/>
</a>
</div>
</div>
</section>
@@ -641,20 +653,26 @@
<section class="s_text_block" data-snippet="s_text_block" data-name="Text">
<div class="container">
<!-- Social -->
<div class="s_share mt-3" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Follow us</h5>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media mt-3" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow us</h5>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook rounded-circle shadow-sm"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter rounded-circle shadow-sm"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin rounded-circle shadow-sm"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram rounded-circle shadow-sm"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-youtube rounded-circle shadow-sm"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-github rounded-circle shadow-sm"/>
</a>
</div>
<!-- Separator -->
<div class="s_hr text-left pt16 pb16" data-name="Separator">
@@ -836,24 +854,24 @@
</small>
</div>
<div class="col-lg-4 text-lg-right">
<div class="s_share no_icon_color" data-snippet="s_share" data-name="Social Media">
<small class="s_share_title text-muted d-none"><b>Follow us</b></small>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media no_icon_color" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<small class="s_social_media_title text-muted d-none" contenteditable="true"><b>Follow us</b></small>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook m-1"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter m-1"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin m-1"/>
</a>
<a href="/website/social/github" class="s_share_github" target="_blank">
<a href="/website/social/github" class="s_social_media_github" target="_blank">
<i class="fa fa-github m-1"/>
</a>
<a href="/website/social/youtube" class="s_share_youtube" target="_blank">
<a href="/website/social/youtube" class="s_social_media_youtube" target="_blank">
<i class="fa fa-youtube m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram m-1"/>
</a>
</div>
@@ -929,17 +947,26 @@
<div class="oe_structure oe_structure_solo" id="oe_structure_header_boxed_1">
<section class="s_text_block" data-snippet="s_text_block" name="Text">
<div class="container">
<div class="s_share text-left" data-snippet="s_share" data-name="Social Media">
<h6 class="s_share_title d-none">Follow us</h6>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media text-left" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h6 class="s_social_media_title d-none" contenteditable="true">Follow us</h6>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook m-1"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_linkedin" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram m-1"/>
</a>
<a href="/website/social/linkedin" class="s_social_media_linkedin d-none" target="_blank">
<i class="fa fa-linkedin m-1"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-youtube m-1"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-github m-1"/>
</a>
</div>
</div>
</section>
@@ -1123,24 +1150,24 @@
<div class="s_hr pt32 pb32" data-snippet="s_hr" data-name="Separator">
<hr class="w-100 mx-auto" style="border-top-width: 1px; border-top-style: solid; border-color: var(--400);"/>
</div>
<div class="s_share text-center" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Follow us</h5>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media text-center" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow us</h5>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook rounded-circle shadow-sm"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter rounded-circle shadow-sm"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin rounded-circle shadow-sm"/>
</a>
<a href="/website/social/github" class="s_share_github" target="_blank">
<a href="/website/social/github" class="s_social_media_github" target="_blank">
<i class="fa fa-github rounded-circle shadow-sm"/>
</a>
<a href="/website/social/youtube" class="s_share_youtube" target="_blank">
<a href="/website/social/youtube" class="s_social_media_youtube" target="_blank">
<i class="fa fa-youtube rounded-circle shadow-sm"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram rounded-circle shadow-sm"/>
</a>
</div>
@@ -1212,24 +1239,24 @@
<p class="mb-0"><small>We help you grow your business</small></p>
</div>
<div class="col-lg-4 text-lg-right pt16">
<div class="s_share no_icon_color" data-snippet="s_share" data-name="Social Media">
<small class="s_share_title d-none"><b>Follow us</b></small>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media no_icon_color" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<small class="s_social_media_title d-none" contenteditable="true"><b>Follow us</b></small>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook m-1"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter m-1"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin m-1"/>
</a>
<a href="/website/social/github" class="s_share_github" target="_blank">
<a href="/website/social/github" class="s_social_media_github" target="_blank">
<i class="fa fa-github m-1"/>
</a>
<a href="/website/social/youtube" class="s_share_youtube" target="_blank">
<a href="/website/social/youtube" class="s_social_media_youtube" target="_blank">
<i class="fa fa-youtube m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram m-1"/>
</a>
<a href="mailto:info@yourcompany.example.com" class="ml-3" target="_blank">
@@ -1410,18 +1437,27 @@
<li><i class="fa fa-envelope fa-fw mr-2"/><span><a href="mailto:info@yourcompany.example.com">info@yourcompany.example.com</a></span></li>
<li><i class="fa fa-phone fa-fw mr-2"/><span class="o_force_ltr"><a href="tel:+1 (650) 555-0111">+1 (650) 555-0111</a></span></li>
</ul>
<div class="s_share text-left" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Follow us</h5>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media text-left" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow us</h5>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook rounded-circle shadow-sm"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter rounded-circle shadow-sm"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin rounded-circle shadow-sm"/>
</a>
<a href="/" class="text-800 float-right">
<a href="/website/social/instagram" class="s_social_media_instagram d-none" target="_blank">
<i class="fa fa-instagram rounded-circle shadow-sm"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-youtube rounded-circle shadow-sm"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-github rounded-circle shadow-sm"/>
</a>
<a href="/" class="text-800">
<i class="fa fa-home rounded-circle shadow-sm"/>
</a>
</div>
@@ -1455,20 +1491,26 @@
<li><i class="fa fa-phone fa-fw mr-2"/><span class="o_force_ltr"><a href="tel:+1 (650) 555-0111">+1 (650) 555-0111</a></span></li>
<li><i class="fa fa-envelope fa-fw mr-2"/><span><a href="mailto:hello@mycompany.com">hello@mycompany.com</a></span></li>
</ul>
<div class="s_share text-left no_icon_color" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Follow us</h5>
<a href="/website/social/github" class="s_share_github" target="_blank">
<div class="s_social_media text-left no_icon_color" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow us</h5>
<a href="/website/social/github" class="s_social_media_github" target="_blank">
<i class="fa fa-2x fa-github m-1"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-2x fa-twitter m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-2x fa-instagram m-1"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-2x fa-linkedin m-1"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-2x fa-youtube m-1"/>
</a>
<a href="/website/social/facebook" class="s_social_media_facebook d-none" target="_blank">
<i class="fa fa-2x fa-facebook m-1"/>
</a>
</div>
</div>
</div>
@@ -1483,17 +1525,26 @@
<div id="footer" class="oe_structure oe_structure_solo" t-ignore="true" t-if="not no_footer">
<section class="s_text_block pt32" data-snippet="s_text_block" data-name="Text">
<div class="container s_allow_columns">
<div class="s_share text-center mb-4" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Follow us</h5>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media text-center mb-4" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow us</h5>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-facebook rounded-circle rounded shadow-sm"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter rounded-circle rounded shadow-sm"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin rounded-circle rounded shadow-sm"/>
</a>
<a href="/website/social/instagram" class="s_social_media_instagram d-none" target="_blank">
<i class="fa fa-instagram rounded-circle rounded shadow-sm"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-youtube rounded-circle rounded shadow-sm"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-github rounded-circle rounded shadow-sm"/>
</a>
</div>
<p class="text-center mb-1">250 Executive Park Blvd, Suite 3400 • San Francisco CA 94134 • United States</p>
<ul class="list-inline text-center">
@@ -1596,17 +1647,26 @@
</ul>
</div>
<div class="col-lg-3 pt16 pb16">
<div class="s_share text-right no_icon_color" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Follow us</h5>
<a href="/website/social/github" class="s_share_github" target="_blank">
<div class="s_social_media text-right no_icon_color" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow us</h5>
<a href="/website/social/github" class="s_social_media_github" target="_blank">
<i class="fa fa-2x fa-github m-1"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-2x fa-twitter m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-2x fa-instagram m-1"/>
</a>
<a href="/website/social/facebook" class="s_social_media_facebook d-none" target="_blank">
<i class="fa fa-2x fa-facebook m-1"/>
</a>
<a href="/website/social/linkedin" class="s_social_media_linkedin d-none" target="_blank">
<i class="fa fa-2x fa-linkedin m-1"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-2x fa-youtube m-1"/>
</a>
</div>
</div>
<div class="col-lg-2 pt16 pb16">
@@ -1638,17 +1698,26 @@
<h5><a href="mailto:hello@mycompany.com">hello@mycompany.com</a></h5>
</div>
<div class="col-lg-3 pt16 pb16">
<div class="s_share text-right no_icon_color" data-snippet="s_share" data-name="Social Media">
<p class="s_share_title d-block mb-2">Follow us</p>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<div class="s_social_media text-right no_icon_color" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<p class="s_social_media_title d-block mb-2" contenteditable="true">Follow us</p>
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-twitter m-1"/>
</a>
<a href="/website/social/linkedin" class="s_share_linkedin" target="_blank">
<a href="/website/social/linkedin" class="s_social_media_linkedin" target="_blank">
<i class="fa fa-linkedin m-1"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-instagram m-1"/>
</a>
<a href="/website/social/facebook" class="s_social_media_facebook d-none" target="_blank">
<i class="fa fa-facebook m-1"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-github m-1"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-youtube m-1"/>
</a>
</div>
</div>
</div>
@@ -1768,17 +1837,26 @@
</ul>
</div>
<div class="col-lg-3 pb24">
<div class="s_share text-right" data-snippet="s_share" data-name="Social Media">
<h5 class="s_share_title d-none">Share</h5>
<a href="/website/social/facebook" class="s_share_facebook" target="_blank">
<div class="s_social_media text-right" data-snippet="s_social_media" data-name="Social Media" contenteditable="false">
<h5 class="s_social_media_title d-none" contenteditable="true">Follow Us</h5>
<a href="/website/social/facebook" class="s_social_media_facebook" target="_blank">
<i class="fa fa-1x fa-facebook rounded-circle shadow-sm"/>
</a>
<a href="/website/social/twitter" class="s_share_twitter" target="_blank">
<a href="/website/social/twitter" class="s_social_media_twitter" target="_blank">
<i class="fa fa-1x fa-twitter rounded-circle shadow-sm"/>
</a>
<a href="/website/social/instagram" class="s_share_instagram" target="_blank">
<a href="/website/social/instagram" class="s_social_media_instagram" target="_blank">
<i class="fa fa-1x fa-instagram rounded-circle shadow-sm"/>
</a>
<a href="/website/social/youtube" class="s_social_media_youtube d-none" target="_blank">
<i class="fa fa-1x fa-youtube rounded-circle shadow-sm"/>
</a>
<a href="/website/social/linkedin" class="s_social_media_linkedin d-none" target="_blank">
<i class="fa fa-1x fa-linkedin rounded-circle shadow-sm"/>
</a>
<a href="/website/social/github" class="s_social_media_github d-none" target="_blank">
<i class="fa fa-1x fa-github rounded-circle shadow-sm"/>
</a>
</div>
</div>
</div>