You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nodebb/src/meta/themes.js

186 lines
4.7 KiB
JavaScript

11 years ago
'use strict';
9 years ago
var nconf = require('nconf');
var winston = require('winston');
var fs = require('fs');
var path = require('path');
var async = require('async');
10 years ago
9 years ago
var file = require('../file');
var db = require('../database');
8 years ago
var events = require('../events');
11 years ago
module.exports = function (Meta) {
11 years ago
Meta.themes = {};
Meta.themes.get = function (callback) {
var themePath = nconf.get('themes_path');
if (typeof themePath !== 'string') {
return callback(null, []);
}
8 years ago
async.waterfall([
function (next) {
fs.readdir(themePath, next);
},
function (files, next) {
async.filter(files, function (file, next) {
fs.stat(path.join(themePath, file), function (err, fileStat) {
if (err) {
if (err.code === 'ENOENT') {
return next(null, false);
}
return next(err);
8 years ago
}
8 years ago
next(null, (fileStat.isDirectory() && file.slice(0, 13) === 'nodebb-theme-'));
});
}, next);
},
function (themes, next) {
11 years ago
async.map(themes, function (theme, next) {
var config = path.join(themePath, theme, 'theme.json');
10 years ago
fs.readFile(config, function (err, file) {
if (err) {
8 years ago
if (err.code === 'ENOENT') {
return next(null, null);
}
return next(err);
10 years ago
}
8 years ago
try {
var configObj = JSON.parse(file.toString());
// Minor adjustments for API output
configObj.type = 'local';
if (configObj.screenshot) {
configObj.screenshot_url = nconf.get('relative_path') + '/css/previews/' + configObj.id;
} else {
configObj.screenshot_url = nconf.get('relative_path') + '/assets/images/themes/default.png';
8 years ago
}
next(null, configObj);
} catch (err) {
winston.error('[themes] Unable to parse theme.json ' + theme);
next(null, null);
10 years ago
}
});
8 years ago
}, next);
},
function (themes, next) {
themes = themes.filter(Boolean);
next(null, themes);
},
], callback);
11 years ago
};
Meta.themes.set = function (data, callback) {
8 years ago
var themeData = {
11 years ago
'theme:type': data.type,
'theme:id': data.id,
'theme:staticDir': '',
'theme:templates': '',
'theme:src': '',
11 years ago
};
switch (data.type) {
11 years ago
case 'local':
async.waterfall([
9 years ago
async.apply(Meta.configs.get, 'theme:id'),
function (current, next) {
async.series([
async.apply(db.sortedSetRemove, 'plugins:active', current),
async.apply(db.sortedSetAdd, 'plugins:active', 0, data.id),
], function (err) {
next(err);
});
},
function (next) {
fs.readFile(path.join(nconf.get('themes_path'), data.id, 'theme.json'), function (err, config) {
11 years ago
if (!err) {
config = JSON.parse(config.toString());
next(null, config);
} else {
next(err);
}
});
},
function (config, next) {
11 years ago
themeData['theme:staticDir'] = config.staticDir ? config.staticDir : '';
themeData['theme:templates'] = config.templates ? config.templates : '';
themeData['theme:src'] = '';
8 years ago
Meta.configs.setMultiple(themeData, next);
// Re-set the themes path (for when NodeBB is reloaded)
Meta.themes.setPath(config);
},
8 years ago
function (next) {
events.log({
type: 'theme-set',
uid: parseInt(data.uid, 10) || 0,
ip: data.ip || '127.0.0.1',
text: data.id,
}, next);
},
11 years ago
], callback);
10 years ago
Meta.reloadRequired = true;
11 years ago
break;
case 'bootswatch':
8 years ago
Meta.configs.setMultiple({
'theme:src': data.src,
bootswatchSkin: data.id.toLowerCase(),
}, callback);
11 years ago
break;
}
};
Meta.themes.setupPaths = function (callback) {
8 years ago
async.waterfall([
function (next) {
async.parallel({
themesData: Meta.themes.get,
currentThemeId: function (next) {
db.getObjectField('config', 'theme:id', next);
},
}, next);
},
8 years ago
function (data, next) {
var themeId = data.currentThemeId || 'nodebb-theme-persona';
8 years ago
var themeObj = data.themesData.filter(function (themeObj) {
8 years ago
return themeObj.id === themeId;
})[0];
8 years ago
if (process.env.NODE_ENV === 'development') {
winston.info('[themes] Using theme ' + themeId);
}
8 years ago
if (!themeObj) {
return callback(new Error('[[error:theme-not-found]]'));
}
10 years ago
8 years ago
Meta.themes.setPath(themeObj);
next();
},
], callback);
};
Meta.themes.setPath = function (themeObj) {
// Theme's templates path
var themePath = nconf.get('base_templates_path');
var fallback = path.join(nconf.get('themes_path'), themeObj.id, 'templates');
10 years ago
if (themeObj.templates) {
themePath = path.join(nconf.get('themes_path'), themeObj.id, themeObj.templates);
10 years ago
} else if (file.existsSync(fallback)) {
themePath = fallback;
}
nconf.set('theme_templates_path', themePath);
10 years ago
nconf.set('theme_config', path.join(nconf.get('themes_path'), themeObj.id, 'theme.json'));
};
8 years ago
};