diff --git a/addons/theme_bootswatch/models/theme_bootswatch.py b/addons/theme_bootswatch/models/theme_bootswatch.py index bf238666044793c2f09b16c2abe795a6207f06f5..77a7c5770636906a838b7ae1be75738f5bb7e5b5 100644 --- a/addons/theme_bootswatch/models/theme_bootswatch.py +++ b/addons/theme_bootswatch/models/theme_bootswatch.py @@ -1,5 +1,6 @@ from odoo import models + class ThemeBootswatch(models.AbstractModel): _inherit = 'theme.utils' diff --git a/addons/theme_default/models/theme_default.py b/addons/theme_default/models/theme_default.py index bcf9853bd9e9ddf9d12bdbb99604529ee996d19c..1fda54cb8aefa9af516d2315cc3ee467857d84e3 100644 --- a/addons/theme_default/models/theme_default.py +++ b/addons/theme_default/models/theme_default.py @@ -1,5 +1,6 @@ from odoo import models + class ThemeDefault(models.AbstractModel): _inherit = 'theme.utils' diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index e17a216e76296eb25fb8ef0540d2cf9907b41ddc..a1cca57919fbbd603304357bdca4588433f3c22c 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -369,10 +369,6 @@ class Website(Home): @http.route(['/website/make_scss_custo'], type='json', auth='user', website=True) def make_scss_custo(self, url, values): """ - Makes a scss customization of the given file. That file must - contain a scss map including a line comment containing the word 'hook', - to indicate the location where to write the new key,value pairs. - Params: url (str): the URL of the scss file to customize (supposed to be a variable @@ -382,24 +378,11 @@ class Website(Home): key,value mapping to integrate in the file's map (containing the word hook). If a key is already in the file's map, its value is overridden. - """ - AssetsUtils = request.env['web_editor.assets'] - - custom_url = AssetsUtils.make_custom_asset_file_url(url, 'web.assets_common') - updatedFileContent = AssetsUtils.get_asset_content(custom_url) or AssetsUtils.get_asset_content(url) - updatedFileContent = updatedFileContent.decode('utf-8') - for name, value in values.items(): - pattern = "'%s': %%s,\n" % name - regex = re.compile(pattern % ".+") - replacement = pattern % value - if regex.search(updatedFileContent): - updatedFileContent = re.sub(regex, replacement, updatedFileContent) - else: - updatedFileContent = re.sub(r'( *)(.*hook.*)', r'\1%s\1\2' % replacement, updatedFileContent) - # Bundle is 'assets_common' as this route is only meant to update - # variables scss files - AssetsUtils.save_asset(url, 'web.assets_common', updatedFileContent, 'scss') + Returns: + boolean + """ + request.env['web_editor.assets'].make_scss_customization(url, values) return True @http.route(['/website/multi_render'], type='json', auth="public", website=True) diff --git a/addons/website/models/assets.py b/addons/website/models/assets.py index c2a52588eaaaa492f58574be8c8b08f94310737c..1bbd653bd47f464659668aa2d59eb106abbb2f7a 100644 --- a/addons/website/models/assets.py +++ b/addons/website/models/assets.py @@ -1,12 +1,46 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import re + from odoo import models class Assets(models.AbstractModel): _inherit = 'web_editor.assets' + def make_scss_customization(self, url, values): + """ + Makes a scss customization of the given file. That file must + contain a scss map including a line comment containing the word 'hook', + to indicate the location where to write the new key,value pairs. + + Params: + url (str): + the URL of the scss file to customize (supposed to be a variable + file which will appear in the assets_common bundle) + + values (dict): + key,value mapping to integrate in the file's map (containing the + word hook). If a key is already in the file's map, its value is + overridden. + """ + custom_url = self.make_custom_asset_file_url(url, 'web.assets_common') + updatedFileContent = self.get_asset_content(custom_url) or self.get_asset_content(url) + updatedFileContent = updatedFileContent.decode('utf-8') + for name, value in values.items(): + pattern = "'%s': %%s,\n" % name + regex = re.compile(pattern % ".+") + replacement = pattern % value + if regex.search(updatedFileContent): + updatedFileContent = re.sub(regex, replacement, updatedFileContent) + else: + updatedFileContent = re.sub(r'( *)(.*hook.*)', r'\1%s\1\2' % replacement, updatedFileContent) + + # Bundle is 'assets_common' as this route is only meant to update + # variables scss files + self.save_asset(url, 'web.assets_common', updatedFileContent, 'scss') + def _get_custom_attachment(self, custom_url, op='='): """ See web_editor.Assets._get_custom_attachment diff --git a/addons/website/static/src/js/widgets/theme.js b/addons/website/static/src/js/widgets/theme.js index 43fe42588e1de576760c9d428aa10420bac5dd03..088ab1a83c0ae95e567938dac97a92725d967358 100644 --- a/addons/website/static/src/js/widgets/theme.js +++ b/addons/website/static/src/js/widgets/theme.js @@ -114,6 +114,8 @@ var ThemeCustomizeDialog = Dialog.extend({ events: { 'change .o_theme_customize_option_input': '_onChange', 'click .checked .o_theme_customize_option_input[type="radio"]': '_onChange', + 'click .o_theme_customize_add_google_font': '_onAddGoogleFontClick', + 'click .o_theme_customize_delete_google_font': '_onDeleteGoogleFontClick', }, CUSTOM_BODY_IMAGE_XML_ID: 'option_custom_body_image', @@ -129,6 +131,7 @@ var ThemeCustomizeDialog = Dialog.extend({ }, options)); this.defaultTab = options.tab || 0; + this.fontVariables = []; }, /** * @override @@ -159,6 +162,9 @@ var ThemeCustomizeDialog = Dialog.extend({ this.$modal.addClass('o_theme_customize_modal'); this.style = window.getComputedStyle(document.documentElement); + this.nbFonts = parseInt(this.style.getPropertyValue('--number-of-fonts')); + var googleFontsProperty = this.style.getPropertyValue('--google-fonts').trim(); + this.googleFonts = googleFontsProperty ? googleFontsProperty.split(/\s*,\s*/g) : []; var $tabs; var loadDef = this._loadViews().then(function (data) { @@ -325,17 +331,25 @@ var ThemeCustomizeDialog = Dialog.extend({ var xmlid = $item.data('xmlid'); var renderingOptions = _.extend({ - string: $item.attr('string') || data.names[xmlid.split(',')[0].trim()], + string: $item.attr('string') || xmlid && data.names[xmlid.split(',')[0].trim()], icon: $item.data('icon'), font: $item.data('font'), }, $item.data()); + var checked; + if (widgetName === 'auto') { + var propValue = self.style.getPropertyValue('--' + $item.data('variable')).trim(); + checked = (propValue === $item.attr('data-value')); + } else { + checked = (xmlid === undefined || xmlid && !_.difference(self._getXMLIDs($item), data.enabled).length); + } + // Build the options template $element = $(core.qweb.render('website.theme_customize_modal_option', _.extend({ alone: alone, - name: xmlid === undefined ? _.uniqueId('option-') : optionsName, + name: xmlid === undefined && widgetName !== 'auto' ? _.uniqueId('option-') : optionsName, id: $item.attr('id') || _.uniqueId('o_theme_customize_input_id_'), - checked: xmlid === undefined || xmlid && (!_.difference(self._getXMLIDs($item), data.enabled).length), + checked: checked, widget: widgetName, }, renderingOptions))); $element.find('input') @@ -370,6 +384,35 @@ var ThemeCustomizeDialog = Dialog.extend({ _processItems($item.children(), $element.find('.o_theme_customize_selection'), true); break; + case 'FONTSELECTION': + var $options = $(); + var variable = $item.data('variable'); + self.fontVariables.push(variable); + _.times(self.nbFonts, function (font) { + $options = $options.add($('<opt/>', { + 'data-widget': 'auto', + 'data-variable': variable, + 'data-value': font + 1, + 'data-font': font + 1, + })); + }); + $element = $(core.qweb.render('website.theme_customize_dropdown_option')); + var $selection = $element.find('.o_theme_customize_selection'); + _processItems($options, $selection, true); + + if (self.googleFonts.length) { + var $googleFontItems = $selection.children().slice(-self.googleFonts.length); + _.each($googleFontItems, function (el, index) { + $(el).append(core.qweb.render('website.theme_customize_delete_font', { + 'index': index, + })); + }); + } + $selection.append($(core.qweb.render('website.theme_customize_add_google_font_option', { + 'variable': variable, + }))); + break; + default: _processItems($item.children(), $container, false); return; @@ -428,6 +471,24 @@ var ThemeCustomizeDialog = Dialog.extend({ }); return xmlIDs; }, + /** + * @private + * @param {object} [values] + * When a new set of google fonts are saved, other variables + * potentially have to be adapted. + */ + _makeGoogleFontsCusto: function (values) { + values = values ? _.clone(values) : {}; + if (this.googleFonts.length) { + values['google-fonts'] = "('" + this.googleFonts.join("', '") + "')"; + } else { + values['google-fonts'] = 'null'; + } + return this._makeSCSSCusto('/website/static/src/scss/options/user_values.scss', values).then(function () { + window.location.hash = 'theme=true'; + window.location.reload(); + }); + }, /** * @private */ @@ -508,6 +569,16 @@ var ThemeCustomizeDialog = Dialog.extend({ return self._quickEdit($(inputData)); })); + // Handle auto changes + var $autoWidgetOptions = $options.has('.o_theme_customize_auto'); + if ($autoWidgetOptions.length > 1) { + $autoWidgetOptions = $autoWidgetOptions.has('input:checked'); + } + var $autosData = $autoWidgetOptions.find('.o_theme_customize_auto'); + defs = defs.concat(_.map($autosData, function (autoData) { + return self._setAuto($(autoData)); + })); + return Promise.all(defs); }, /** @@ -519,7 +590,7 @@ var ThemeCustomizeDialog = Dialog.extend({ var value = parseFloat(text) || ''; var unit = text.match(/([^\s\d]+)$/)[1]; - var def = new Promise(function (resolve, reject) { + return new Promise(function (resolve, reject) { var qEdit = new QuickEdit(self, value, unit); qEdit.on('QuickEdit:save', self, function (ev) { ev.stopPropagation(); @@ -531,15 +602,28 @@ var ThemeCustomizeDialog = Dialog.extend({ } var values = {}; - values[$inputData.data('value')] = value; + values[$inputData.data('variable')] = value; self._makeSCSSCusto('/website/static/src/scss/options/user_values.scss', values) .then(resolve) .guardedCatch(resolve); }); qEdit.appendTo($inputData.closest('.o_theme_customize_option')); }); + }, + /** + * @private + */ + _setAuto: function ($autoData) { + var self = this; + var values = {}; + var isChecked = $autoData.siblings('.o_theme_customize_option_input').prop('checked'); + values[$autoData.data('variable')] = isChecked ? $autoData.data('value') : 'null'; - return def; + return new Promise(function (resolve, reject) { + self._makeSCSSCusto('/website/static/src/scss/options/user_values.scss', values) + .then(resolve) + .guardedCatch(resolve); + }); }, /** * @private @@ -665,7 +749,7 @@ var ThemeCustomizeDialog = Dialog.extend({ }); _.each(this.$('.o_theme_customize_input'), function (el) { var $el = $(el); - var value = self.style.getPropertyValue('--' + $el.data('value')).trim(); + var value = self.style.getPropertyValue('--' + $el.data('variable')).trim(); // Convert rem values to px values if (_.str.endsWith(value, 'rem')) { @@ -692,7 +776,7 @@ var ThemeCustomizeDialog = Dialog.extend({ var $checked = $dropdown.find('label.checked'); $checked.closest('.dropdown-item').addClass('active'); - var classes = 'btn btn-light dropdown-toggle w-100 o_theme_customize_dropdown_btn'; + var classes = 'btn btn-light dropdown-toggle w-100 o_text_overflow o_theme_customize_dropdown_btn'; if ($checked.data('font-id')) { classes += _.str.sprintf(' o_theme_customize_option_font_%s', $checked.data('font-id')); } @@ -766,6 +850,73 @@ var ThemeCustomizeDialog = Dialog.extend({ self.$inputs.prop('disabled', false); }); }, + /** + * @private + */ + _onAddGoogleFontClick: function (ev) { + var self = this; + var variable = $(ev.currentTarget).data('variable'); + new Dialog(this, { + title: _t("Add a Google Font"), + $content: $(core.qweb.render('website.dialog.addGoogleFont')), + buttons: [ + { + text: _t("Save"), + classes: 'btn-primary', + click: function () { + var $input = this.$('.o_input_google_font'); + var m = $input.val().match(/\bfamily=([\w+]+)/); + if (!m) { + $input.addClass('is-invalid'); + return; + } + var font = m[1].replace(/\+/g, ' '); + self.googleFonts.push(font); + var values = {}; + values[variable] = self.nbFonts + 1; + return self._makeGoogleFontsCusto(values); + }, + }, + { + text: _t("Discard"), + close: true, + }, + ], + }).open(); + }, + /** + * @private + * @param {Event} ev + */ + _onDeleteGoogleFontClick: function (ev) { + var self = this; + ev.preventDefault(); + + var nbBaseFonts = this.nbFonts - this.googleFonts.length; + + // Remove Google font + var googleFontIndex = $(ev.currentTarget).data('fontIndex'); + this.googleFonts.splice(googleFontIndex, 1); + + // Adapt font variable indexes to the removal + var values = {}; + _.each(this.fontVariables, function (variable) { + var value = parseInt(self.style.getPropertyValue('--' + variable)); + var googleFontValue = nbBaseFonts + 1 + googleFontIndex; + if (value === googleFontValue) { + // If an element is using the google font being removed, reset + // it to the first base font. + values[variable] = 1; + } else if (value > googleFontValue) { + // If an element is using a google font whose index is higher + // than the one of the font being removed, that index must be + // lowered by 1 so that the font is unchanged. + values[variable] = value - 1; + } + }); + + return this._makeGoogleFontsCusto(values); + }, }); var ThemeCustomizeMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({ diff --git a/addons/website/static/src/scss/bootstrap_overridden.scss b/addons/website/static/src/scss/bootstrap_overridden.scss index 1dd53f6a7bf08dfb7bb8ba6c231084a560b517e3..011e16511f5c0bd7063b64b2c5985ee3118f1544 100644 --- a/addons/website/static/src/scss/bootstrap_overridden.scss +++ b/addons/website/static/src/scss/bootstrap_overridden.scss @@ -25,9 +25,9 @@ $body-color: palette-color('text') !default; // // Font, line-height, and color for body text, headings, and more. -$font-family-sans-serif: nth($o-theme-fonts, $o-theme-font-number) !default; +$font-family-sans-serif: $o-theme-font !default; -$headings-font-family: nth($o-theme-fonts, $o-theme-headings-font-number) !default; +$headings-font-family: $o-theme-headings-font !default; $headings-color: palette-color('h1') !default; // Jumbotron diff --git a/addons/website/static/src/scss/options/fonts/option_font_body_02_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_body_02_variables.scss deleted file mode 100644 index ab959cd7a6ddc2400fe7e529459b551d77a7baba..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_body_02_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-font-number: 2; diff --git a/addons/website/static/src/scss/options/fonts/option_font_body_03_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_body_03_variables.scss deleted file mode 100644 index 882e72a0b72cbf8ba12de70e1479c681d1e60092..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_body_03_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-font-number: 3; diff --git a/addons/website/static/src/scss/options/fonts/option_font_body_04_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_body_04_variables.scss deleted file mode 100644 index 5340d78012c96dbf0b6ce7c4ecdbd02521908e0c..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_body_04_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-font-number: 4; diff --git a/addons/website/static/src/scss/options/fonts/option_font_body_05_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_body_05_variables.scss deleted file mode 100644 index 31723e664c007aeacd5ea35e0c4ebab43955f9ef..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_body_05_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-font-number: 5; diff --git a/addons/website/static/src/scss/options/fonts/option_font_body_06_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_body_06_variables.scss deleted file mode 100644 index 66abf12c21c59eaa16a02cd6ea0ce143c9904857..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_body_06_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-font-number: 6; diff --git a/addons/website/static/src/scss/options/fonts/option_font_button_02_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_button_02_variables.scss deleted file mode 100644 index 2d804021980da9e83e2670a570e16013be34e08e..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_button_02_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-buttons-font-number: 2; diff --git a/addons/website/static/src/scss/options/fonts/option_font_button_03_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_button_03_variables.scss deleted file mode 100644 index 1c614fd35d0acc679ef1db04204060b0cbecf22b..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_button_03_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-buttons-font-number: 3; diff --git a/addons/website/static/src/scss/options/fonts/option_font_button_04_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_button_04_variables.scss deleted file mode 100644 index 8ef0852a1ff1d1b92664802d8246a55b195b6a84..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_button_04_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-buttons-font-number: 4; diff --git a/addons/website/static/src/scss/options/fonts/option_font_button_05_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_button_05_variables.scss deleted file mode 100644 index 0adadb1e9c46919dc8126b31990aca4fe34c1f7c..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_button_05_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-buttons-font-number: 5; diff --git a/addons/website/static/src/scss/options/fonts/option_font_button_06_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_button_06_variables.scss deleted file mode 100644 index fa00777d71642e1ca04b77595a6b5c0c3c258b38..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_button_06_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-buttons-font-number: 6; diff --git a/addons/website/static/src/scss/options/fonts/option_font_navbar_02_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_navbar_02_variables.scss deleted file mode 100644 index 45d8014b8eba0a7ddd56f62da66d428d6c2a83a0..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_navbar_02_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-navbar-font-number: 2; diff --git a/addons/website/static/src/scss/options/fonts/option_font_navbar_03_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_navbar_03_variables.scss deleted file mode 100644 index c46c2de11804fa9e646eda6d06bb5b82893e053b..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_navbar_03_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-navbar-font-number: 3; diff --git a/addons/website/static/src/scss/options/fonts/option_font_navbar_04_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_navbar_04_variables.scss deleted file mode 100644 index 69662acc7739843a12ff5161c233bb420f25c26a..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_navbar_04_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-navbar-font-number: 4; diff --git a/addons/website/static/src/scss/options/fonts/option_font_navbar_05_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_navbar_05_variables.scss deleted file mode 100644 index c96837086b5a631e913a7ae7b4e283716fb5c0a9..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_navbar_05_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-navbar-font-number: 5; diff --git a/addons/website/static/src/scss/options/fonts/option_font_navbar_06_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_navbar_06_variables.scss deleted file mode 100644 index 49ef9f8167c1a5c13a1555f61db219204bb5115f..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_navbar_06_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-navbar-font-number: 6; diff --git a/addons/website/static/src/scss/options/fonts/option_font_title_02_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_title_02_variables.scss deleted file mode 100644 index 690e1b1c3a64f384e9f9c059e8cfb117e780c6f8..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_title_02_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-headings-font-number: 2; diff --git a/addons/website/static/src/scss/options/fonts/option_font_title_03_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_title_03_variables.scss deleted file mode 100644 index c68022bb4da34c7b5baec1b50aca6bd1ba18c96f..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_title_03_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-headings-font-number: 3; diff --git a/addons/website/static/src/scss/options/fonts/option_font_title_04_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_title_04_variables.scss deleted file mode 100644 index 37b5a9b328fce27c1ab7db9feb5c0fba7157ead9..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_title_04_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-headings-font-number: 4; diff --git a/addons/website/static/src/scss/options/fonts/option_font_title_05_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_title_05_variables.scss deleted file mode 100644 index ca1848f61ed2045b7240ae4dec676ef5d1357267..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_title_05_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-headings-font-number: 5; diff --git a/addons/website/static/src/scss/options/fonts/option_font_title_06_variables.scss b/addons/website/static/src/scss/options/fonts/option_font_title_06_variables.scss deleted file mode 100644 index 572800b17ec74bb04e289f1c73e450c54981d46c..0000000000000000000000000000000000000000 --- a/addons/website/static/src/scss/options/fonts/option_font_title_06_variables.scss +++ /dev/null @@ -1 +0,0 @@ -$o-theme-headings-font-number: 6; diff --git a/addons/website/static/src/scss/primary_variables.scss b/addons/website/static/src/scss/primary_variables.scss index bb9d182756ab714e787cd92bcaddedcfb2576e82..e3d87ae98c4cfdebac9d48cb222f6f7866b95a9c 100644 --- a/addons/website/static/src/scss/primary_variables.scss +++ b/addons/website/static/src/scss/primary_variables.scss @@ -51,6 +51,11 @@ $o-website-values-palettes: ( ( 'logo-height': null, // Default to navbar height (see portal) 'header-font-size': null, // Default to BS (normal font-size) + 'font-number': 1, + 'headings-font-number': 1, + 'navbar-font-number': 1, + 'buttons-font-number': 1, + 'google-fonts': null, ), ) !default; $o-website-values-palette-number: 1 !default; @@ -87,7 +92,3 @@ $o-theme-font-names: ( 'Noto Serif', 'Arvo', ) !default; -$o-theme-font-number: 1 !default; -$o-theme-headings-font-number: 1 !default; -$o-theme-buttons-font-number: 1 !default; -$o-theme-navbar-font-number: 1 !default; diff --git a/addons/website/static/src/scss/secondary_variables.scss b/addons/website/static/src/scss/secondary_variables.scss index 168965c56f113144548c11b81969f265db2fd16a..5c2a9a53e1e33777c092d56a48e95adf6f1373e0 100644 --- a/addons/website/static/src/scss/secondary_variables.scss +++ b/addons/website/static/src/scss/secondary_variables.scss @@ -50,4 +50,16 @@ $o-website-values-palette-number: length($o-website-values-palettes); @return map-get($o-website-values, $key); } +@if o-website-value('google-fonts') { + $o-theme-font-names: join($o-theme-font-names, o-website-value('google-fonts')); + @each $font in o-website-value('google-fonts') { + $o-theme-fonts: append($o-theme-fonts, (quote($font), sans-serif)); + $o-theme-font-urls: append($o-theme-font-urls, quote($font) + ':400,400i,700,700i'); + } +} + $o-theme-navbar-logo-height: o-website-value('logo-height') !default; +$o-theme-font: nth($o-theme-fonts, o-website-value('font-number')) !default; +$o-theme-headings-font: nth($o-theme-fonts, o-website-value('headings-font-number')) !default; +$o-theme-navbar-font: nth($o-theme-fonts, o-website-value('navbar-font-number')) !default; +$o-theme-buttons-font: nth($o-theme-fonts, o-website-value('buttons-font-number')) !default; diff --git a/addons/website/static/src/scss/website.edit_mode.scss b/addons/website/static/src/scss/website.edit_mode.scss index 82da43caa9ad4b35622999df8266cbaeb1b9f108..3e6a960456a45f90d2a5ae735c166db725578cdb 100644 --- a/addons/website/static/src/scss/website.edit_mode.scss +++ b/addons/website/static/src/scss/website.edit_mode.scss @@ -51,7 +51,7 @@ .dropdown-menu { position: static !important; transform: none !important; - width: 100%; + min-width: 100%; } .o_theme_customize_option { @@ -195,6 +195,11 @@ } $i: $i + 1; } + + .o_theme_customize_delete_google_font { + @include o-position-absolute(1px, 1px, 1px, auto); + padding: 0 8px !important; + } } diff --git a/addons/website/static/src/scss/website.scss b/addons/website/static/src/scss/website.scss index 5fb20b332c811d8f7e96631b435b0af16c6ad850..1bda068be3f1409e3ce4f7700077e2b12f71dd48 100644 --- a/addons/website/static/src/scss/website.scss +++ b/addons/website/static/src/scss/website.scss @@ -4,10 +4,10 @@ $-seen: (); $-font-numbers: ( - $o-theme-font-number, - $o-theme-headings-font-number, - $o-theme-buttons-font-number, - $o-theme-navbar-font-number + o-website-value('font-number'), + o-website-value('headings-font-number'), + o-website-value('navbar-font-number'), + o-website-value('buttons-font-number'), ); @each $-number in $-font-numbers { @if index($-seen, $-number) == null { @@ -55,6 +55,7 @@ $-font-numbers: ( --h6: #{$-h6-color}; --logo-height: #{$o-theme-navbar-logo-height}; + --number-of-fonts: #{length($o-theme-fonts)}; } #wrapwrap { @@ -75,8 +76,8 @@ $-font-numbers: ( } .navbar { - @if ($o-theme-navbar-font-number != $o-theme-font-number) { - font-family: nth($o-theme-fonts, $o-theme-navbar-font-number); + @if ($o-theme-navbar-font != $o-theme-font) { + font-family: $o-theme-navbar-font; } .nav-item { @@ -154,8 +155,8 @@ h6 { color: color('h6'); } .btn { - @if ($o-theme-buttons-font-number != $o-theme-font-number) { - font-family: nth($o-theme-fonts, $o-theme-buttons-font-number); + @if ($o-theme-buttons-font != $o-theme-font) { + font-family: $o-theme-buttons-font; } } diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index f2e1465a7886b88e58a7e4d4559a328157d6e0e9..772ac73258fb73ac8da3e1f659b7407ac821add2 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -37,17 +37,30 @@ <div class="form-row justify-content-between o_options_container"/> </div> <t t-name="website.theme_customize_modal_option"> - <div t-attf-class="o_theme_customize_option my-1 flex-grow-0 #{font ? 'o_theme_customize_option_font_' + font : ''} #{widget ? 'o_theme_customize_with_widget' : ''}"> + <div t-attf-class="o_theme_customize_option my-1 flex-grow-0 #{font ? 'o_theme_customize_option_font_' + font : ''} #{widget and widget != 'auto' ? 'o_theme_customize_with_widget' : ''}"> <img t-if="icon" t-att-src="icon"/> <t t-set="label" t-value="font ? '' : string"/> - <t t-if="alone and !widget" t-call="website.components.switch"/> + <t t-if="alone and (!widget or widget == 'auto')" t-call="website.components.switch"/> <label t-else=""> <input t-att-id="id" t-att-name="name" type="radio" t-att-checked="checked ? 'checked' : undefined"/> <span><t t-esc="label"/></span> </label> </div> </t> + <t t-name="website.theme_customize_delete_font"> + <t t-set="delete_font_title">Delete this font</t> + <button type="button" + class="btn btn-link d-flex align-items-center text-danger fa fa-trash-o o_theme_customize_delete_google_font" + t-att-aria-label="delete_font_title" + t-att-title="delete_font_title" + t-att-data-font-index="index"/> + </t> + <t t-name="website.theme_customize_add_google_font_option"> + <a class="dropdown-item p-2 o_theme_customize_add_google_font" t-att-data-variable="variable" href="#"> + <i class="fa fa-plus"/> Add a Google Font + </a> + </t> <t t-name="website.theme_customize_dropdown_option"> <div t-attf-class="dropdown o_theme_customize_dropdown"> <div class="dropdown-menu rounded-0 o_theme_customize_selection" role="menu"/> @@ -59,13 +72,18 @@ t-att-data-color-type="colorType"/> </t> <t t-name="website.theme_customize_widget_input"> - <div t-attf-class="o_theme_customize_input o_theme_customize_input_#{value}" - t-att-data-value="value" + <div class="o_theme_customize_input" + t-att-data-variable="variable" t-att-data-unit="unit"> <i class="fa fa-edit"/> <span/> </div> </t> + <t t-name="website.theme_customize_widget_auto"> + <div class="o_theme_customize_auto" + t-att-data-variable="variable" + t-att-data-value="value"/> + </t> <t t-name="website.theme_customize_active_input"> <div class="input-group input-group-sm align-items-center o_theme_customize_active_input"> <input type="text" class="form-control" t-att-value="widget.value"/> @@ -103,4 +121,17 @@ </div> </div> </div> + <!-- Add a Google Font option dialog --> + <div t-name="website.dialog.addGoogleFont"> + <div class="form-group row"> + <label class="col-form-label col-md-3" for="google_font_html">Google Font HTML</label> + <div class="col-md-9"> + <textarea id="google_font_html" class="form-control o_input_google_font" + placeholder="<link href='https://fonts.googleapis.com/css?family=Bonbon&display=swap' rel='stylesheet'>" style="height: 100px;"/> + <span class="float-right text-muted"> + Select one font on <a target="_blank" href="https://fonts.google.com">fonts.google.com</a> and copy paste the embed code here. + </span> + </div> + </div> + </div> </templates> diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index 6b2d5eca73dae706542948c30dfd569d50ec6d5d..3025d7276cb05206e168d1e183cde707d94e5329 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -527,11 +527,11 @@ <list string="Main Layout"> <checkbox><opt data-xmlid="website.affix_top_menu" data-reload="/"/></checkbox> <checkbox><opt data-xmlid="portal.portal_show_sign_in" data-reload="/"/></checkbox> - <opt data-widget="input" data-unit="rem" data-value="header-font-size" string="Font Size"/> + <opt data-widget="input" data-unit="rem" data-variable="header-font-size" string="Font Size"/> </list> <list string="Logo"> <checkbox><opt data-xmlid="website.layout_logo_show" data-reload="/"/></checkbox> - <opt data-widget="input" data-unit="rem" data-value="logo-height" string="Logo Height"/> + <opt data-widget="input" data-unit="rem" data-variable="logo-height" string="Logo Height"/> </list> </content> @@ -551,44 +551,16 @@ <!-- Font options --> <content id="theme_customize_content_fonts" string="Fonts" title="Choose your fonts"> <list string="Title"> - <selection id="theme_customize_content_fonts_title"> - <opt data-xmlid="" data-font="1"/> - <opt data-xmlid="website.option_font_title_02_variables" data-font="2"/> - <opt data-xmlid="website.option_font_title_03_variables" data-font="3"/> - <opt data-xmlid="website.option_font_title_04_variables" data-font="4"/> - <opt data-xmlid="website.option_font_title_05_variables" data-font="5"/> - <opt data-xmlid="website.option_font_title_06_variables" data-font="6"/> - </selection> + <fontselection data-variable="headings-font-number"/> </list> <list string="Body"> - <selection id="theme_customize_content_fonts_body"> - <opt data-xmlid="" data-font="1"/> - <opt data-xmlid="website.option_font_body_02_variables" data-font="2"/> - <opt data-xmlid="website.option_font_body_03_variables" data-font="3"/> - <opt data-xmlid="website.option_font_body_04_variables" data-font="4"/> - <opt data-xmlid="website.option_font_body_05_variables" data-font="5"/> - <opt data-xmlid="website.option_font_body_06_variables" data-font="6"/> - </selection> + <fontselection data-variable="font-number"/> </list> <list string="Button"> - <selection id="theme_customize_content_fonts_button"> - <opt data-xmlid="" data-font="1"/> - <opt data-xmlid="website.option_font_button_02_variables" data-font="2"/> - <opt data-xmlid="website.option_font_button_03_variables" data-font="3"/> - <opt data-xmlid="website.option_font_button_04_variables" data-font="4"/> - <opt data-xmlid="website.option_font_button_05_variables" data-font="5"/> - <opt data-xmlid="website.option_font_button_06_variables" data-font="6"/> - </selection> + <fontselection data-variable="buttons-font-number"/> </list> <list string="Navbar"> - <selection id="theme_customize_content_fonts_navbar"> - <opt data-xmlid="" data-font="1"/> - <opt data-xmlid="website.option_font_navbar_02_variables" data-font="2"/> - <opt data-xmlid="website.option_font_navbar_03_variables" data-font="3"/> - <opt data-xmlid="website.option_font_navbar_04_variables" data-font="4"/> - <opt data-xmlid="website.option_font_navbar_05_variables" data-font="5"/> - <opt data-xmlid="website.option_font_navbar_06_variables" data-font="6"/> - </selection> + <fontselection data-variable="navbar-font-number"/> </list> </content> </div> @@ -615,116 +587,6 @@ </xpath> </template> -<!-- TODO use scss customization for fonts instead (like for user colors) --> - -<!-- Title font options --> -<template id="option_font_title_02_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_title_02_variables.scss"/> - </xpath> -</template> -<template id="option_font_title_03_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_title_03_variables.scss"/> - </xpath> -</template> -<template id="option_font_title_04_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_title_04_variables.scss"/> - </xpath> -</template> -<template id="option_font_title_05_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_title_05_variables.scss"/> - </xpath> -</template> -<template id="option_font_title_06_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_title_06_variables.scss"/> - </xpath> -</template> - -<!-- Body font options --> -<template id="option_font_body_02_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_body_02_variables.scss"/> - </xpath> -</template> -<template id="option_font_body_03_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_body_03_variables.scss"/> - </xpath> -</template> -<template id="option_font_body_04_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_body_04_variables.scss"/> - </xpath> -</template> -<template id="option_font_body_05_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_body_05_variables.scss"/> - </xpath> -</template> -<template id="option_font_body_06_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_body_06_variables.scss"/> - </xpath> -</template> - -<!-- Button font options --> -<template id="option_font_button_02_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_button_02_variables.scss"/> - </xpath> -</template> -<template id="option_font_button_03_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_button_03_variables.scss"/> - </xpath> -</template> -<template id="option_font_button_04_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_button_04_variables.scss"/> - </xpath> -</template> -<template id="option_font_button_05_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_button_05_variables.scss"/> - </xpath> -</template> -<template id="option_font_button_06_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_button_06_variables.scss"/> - </xpath> -</template> - -<!-- Navbar font options --> -<template id="option_font_navbar_02_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_navbar_02_variables.scss"/> - </xpath> -</template> -<template id="option_font_navbar_03_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_navbar_03_variables.scss"/> - </xpath> -</template> -<template id="option_font_navbar_04_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_navbar_04_variables.scss"/> - </xpath> -</template> -<template id="option_font_navbar_05_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_navbar_05_variables.scss"/> - </xpath> -</template> -<template id="option_font_navbar_06_variables" inherit_id="website._assets_primary_variables" active="False"> - <xpath expr="//link[last()]" position="after"> - <link rel="stylesheet" type="text/scss" href="/website/static/src/scss/options/fonts/option_font_navbar_06_variables.scss"/> - </xpath> -</template> - <template id="kanban"> <t t-set="step"><t t-esc="step or 0"/></t> <t t-set="scope"><t t-esc="scope or 0"/></t> diff --git a/addons/website_theme_install/models/theme_models.py b/addons/website_theme_install/models/theme_models.py index 20a30c9713a8cee81b9314bb0f18299ec41b1402..20105df25c128a8844d569bef0bc5dd42a7598b2 100644 --- a/addons/website_theme_install/models/theme_models.py +++ b/addons/website_theme_install/models/theme_models.py @@ -147,6 +147,18 @@ class Theme(models.AbstractModel): if not website: # remove optional website in master website = self.env['website'].get_current_website() + # Reinitialize font customizations + self.env['web_editor.assets'].make_scss_customization( + '/website/static/src/scss/options/user_values.scss', + { + 'font-number': 'null', + 'headings-font-number': 'null', + 'navbar-font-number': 'null', + 'buttons-font-number': 'null', + } + ) + + # Call specific theme post copy theme_post_copy = '_%s_post_copy' % mod.name if hasattr(self, theme_post_copy): _logger.info('Executing method %s' % theme_post_copy)