Comment créer des variables globales accessibles dans toutes les vues en utilisant Express / Node.JS?

Ok, j’ai construit un blog en utilisant Jekyll et vous pouvez définir des variables dans un fichier _config.yml qui sont accessibles dans tous les templates / layouts. J’utilise actuellement Node.JS / Express avec les modèles EJS et ejs-locals (pour les partiels / layouts. Je cherche à faire quelque chose de similaire aux variables globales comme site.title que l’on trouve dans _config.yml si quelqu’un est familier avec Jekyll J’ai des variables comme le titre du site (plutôt que le titre de la page), le nom de l’auteur / de la société, qui restnt les mêmes sur toutes mes pages.

Voici un exemple de ce que je fais actuellement:

 exports.index = function(req, res){ res.render('index', { siteTitle: 'My Website Title', pageTitle: 'The Root Splash Page', author: 'Cory Gross', description: 'My app description', indexSpecificData: someData }); }; exports.home = function (req, res) { res.render('home', { siteTitle: 'My Website Title', pageTitle: 'The Home Page', author: 'Cory Gross', description: 'My app description', homeSpecificData: someOtherData }); }; 

Je voudrais pouvoir définir des variables comme le titre, la description, l’auteur, etc. de mon site en un seul endroit et les rendre accessibles dans mes mises en page / modèles via EJS sans avoir à les passer comme options pour chaque appel à res.render . Y a-t-il un moyen de le faire et de me permettre de transmettre d’autres variables spécifiques à chaque page?

    Après avoir eu l’occasion d’étudier un peu plus la référence de l’API Express 3, j’ai découvert ce que je cherchais. Plus précisément, les entrées pour app.locals , puis un peu plus loin les res.locals contenaient les réponses dont j’avais besoin.

    J’ai découvert par moi-même que la fonction app.locals prend un object et stocke toutes ses propriétés en tant que variables globales définies pour l’application. Ces globaux sont transmis en tant que variables locales à chaque vue. La fonction res.locals , cependant, a la scope de la requête et, par conséquent, les variables locales de réponse ne sont accessibles que pour la ou les vues rendues pendant cette requête / réponse particulière.

    Donc, pour mon cas dans mon app.js j’ai ajouté:

     app.locals({ site: { title: 'ExpressBootstrapEJS', description: 'A boilerplate for a simple web application with a Node.JS and Express backend, with an EJS template with using Twitter Bootstrap.' }, author: { name: 'Cory Gross', contact: 'CoryG89@gmail.com' } }); 

    Ensuite, toutes ces variables sont accessibles dans mes vues en tant que site.title , site.description , author.name , author.contact .

    Je pourrais également définir des variables locales pour chaque réponse à une requête avec res.locals , ou simplement passer des variables comme le titre de la page en tant que paramètre d’ options dans l’appel de render .

    EDIT: Cette méthode ne vous permettra pas d’utiliser ces sections locales dans votre middleware. En fait, j’ai rencontré cela comme le suggère Pickels dans le commentaire ci-dessous. Dans ce cas, vous devrez créer une fonction middleware en tant que telle dans sa réponse alternative (et appréciée). Votre fonction middleware devra les append à res.locals pour chaque réponse, puis appeler next . Cette fonction de middleware devra être placée au-dessus de tout autre middleware qui doit utiliser ces locaux.

    EDIT: Une autre différence entre la déclaration des sections locales via app.locals et res.locals est que, avec app.locals les variables sont définies une seule fois et persistent tout au long de la vie de l’application. Lorsque vous définissez des sections locales avec res.locals dans votre middleware, elles sont définies chaque fois que vous recevez une demande. Vous devriez plutôt préférer définir des globals via app.locals moins que la valeur ne dépende de la variable de requête req transmise au middleware. Si la valeur ne change pas, il sera plus efficace de la définir une seule fois dans app.locals .

    Vous pouvez le faire en les ajoutant à l’object local dans un middleware général.

     app.use(function (req, res, next) { res.locals = { siteTitle: "My Website's Title", pageTitle: "The Home Page", author: "Cory Gross", description: "My app's description", }; next(); }); 

    Les sections locales sont également une fonction qui étendra l’object local plutôt que de l’écraser. Donc, les travaux suivants aussi

     res.locals({ siteTitle: "My Website's Title", pageTitle: "The Home Page", author: "Cory Gross", description: "My app's description", }); 

    Exemple complet

     var app = express(); var middleware = { render: function (view) { return function (req, res, next) { res.render(view); } }, globalLocals: function (req, res, next) { res.locals({ siteTitle: "My Website's Title", pageTitle: "The Root Splash Page", author: "Cory Gross", description: "My app's description", }); next(); }, index: function (req, res, next) { res.locals({ indexSpecificData: someData }); next(); } }; app.use(middleware.globalLocals); app.get('/', middleware.index, middleware.render('home')); app.get('/products', middleware.products, middleware.render('products')); 

    J’ai également ajouté un middleware de rendu générique. De cette façon, vous n’avez pas besoin d’append res.render à chaque route, ce qui signifie que vous avez une meilleure réutilisation du code. Une fois que vous aurez parcouru le chemin du middleware réutilisable, vous remarquerez que vous aurez beaucoup de blocs de construction qui accéléreront énormément le développement.

    Pour Express 4.0, j’ai trouvé que l’utilisation de variables au niveau de l’application fonctionnait un peu différemment et que la réponse de Cory ne fonctionnait pas pour moi.

    De la documentation: http://expressjs.com/en/api.html#app.locals

    J’ai trouvé que vous pouviez déclarer une variable globale pour l’application dans

     app.locals 

    par exemple

     app.locals.baseUrl = "http://www.google.com" 

    Et puis dans votre application, vous pouvez accéder à ces variables et dans votre middleware express, vous pouvez y accéder dans l’object req comme

     req.app.locals.baseUrl 

    par exemple

     console.log(req.app.locals.baseUrl) //prints out http://www.google.com 

    Dans votre app.js, vous devez append quelque chose comme ça

     global.myvar = 100; 

    Maintenant, dans tous vos fichiers que vous voulez utiliser cette variable, vous pouvez simplement y accéder en tant que myvar

    Une façon de le faire en mettant à jour la variable app.locals pour cette application dans app.js

    Définir via suivant

     var app = express(); app.locals.appName = "DRC on FHIR"; 

    Avoir access

     app.listen(3000, function () { console.log('[' + app.locals.appName + '] => app listening on port 3001!'); }); 

    Elaborant avec une capture d’exemple de @RamRovi avec une légère amélioration.

    entrer la description de l'image ici

    vous pouvez aussi utiliser “global”

    Exemple:

    déclarer comme ceci:

      app.use(function(req,res,next){ global.site_url = req.headers.host; // hostname = 'localhost:8080' next(); }); 

    Utilisez comme ceci: dans n’importe quelle vue ou fichier ejs <% console.log (site_url); %>

    dans les fichiers js console.log (site_url);

    Ce que je fais pour éviter d’avoir une scope globale polluée est de créer un script que je peux inclure n’importe où.

     // my-script.js const ActionsOverTime = require('@bigteam/node-aot').ActionsOverTime; const config = require('../../config/config').actionsOverTime; let aotInstance; (function () { if (!aotInstance) { console.log('Create new aot instance'); aotInstance = ActionsOverTime.createActionOverTimeEmitter(config); } })(); exports = aotInstance; 

    Faire cela créera seulement une nouvelle instance une fois et la partagera partout où le fichier est inclus. Je ne sais pas si c’est parce que la variable est mise en cache ou en raison d’un mécanisme de référence interne pour l’application (qui peut inclure la mise en cache). Tout commentaire sur la manière dont le nœud se résout serait génial.

    Peut-être aussi lisez ceci pour avoir un aperçu de la manière dont les travaux doivent être exécutés: http://fredkschott.com/post/2014/06/require-and-the-module-system/