feat: add new tab to define bs variables

to override bootstrap vars.
dont crash if scss fails to compile, just use empty css and log the error, this allows accessing the acp if client scss has errors
isekai-main
Barış Soner Uşaklı 2 years ago
parent ddb41fbe5a
commit de68f7493d

@ -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 <a href=\"https://bootstrap.build/app\">bootstrap.build</a> and paste the output here.<br/>Changes require a rebuild & restart.",
"bsvariables.enable": "Enable _variables.scss"
}

@ -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')) {

@ -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;
}

@ -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') {

@ -1,11 +1,12 @@
<div class="tags d-flex flex-column gap-2 px-lg-4">
<div class="d-flex border-bottom py-2 m-0 sticky-top acp-page-main-header align-items-center justify-content-between flex-wrap gap-2">
<div class="d-flex flex-wrap gap-3">
<h4 class="fw-bold tracking-tight mb-0">[[admin/appearance/customise:customise]]</h4>
<ul class="nav nav-pills text-sm">
<li class="nav-item"><a class="nav-link active" href="#custom-css" data-bs-toggle="tab">[[admin/appearance/customise:custom-css]]</a></li>
<li class="nav-item"><a class="nav-link" href="#custom-js" data-bs-toggle="tab">[[admin/appearance/customise:custom-js]]</a></li>
<li class="nav-item"><a class="nav-link" href="#custom-header" data-bs-toggle="tab">[[admin/appearance/customise:custom-header]]</a></li>
<div class="d-flex flex-wrap gap-3 align-items-center">
<h4 class="fw-bold tracking-tight mb-1">[[admin/appearance/customise:customise]]</h4>
<ul class="nav nav-pills d-flex gap-1 text-sm">
<li class="nav-item"><a class="nav-link active px-2 py-1" href="#custom-css" data-bs-toggle="tab">[[admin/appearance/customise:custom-css]]</a></li>
<li class="nav-item"><a class="nav-link px-2 py-1" href="#custom-js" data-bs-toggle="tab">[[admin/appearance/customise:custom-js]]</a></li>
<li class="nav-item"><a class="nav-link px-2 py-1" href="#custom-header" data-bs-toggle="tab">[[admin/appearance/customise:custom-header]]</a></li>
<li class="nav-item"><a class="nav-link px-2 py-1" href="#bsvariables" data-bs-toggle="tab">[[admin/appearance/customise:bsvariables]]</a></li>
</ul>
</div>
<div class="d-flex align-items-center gap-1">
@ -24,7 +25,7 @@
<br />
<form class="form">
<div class="form-check">
<div class="form-check form-switch">
<input class="form-check-input" id="useCustomCSS" type="checkbox" data-field="useCustomCSS" />
<label class="form-check-label" for="useCustomCSS">[[admin/appearance/customise:custom-css.enable]]</label>
</div>
@ -40,7 +41,7 @@
<br />
<form class="form">
<div class="form-check">
<div class="form-check form-switch">
<input class="form-check-input" id="useCustomJS" type="checkbox" data-field="useCustomJS" />
<label class="form-check-label" for="useCustomJS">[[admin/appearance/customise:custom-js.enable]]</label>
</div>
@ -55,17 +56,37 @@
<div id="customHTML"></div>
<input type="hidden" id="customHTML-holder" value="" data-field="customHTML" />
<br />
<br/>
<form class="form">
<div class="form-check">
<div class="form-check form-switch">
<input class="form-check-input" id="useCustomHTML" type="checkbox" data-field="useCustomHTML" />
<label class="form-check-label" for="useCustomHTML">[[admin/appearance/customise:custom-header.enable]]</label>
</div>
</form>
</div>
<div class="tab-pane fade" id="bsvariables">
<p>
[[admin/appearance/customise:bsvariables.description]]
</p>
<div id="customVariables"></div>
<input type="hidden" id="customVariables-holder" value="" data-field="bsVariables" />
<br/>
<form class="form">
<div class="form-check form-switch">
<input class="form-check-input" id="useBSVariables" type="checkbox" data-field="useBSVariables" />
<label class="form-check-label" for="useBSVariables">[[admin/appearance/customise:bsvariables.enable]]</label>
</div>
</form>
</div>
<form class="form">
<div class="form-check">
<div class="form-check form-switch">
<input class="form-check-input" id="enableLiveReload" type="checkbox" data-field="enableLiveReload" checked />
<label class="form-check-label" for="enableLiveReload">[[admin/appearance/customise:custom-css.livereload]]</label>
<div class="form-text">[[admin/appearance/customise:custom-css.livereload.description]]</div>

Loading…
Cancel
Save