85 votes

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

Ok, j'ai donc créé un blog en utilisant Jekyll et vous pouvez définir des variables dans un fichier _config.yml qui sont accessibles dans tous les modèles/présentations. J'utilise actuellement Node.JS / Express con EJS modèles et ejs-locals (pour les partiels/maquettes. Je cherche à faire quelque chose de similaire aux variables globales comme site.title qui se trouvent dans _config.yml si quelqu'un connaît 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 restent 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
    });
};

J'aimerais pouvoir définir des variables comme le titre de mon site, la description, l'auteur, etc. en un seul endroit et les rendre accessibles dans mes layouts/templates via EJS sans avoir à les passer en tant qu'options à chaque appel de res.render . Existe-t-il un moyen de faire cela tout en me permettant de passer d'autres variables spécifiques à chaque page ?

113voto

Cory Gross Points 3118

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

J'ai découvert par moi-même que la fonction app.locals prend un objet et stocke toutes ses propriétés sous forme de variables globales liées à l'application. Ces variables globales sont transmises à chaque vue en tant que variables locales. La fonction res.locals Les variables locales de la réponse ne sont donc accessibles qu'à la ou aux vue(s) rendue(s) au cours de cette requête/réponse particulière.

Ainsi, dans mon cas, dans mon app.js Ce que j'ai fait, c'est ajouter :

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

Toutes ces variables sont ensuite 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 qu'élément de l'élément options dans le fichier render appel.

EDITAR: Cette méthode permettra pas vous permettent d'utiliser ces locaux dans votre logiciel intermédiaire. J'ai en fait rencontré ce problème, comme le suggère Pickels dans le commentaire ci-dessous. Dans ce cas, vous devrez créer une fonction middleware comme indiqué dans sa réponse alternative (et appréciée). Votre fonction d'intergiciel devra les ajouter à res.locals pour chaque réponse, puis appeler next . Cette fonction d'intergiciel devra être placée au-dessus de tout autre intergiciel devant utiliser ces locaux.

EDITAR: Une autre différence entre la déclaration de locaux via app.locals et res.locals est qu'avec app.locals les variables sont définies une seule fois et persistent pendant toute la durée de vie de l'application. Lorsque vous définissez des variables locales avec res.locals dans votre intergiciel, elles sont définies à chaque fois que vous recevez une demande. Vous devriez préférer définir les valeurs globales par l'intermédiaire de app.locals sauf si la valeur dépend de la demande req transmise à l'intergiciel. Si la valeur ne change pas, il sera plus efficace de ne la définir qu'une seule fois dans app.locals .

59voto

Pickels Points 9201

Vous pouvez le faire en les ajoutant à l'objet local dans un intergiciel 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();
});

Locals est également une fonction qui étend l'objet locals au lieu de l'écraser. Ainsi, la fonction suivante fonctionne également

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 intergiciel de rendu générique. De cette façon, vous n'avez pas à ajouter res.render à chaque route, ce qui signifie que vous avez une meilleure réutilisation du code. Une fois que vous aurez emprunté la voie des intergiciels réutilisables, vous remarquerez que vous aurez beaucoup de blocs de construction, ce qui accélérera considérablement le développement.

19voto

RamRovi Points 381

Pour Express 4.0, j'ai constaté que l'utilisation de variables au niveau de l'application fonctionne un peu différemment et la réponse de Cory n'a pas fonctionné pour moi.

D'après les documents : http://expressjs.com/en/api.html#app.locals

J'ai découvert qu'il était possible de déclarer une variable globale pour l'application dans

app.locals

Par exemple

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

Ensuite, dans votre application, vous pouvez accéder à ces variables et dans votre middleware express, vous pouvez y accéder dans l'objet req en tant que

req.app.locals.baseUrl

par exemple

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

17voto

Dans votre app.js, vous devez ajouter quelque chose comme ceci

global.myvar = 100;

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

1voto

Shaik Matheen Points 326

Vous pouvez également utiliser "global"

Ejemplo:

déclarer comme ceci :

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

Utiliser comme ceci : i <% console.log(site_url) ; %>

i console.log(site_url) ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X