I have an Expressjs app running on NodeJS 0.8.8 using MongoDB and the Jade template language, and I'd like to allow the user to configure many of the site-wide presentation options such as the page titles, logo image, etc.
How can I store these configuration options in a mongoDB database so that I can read them upon application startup, manipulate them while the app is running, and display them in the jade templates?
Here's my general app setup:
var app = module.exports = express();
global.app = app;
var DB = require('./accessDB');
var conn = 'mongodb://localhost/dbname';
var db;
// App Config
app.configure(function(){
...
});
db = new DB.startup(conn);
//env specific config
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
}); // etc
// use date manipulation tool moment
app.locals.moment = moment;
// Load the router
require('./routes')(app);
So Far I have created a model called "Site" for the "siteConfig" collection and I have a function called getSiteConfig in accessDB.js that runs Site.find()... to retrieve the fields in the one document in the collection.
So this is the crux of the question: how should I inject those fields into the express app so that they can be used throughout the site? Should I follow the same pattern I used with the moment.js tool? Like this:
db.getSiteConfig(function(err, siteConfig){
if (err) {throw err;}
app.locals.siteConfig = siteConfig;
});
If not, what would be the correct way to do this?
Thanks!
import mongoose from 'mongoose'; const Schema = mongoose. Schema; const postSchema = new Schema({ title: { type: 'String', required: true }, content: { type: 'String', required: true }, slug: { type: 'String', required: true } }); let Post = mongoose. model('Post', postSchema);
Consider using express middleware for loading site config.
app.configure(function() {
app.use(function(req, res, next) {
// feel free to use req to store any user-specific data
return db.getSiteConfig(req.user, function(err, siteConfig) {
if (err) return next(err);
res.local('siteConfig', siteConfig);
return next();
});
});
...
});
Throwing an err is a realy bad idea because it will crash your application.
So use next(err);
instead. It will pass your error to express errorHandler
.
If you already authenticated your user (in previous middleware, for example) and stored its data into req.user
, you can use it to get the right config from db.
But be careful with using your getSiteConfig
function inside of express middleware because it will pause express from further processing of the request until the data is received.
You shall consider caching siteConfig
in express session to speedup you application. Storing session-specific data in express session is absolutely safe because there is no way for user to get access to it.
The following code demonstrates the idea of caching siteConfig
in express sessionn:
app.configure(function() {
app.use(express.session({
secret: "your sercret"
}));
app.use(/* Some middleware that handles authentication */);
app.use(function(req, res, next) {
if (req.session.siteConfig) {
res.local('siteConfig', req.session.siteConfig);
return next();
}
return db.getSiteConfig(req.user, function(err, siteConfig) {
if (err) return next(err);
req.session.siteConfig = siteConfig;
res.local('siteConfig', siteConfig);
return next();
});
});
...
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With