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

157 lines
3.8 KiB
JavaScript

11 years ago
'use strict';
var nconf = require('nconf'),
winston = require('winston'),
11 years ago
fs = require('fs'),
path = require('path'),
async = require('async'),
db = require('../database');
module.exports = function(Meta) {
Meta.themes = {};
Meta.themes.get = function (callback) {
var themePath = nconf.get('themes_path');
if (typeof themePath !== 'string') {
return callback(null, []);
}
fs.readdir(themePath, function (err, files) {
if (err) {
return callback(err);
}
async.filter(files, function (file, next) {
fs.stat(path.join(themePath, file), function (err, fileStat) {
if (err) {
return next(false);
}
next((fileStat.isDirectory() && file.slice(0, 13) === 'nodebb-theme-'));
});
}, function (themes) {
async.map(themes, function (theme, next) {
var config = path.join(themePath, theme, 'theme.json');
if (fs.existsSync(config)) {
fs.readFile(config, function (err, file) {
if (err) {
return next();
} else {
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') + '/images/themes/default.png';
}
11 years ago
next(err, configObj);
}
});
} else {
next();
}
}, function (err, themes) {
themes = themes.filter(function (theme) {
return (theme !== undefined);
});
callback(null, themes);
});
});
});
};
Meta.themes.set = function(data, callback) {
var themeData = {
'theme:type': data.type,
'theme:id': data.id,
'theme:staticDir': '',
'theme:templates': '',
'theme:src': ''
};
switch(data.type) {
case 'local':
async.waterfall([
function(next) {
fs.readFile(path.join(nconf.get('themes_path'), data.id, 'theme.json'), function(err, config) {
if (!err) {
config = JSON.parse(config.toString());
next(null, config);
} else {
next(err);
}
});
},
function(config, next) {
themeData['theme:staticDir'] = config.staticDir ? config.staticDir : '';
themeData['theme:templates'] = config.templates ? config.templates : '';
themeData['theme:src'] = '';
db.setObject('config', themeData, next);
// Re-set the themes path (for when NodeBB is reloaded)
Meta.themes.setPath(config);
11 years ago
}
], callback);
10 years ago
Meta.reloadRequired = true;
11 years ago
break;
case 'bootswatch':
Meta.configs.set('theme:src', data.src, callback);
break;
}
};
10 years ago
Meta.themes.setupPaths = function(callback) {
async.parallel({
themesData: Meta.themes.get,
currentThemeId: function(next) {
db.getObjectField('config', 'theme:id', next);
}
}, function(err, data) {
if (err) {
10 years ago
return callback(err);
}
var themeId = data.currentThemeId || 'nodebb-theme-persona';
var themeObj = data.themesData.filter(function(themeObj) {
return themeObj.id === themeId;
})[0];
if (process.env.NODE_ENV === 'development') {
winston.info('[themes] Using theme ' + themeId);
}
10 years ago
if (!themeObj) {
return callback(new Error('[[error:theme-not-found]]'));
}
Meta.themes.setPath(themeObj);
10 years ago
callback();
});
};
Meta.themes.setPath = function(themeObj) {
// Theme's templates path
var themePath = nconf.get('base_templates_path'),
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);
} else if (fs.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'));
};
11 years ago
};