diff --git a/public/language/en-GB/admin/appearance/customise.json b/public/language/en-GB/admin/appearance/customise.json
index 3b6a7f1795..147ef37bb4 100644
--- a/public/language/en-GB/admin/appearance/customise.json
+++ b/public/language/en-GB/admin/appearance/customise.json
@@ -13,5 +13,8 @@
"custom-header.enable": "Enable Custom Header",
"custom-css.livereload": "Enable Live Reload",
- "custom-css.livereload.description": "Enable this to force all sessions on every device under your account to refresh whenever you click save"
+ "custom-css.livereload.description": "Enable this to force all sessions on every device under your account to refresh whenever you click save",
+ "bsvariables": "_variables.scss",
+ "bsvariables.description": "Override bootstrap variables here. You can also use a tool like bootstrap.build and paste the output here.
Changes require a rebuild & restart.",
+ "bsvariables.enable": "Enable _variables.scss"
}
\ No newline at end of file
diff --git a/public/src/admin/appearance/customise.js b/public/src/admin/appearance/customise.js
index 31a156cf3b..f7be05ae0f 100644
--- a/public/src/admin/appearance/customise.js
+++ b/public/src/admin/appearance/customise.js
@@ -8,10 +8,12 @@ define('admin/appearance/customise', ['admin/settings', 'ace/ace'], function (Se
$('#customCSS').text($('#customCSS-holder').val());
$('#customJS').text($('#customJS-holder').val());
$('#customHTML').text($('#customHTML-holder').val());
+ $('#customVariables').text($('#customVariables-holder').val());
initACE('customCSS', 'scss', '#customCSS-holder');
initACE('customJS', 'javascript', '#customJS-holder');
initACE('customHTML', 'html', '#customHTML-holder');
+ initACE('customVariables', 'scss', '#customVariables-holder');
$('#save').on('click', function () {
if ($('#enableLiveReload').is(':checked')) {
diff --git a/src/meta/css.js b/src/meta/css.js
index 65d2ff7b0f..3396e6edd3 100644
--- a/src/meta/css.js
+++ b/src/meta/css.js
@@ -48,9 +48,11 @@ const buildImports = {
function boostrapImport(themeData) {
// see https://getbootstrap.com/docs/5.0/customize/sass/#variable-defaults
// for an explanation of this order and https://bootswatch.com/help/
- const { bootswatchSkin } = themeData;
+ const { bootswatchSkin, bsVariables } = themeData;
return [
- bootswatchSkin ? `@import "bootswatch/dist/${bootswatchSkin}/variables";` : '',
+ bootswatchSkin ?
+ `@import "bootswatch/dist/${bootswatchSkin}/variables";` :
+ bsVariables,
'@import "bootstrap/scss/mixins/banner";',
'@include bsBanner("");',
// functions must be included first
@@ -179,12 +181,16 @@ async function getBundleMetadata(target) {
let themeData = null;
if (target === 'client') {
- themeData = await db.getObjectFields('config', ['theme:type', 'theme:id']);
+ themeData = await db.getObjectFields('config', ['theme:type', 'theme:id', 'useBSVariables', 'bsVariables']);
const themeId = (themeData['theme:id'] || 'nodebb-theme-harmony');
- const baseThemePath = path.join(nconf.get('themes_path'), (themeData['theme:type'] && themeData['theme:type'] === 'local' ? themeId : 'nodebb-theme-harmony'));
+ const baseThemePath = path.join(
+ nconf.get('themes_path'),
+ (themeData['theme:type'] && themeData['theme:type'] === 'local' ? themeId : 'nodebb-theme-harmony')
+ );
+ console.log(themeData);
paths.unshift(baseThemePath);
paths.unshift(`${baseThemePath}/node_modules`);
-
+ themeData.bsVariables = parseInt(themeData.useBSVariables, 10) === 1 ? (themeData.bsVariables || '') : '';
themeData.bootswatchSkin = skin;
}
diff --git a/src/meta/minifier.js b/src/meta/minifier.js
index f12144ae5c..ee72906f9e 100644
--- a/src/meta/minifier.js
+++ b/src/meta/minifier.js
@@ -158,10 +158,16 @@ Minifier.js.bundle = async function (data, fork) {
};
actions.buildCSS = async function buildCSS(data) {
- const scssOutput = await sass.compileStringAsync(data.source, {
- loadPaths: data.paths,
- });
- let css = scssOutput.css.toString();
+ let css = '';
+ try {
+ const scssOutput = await sass.compileStringAsync(data.source, {
+ loadPaths: data.paths,
+ });
+ css = scssOutput.css.toString();
+ } catch (err) {
+ winston.error(err.stack);
+ }
+
async function processScss(direction) {
if (direction === 'rtl') {
diff --git a/src/views/admin/appearance/customise.tpl b/src/views/admin/appearance/customise.tpl
index 94bdbfb989..84cca3a868 100644
--- a/src/views/admin/appearance/customise.tpl
+++ b/src/views/admin/appearance/customise.tpl
@@ -1,11 +1,12 @@