2012-09-14 26 views
5

Tengo una aplicación Expressjs ejecutándose en NodeJS 0.8.8 usando MongoDB y el lenguaje de plantilla de Jade, y me gustaría permitir que el usuario configure muchas de las opciones de presentación de todo el sitio como los títulos de página, la imagen del logotipo, etc.¿Cómo puedo almacenar la configuración del sitio en MongoDB para una aplicación NodeJS Express?

¿Cómo puedo almacenar estas opciones de configuración en una base de datos mongoDB para poder leerlas al inicio de la aplicación, manipularlas mientras la aplicación se está ejecutando y mostrarlas en las plantillas de jade?

Aquí está mi configuración general de aplicación:

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); 

Hasta ahora he creado un modelo llamado "sitio" de la colección "SiteConfig" y tengo una función llamada getSiteConfig en accessDB.js que corre Site.find() ... para recuperar los campos en el documento de la colección.

Así que este es el quid de la cuestión: ¿cómo debo inyectar esos campos en la aplicación express para que puedan ser utilizados en todo el sitio? ¿Debería seguir el mismo patrón que utilicé con la herramienta moment.js? De esta manera:

db.getSiteConfig(function(err, siteConfig){ 
    if (err) {throw err;} 
    app.locals.siteConfig = siteConfig; 
}); 

Si no, ¿cuál sería la forma correcta de hacerlo?

Gracias!

+0

es esto algo que desea almacenar en la sesión? – c0deNinja

+0

No, no lo creo. No quiero que el cliente tenga acceso a él. Solo quiero que la aplicación express del lado del servidor (especialmente Jade) tenga acceso a ella. Lo tengo funcionando hasta el punto de un console.log. Supongo que debería intentar agregarlo a los directorios de aplicaciones y ver qué sucede, pero no estoy seguro de las implicaciones de seguridad de usarlo. (o la estabilidad del mismo) – tutley

Respuesta

16

Considere utilizar middleware express para cargar la configuración del sitio.

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(); 
    }); 
    }); 
    ... 
}); 

Lanzar una equivocación es una muy mala idea porque se bloqueará su aplicación. Así que use next(err); en su lugar. Pasará su error para expresar errorHandler.

Si ya autenticó a su usuario (en middleware previo, por ejemplo) y almacenó sus datos en req.user, puede usarlo para obtener la configuración correcta de db.

Pero tenga cuidado con el uso de su función getSiteConfig dentro del middleware expreso, ya que pausará el procesamiento exprés de la solicitud hasta que se reciban los datos.

Deberá considerar el almacenamiento en memoria caché siteConfig en sesión express para acelerar su aplicación. El almacenamiento de datos específicos de la sesión en la sesión express es absolutamente seguro porque no hay forma de que el usuario tenga acceso a él.

El código siguiente muestra la idea de almacenamiento en caché en siteConfig sessionn expresa:

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(); 
    }); 
    }); 
    ... 
}); 
+1

Esta es una gran respuesta y realmente lo aprecio. Desafortunadamente no puedo votar porque no tengo suficiente reputación, pero si alguien está viendo esto, vote esto. Gracias de nuevo. – tutley

Cuestiones relacionadas